summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2013-09-15 21:57:55 -0700
committerKaz Kylheku <kaz@kylheku.com>2013-09-15 21:57:55 -0700
commit672e606b6d857e370ac75c076a1b2982e5bccd67 (patch)
tree46dcaace1126e2b2c2f785e42f562fe5c7718484 /src
downloadsekaiju-672e606b6d857e370ac75c076a1b2982e5bccd67.tar.gz
sekaiju-672e606b6d857e370ac75c076a1b2982e5bccd67.tar.bz2
sekaiju-672e606b6d857e370ac75c076a1b2982e5bccd67.zip
Converted Sekaiju 3.6 to Visual Studio 2008.
Diffstat (limited to 'src')
-rw-r--r--src/AboutDlg.cpp50
-rw-r--r--src/AboutDlg.h45
-rw-r--r--src/AutoSaveDlg.cpp164
-rw-r--r--src/AutoSaveDlg.h67
-rw-r--r--src/ChildFrame.cpp99
-rw-r--r--src/ColorOptionPage.cpp160
-rw-r--r--src/ColorOptionPage.h61
-rw-r--r--src/ColorSelectComboBox.cpp190
-rw-r--r--src/ColorSelectComboBox.h81
-rw-r--r--src/ColorfulCheckListBox.cpp186
-rw-r--r--src/ColorfulComboBox.cpp189
-rw-r--r--src/ColorfulComboBox.h58
-rw-r--r--src/EditBeatScanDlg.cpp139
-rw-r--r--src/EditBeatScanDlg.h65
-rw-r--r--src/EditBreakupAndTrillDlg.cpp143
-rw-r--r--src/EditBreakupAndTrillDlg.h65
-rw-r--r--src/EditChannelDlg.cpp109
-rw-r--r--src/EditChannelDlg.h61
-rw-r--r--src/EditDurationDlg.cpp113
-rw-r--r--src/EditDurationDlg.h61
-rw-r--r--src/EditInsertMeasureDlg.cpp98
-rw-r--r--src/EditInsertMeasureDlg.h59
-rw-r--r--src/EditKeyDlg.cpp112
-rw-r--r--src/EditKeyDlg.h63
-rw-r--r--src/EditQuantizeDlg.cpp142
-rw-r--r--src/EditQuantizeDlg.h64
-rw-r--r--src/EditRemoveMeasureDlg.cpp98
-rw-r--r--src/EditRemoveMeasureDlg.h59
-rw-r--r--src/EditTimeDlg.cpp102
-rw-r--r--src/EditTimeDlg.h62
-rw-r--r--src/EditTimeSmpDlg.cpp102
-rw-r--r--src/EditTimeSmpDlg.h61
-rw-r--r--src/EditTrackDlg.cpp109
-rw-r--r--src/EditTrackDlg.h60
-rw-r--r--src/EditValueDlg.cpp149
-rw-r--r--src/EditValueDlg.h65
-rw-r--r--src/EditVelocityDlg.cpp117
-rw-r--r--src/EditVelocityDlg.h61
-rw-r--r--src/EventKindListBox.cpp135
-rw-r--r--src/EventKindListBox.h64
-rw-r--r--src/EventListFrame.cpp3301
-rw-r--r--src/EventListIndexPropertyView.cpp4404
-rw-r--r--src/EventListIndexPropertyView.h120
-rw-r--r--src/EventListIndexScaleView.cpp454
-rw-r--r--src/EventListIndexScaleView.h77
-rw-r--r--src/EventListOptionPage.cpp126
-rw-r--r--src/EventListOptionPage.h72
-rw-r--r--src/EventListPrintView.cpp865
-rw-r--r--src/EventListPrintView.h75
-rw-r--r--src/EventListPropertyScaleView.cpp251
-rw-r--r--src/EventListPropertyScaleView.h73
-rw-r--r--src/EventListScaleView.cpp168
-rw-r--r--src/EventListScaleView.h52
-rw-r--r--src/FilePropertyDlg.cpp148
-rw-r--r--src/FilePropertyDlg.h70
-rw-r--r--src/GeneralOptionPage.cpp124
-rw-r--r--src/GeneralOptionPage.h78
-rw-r--r--src/GraphKindListBox.cpp135
-rw-r--r--src/GraphKindListBox.h64
-rw-r--r--src/HistoryRecord.cpp45
-rw-r--r--src/HistoryRecord.h56
-rw-r--r--src/HistoryUnit.cpp351
-rw-r--r--src/HistoryUnit.h48
-rw-r--r--src/InplaceEdit.cpp98
-rw-r--r--src/InplaceEdit.h46
-rw-r--r--src/InplaceListBox.cpp103
-rw-r--r--src/InplaceListBox.h48
-rw-r--r--src/LanguageDlg.cpp101
-rw-r--r--src/LanguageDlg.h57
-rw-r--r--src/MIDIDeviceSheet.cpp93
-rw-r--r--src/MIDIDeviceSheet.h59
-rw-r--r--src/MIDIInDevicePage.cpp122
-rw-r--r--src/MIDIInDevicePage.h55
-rw-r--r--src/MIDIInSyncModePage.cpp104
-rw-r--r--src/MIDIInSyncModePage.h57
-rw-r--r--src/MIDIInstDefDrumPage.cpp112
-rw-r--r--src/MIDIInstDefDrumPage.h58
-rw-r--r--src/MIDIInstDefNormPage.cpp111
-rw-r--r--src/MIDIInstDefNormPage.h56
-rw-r--r--src/MIDIOutDevicePage.cpp138
-rw-r--r--src/MIDIOutDevicePage.h56
-rw-r--r--src/MIDIOutSyncModePage.cpp104
-rw-r--r--src/MIDIOutSyncModePage.h57
-rw-r--r--src/MIDISyncModeSheet.cpp66
-rw-r--r--src/MIDISyncModeSheet.h51
-rw-r--r--src/MainFrame.cpp773
-rw-r--r--src/MetronomeDlg.cpp194
-rw-r--r--src/MetronomeDlg.h65
-rw-r--r--src/MusicalScoreFrame.cpp3960
-rw-r--r--src/MusicalScoreFrame.h352
-rw-r--r--src/MusicalScoreOptionPage.cpp88
-rw-r--r--src/MusicalScoreOptionPage.h61
-rw-r--r--src/MusicalScorePrintView.cpp2137
-rw-r--r--src/MusicalScorePrintView.h108
-rw-r--r--src/MusicalScoreScaleView.cpp155
-rw-r--r--src/MusicalScoreScaleView.h51
-rw-r--r--src/MusicalScoreTimeScaleView.cpp628
-rw-r--r--src/MusicalScoreTimeScaleView.h76
-rw-r--r--src/MusicalScoreTrackScaleView.cpp1200
-rw-r--r--src/MusicalScoreTrackScaleView.h105
-rw-r--r--src/MusicalScoreTrackTimeView.cpp3025
-rw-r--r--src/MusicalScoreTrackTimeView.h137
-rw-r--r--src/OptionSheet.cpp99
-rw-r--r--src/OptionSheet.h66
-rw-r--r--src/PianoRollFrame.cpp2957
-rw-r--r--src/PianoRollFrame.h245
-rw-r--r--src/PianoRollKeyScaleView.cpp517
-rw-r--r--src/PianoRollKeyScaleView.h78
-rw-r--r--src/PianoRollKeyTimeView.cpp2181
-rw-r--r--src/PianoRollKeyTimeView.h103
-rw-r--r--src/PianoRollOptionPage.cpp96
-rw-r--r--src/PianoRollOptionPage.h64
-rw-r--r--src/PianoRollPrintView.cpp1075
-rw-r--r--src/PianoRollPrintView.h79
-rw-r--r--src/PianoRollScaleView.cpp163
-rw-r--r--src/PianoRollScaleView.h51
-rw-r--r--src/PianoRollTimeScaleView.cpp715
-rw-r--r--src/PianoRollTimeScaleView.h80
-rw-r--r--src/PianoRollVelScaleView.cpp530
-rw-r--r--src/PianoRollVelScaleView.h83
-rw-r--r--src/PianoRollVelTimeView.cpp1976
-rw-r--r--src/PianoRollVelTimeView.h103
-rw-r--r--src/PropertyKeySignatureDlg.cpp103
-rw-r--r--src/PropertyKeySignatureDlg.h62
-rw-r--r--src/PropertyMarkerDlg.cpp71
-rw-r--r--src/PropertyMarkerDlg.h58
-rw-r--r--src/PropertyNoteDlg.cpp168
-rw-r--r--src/PropertyNoteDlg.h75
-rw-r--r--src/PropertyTempoDlg.cpp71
-rw-r--r--src/PropertyTempoDlg.h58
-rw-r--r--src/PropertyTimeSignatureDlg.cpp125
-rw-r--r--src/PropertyTimeSignatureDlg.h65
-rw-r--r--src/Resource.h1796
-rw-r--r--src/Sekaiju.rc37
-rw-r--r--src/SekaijuApp.cpp4044
-rw-r--r--src/SekaijuApp.h600
-rw-r--r--src/SekaijuDoc.cpp8999
-rw-r--r--src/SekaijuDoc.h320
-rw-r--r--src/SekaijuDocManager.cpp194
-rw-r--r--src/SekaijuDocManager.h37
-rw-r--r--src/SekaijuDocTemplate.cpp282
-rw-r--r--src/SekaijuDocTemplate.h51
-rw-r--r--src/SekaijuFileDlg.cpp117
-rw-r--r--src/SekaijuFileDlg.h52
-rw-r--r--src/SekaijuStatusBar.cpp108
-rw-r--r--src/SekaijuToolBar.cpp174
-rw-r--r--src/SekaijuView.cpp87
-rw-r--r--src/SekaijuView.h66
-rw-r--r--src/TrackListBox.cpp131
-rw-r--r--src/TrackListBox.h61
-rw-r--r--src/TrackListFrame.cpp2228
-rw-r--r--src/TrackListFrame.h209
-rw-r--r--src/TrackListModeScaleView.cpp244
-rw-r--r--src/TrackListModeScaleView.h73
-rw-r--r--src/TrackListOption1Page.cpp124
-rw-r--r--src/TrackListOption1Page.h70
-rw-r--r--src/TrackListOption2Page.cpp127
-rw-r--r--src/TrackListOption2Page.h72
-rw-r--r--src/TrackListPrintView.cpp1259
-rw-r--r--src/TrackListPrintView.h80
-rw-r--r--src/TrackListScaleView.cpp146
-rw-r--r--src/TrackListScaleView.h52
-rw-r--r--src/TrackListTimeScaleView.cpp695
-rw-r--r--src/TrackListTimeScaleView.h88
-rw-r--r--src/TrackListTrackModeView.cpp3368
-rw-r--r--src/TrackListTrackModeView.h106
-rw-r--r--src/TrackListTrackScaleView.cpp432
-rw-r--r--src/TrackListTrackScaleView.h78
-rw-r--r--src/TrackListTrackTimeView.cpp1262
-rw-r--r--src/TrackListTrackTimeView.h96
-rw-r--r--src/childframe.h56
-rw-r--r--src/colorfulchecklistbox.h58
-rw-r--r--src/common.h57
-rw-r--r--src/eventlistframe.h221
-rw-r--r--src/mainframe.h97
-rw-r--r--src/mousewheel.h38
-rw-r--r--src/sekaijustatusbar.h52
-rw-r--r--src/sekaijutoolbar.h58
-rw-r--r--src/winver.h30
179 files changed, 70661 insertions, 0 deletions
diff --git a/src/AboutDlg.cpp b/src/AboutDlg.cpp
new file mode 100644
index 0000000..176a869
--- /dev/null
+++ b/src/AboutDlg.cpp
@@ -0,0 +1,50 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ヴァージョン情報ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include "resource.h"
+#include "AboutDlg.h"
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CAboutDlg::CAboutDlg () : CDialog (CAboutDlg::IDD) {
+
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CAboutDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CAboutDlg, CDialog)
+END_MESSAGE_MAP ()
+
diff --git a/src/AboutDlg.h b/src/AboutDlg.h
new file mode 100644
index 0000000..47020fb
--- /dev/null
+++ b/src/AboutDlg.h
@@ -0,0 +1,45 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ヴァージョン情報ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _ABOUTDLG_H_
+#define _ABOUTDLG_H_
+
+class CAboutDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CAboutDlg(); // コンストラクタ
+ enum { IDD = IDD_ABOUTBOX };
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif
diff --git a/src/AutoSaveDlg.cpp b/src/AutoSaveDlg.cpp
new file mode 100644
index 0000000..94bd653
--- /dev/null
+++ b/src/AutoSaveDlg.cpp
@@ -0,0 +1,164 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 自動保存ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "AutoSaveDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CAutoSaveDlg::CAutoSaveDlg () : CDialog (CAutoSaveDlg::IDD) {
+ m_nOn = 0;
+ m_lInterval = 0;
+ m_nDisableWhilePlaying = 0;
+ m_nDisableWhileRecording = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 『自動保存間隔』の値範囲設定(1〜120[分])
+BOOL CAutoSaveDlg::SetIntervalRange () {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_AUTOSAVE_INTERVALSP))->SetRange (1, 120);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_AUTOSAVE_INTERVALSP))->SetPos (CLIP (1, m_lInterval, 120));
+ return TRUE;
+}
+
+// 『自動保存間隔』を更新
+BOOL CAutoSaveDlg::UpdateInterval () {
+ int nOn = ((CButton*)GetDlgItem (IDC_AUTOSAVE_ON))->GetCheck ();
+ GetDlgItem (IDC_AUTOSAVE_INTERVAL)->EnableWindow (nOn);
+ GetDlgItem (IDC_AUTOSAVE_INTERVALSP)->EnableWindow (nOn);
+ return TRUE;
+}
+
+// 『演奏中は自動保存しない』を更新
+BOOL CAutoSaveDlg::UpdateDisableWhilePlaying () {
+ int nOn = ((CButton*)GetDlgItem (IDC_AUTOSAVE_ON))->GetCheck ();
+ GetDlgItem (IDC_AUTOSAVE_DISABLEWHILEPLAYING)->EnableWindow (nOn);
+ return TRUE;
+}
+
+// 『リアルタイム入力中は自動保存しない』を更新
+BOOL CAutoSaveDlg::UpdateDisableWhileRecording () {
+ int nOn = ((CButton*)GetDlgItem (IDC_AUTOSAVE_ON))->GetCheck ();
+ GetDlgItem (IDC_AUTOSAVE_DISABLEWHILERECORDING)->EnableWindow (nOn);
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CAutoSaveDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Check (pDX, IDC_AUTOSAVE_ON, m_nOn);
+ DDX_Text (pDX, IDC_AUTOSAVE_INTERVAL, m_lInterval);
+ DDV_MinMaxInt (pDX, m_lInterval, 1, 120);
+ DDX_Check (pDX, IDC_AUTOSAVE_DISABLEWHILEPLAYING, m_nDisableWhilePlaying);
+ DDX_Check (pDX, IDC_AUTOSAVE_DISABLEWHILERECORDING, m_nDisableWhileRecording);
+}
+
+// ダイアログの初期化
+BOOL CAutoSaveDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_AUTOSAVE_INTERVALSP))->SetRange (1, 120);
+ UpdateInterval ();
+ UpdateDisableWhilePlaying ();
+ UpdateDisableWhileRecording ();
+ SetIntervalRange ();
+ return bRet;
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CAutoSaveDlg, CDialog)
+ ON_BN_CLICKED (IDC_AUTOSAVE_ON, OnChangeOn)
+ ON_BN_CLICKED (IDC_AUTOSAVE_DELETEALLFILENOW, OnDeleteAllFileNow)
+END_MESSAGE_MAP ()
+
+// 『自動保存をする(ドキュメントが変更されている場合のみ)』
+void CAutoSaveDlg::OnChangeOn () {
+ UpdateInterval ();
+ UpdateDisableWhilePlaying ();
+ UpdateDisableWhileRecording ();
+}
+
+// 『今すぐすべての自動保存ファイルを削除する』
+void CAutoSaveDlg::OnDeleteAllFileNow () {
+
+ // 本当にすべて削除してよいか確認
+ long lRet = 0;
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_ARE_YOU_SURE_TO_DELETE_ALL_AUTOSAVEFILE_NOW_REALLY));
+ lRet = AfxMessageBox (strMsg, MB_ICONQUESTION | MB_YESNOCANCEL);
+ if (lRet != IDYES) {
+ return;
+ }
+
+ // autosaveディレクトリ内の拡張子(*.skj)のファイルを全て削除する。
+ lRet = 0;
+ CString strFileName1;
+ CString strFileName2;
+ VERIFY (strFileName1.LoadString (IDS_AUTOSAVEFILENAME));
+ strFileName2 = m_strExeFilePath + strFileName1;
+ HANDLE hFind = NULL;
+ WIN32_FIND_DATA fd;
+ hFind = ::FindFirstFile ((LPCTSTR)strFileName2, &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ do {
+ if (_tcscmp (fd.cFileName, _T(".")) != 0 &&
+ _tcscmp (fd.cFileName, _T("..")) != 0) {
+ CString strFileName3;
+ CString strFileName4;
+ VERIFY (strFileName3.LoadString (IDS_AUTOSAVEDIRNAME));
+ strFileName4 = m_strExeFilePath + strFileName3 + fd.cFileName;
+ BOOL bRet = _tremove (strFileName4);
+ if (bRet == FALSE) {
+ _RPTF1 (_CRT_WARN, "AutoSaveFile Delete Failed. - \"%s\"\n", strFileName4);
+ }
+ else {
+ _RPTF1 (_CRT_WARN, "AutoSaveFile Delete Successful. - \"%s\"\n", strFileName4);
+ }
+ lRet++;
+ }
+ } while (::FindNextFile (hFind, &fd));
+ ::FindClose (hFind);
+ }
+}
+
+
diff --git a/src/AutoSaveDlg.h b/src/AutoSaveDlg.h
new file mode 100644
index 0000000..d3863d3
--- /dev/null
+++ b/src/AutoSaveDlg.h
@@ -0,0 +1,67 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 自動保存ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _AUTOSAVEDLG_H_
+#define _AUTOSAVEDLG_H_
+
+class CAutoSaveDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strExeFilePath; // 実行ファイルのパス名
+ int m_nOn; // 自動保存オン
+ int m_lInterval; // 自動保存間隔(1-120)[分]
+ int m_nDisableWhilePlaying; // 演奏中は自動保存しない
+ int m_nDisableWhileRecording; // リアルタイム入力中は自動保存しない
+
+public:
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+ // コンストラクタ
+ CAutoSaveDlg ();
+ enum {IDD = IDD_AUTOSAVE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ BOOL SetIntervalRange ();
+ BOOL UpdateInterval ();
+ BOOL UpdateDisableWhilePlaying ();
+ BOOL UpdateDisableWhileRecording ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+ afx_msg void OnChangeOn ();
+ afx_msg void OnDeleteAllFileNow ();
+};
+
+#endif
diff --git a/src/ChildFrame.cpp b/src/ChildFrame.cpp
new file mode 100644
index 0000000..4303f06
--- /dev/null
+++ b/src/ChildFrame.cpp
@@ -0,0 +1,99 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MDI子フレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE (CChildFrame, CMDIChildWnd)
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CChildFrame::CChildFrame () {
+}
+
+// デストラクタ
+CChildFrame::~CChildFrame () {
+
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// ドキュメントへのポインタ取得
+CDocument* CChildFrame::GetDocument () {
+ CView* pActiveView = GetActiveView ();
+ if (pActiveView) {
+ return pActiveView->GetDocument ();
+ }
+ else {
+ return NULL;
+ }
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウが破棄された後
+void CChildFrame::PostNcDestroy () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ pSekaijuApp->UpdateCurWndAndDocPtr ();
+ CMDIChildWnd::PostNcDestroy ();
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CChildFrame, CMDIChildWnd)
+ ON_WM_MDIACTIVATE ()
+END_MESSAGE_MAP ()
+
+// ウィンドウがアクティブになったとき
+void CChildFrame::OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (bActivate == TRUE) {
+ pSekaijuApp->UpdateCurWndAndDocPtr ();
+ }
+ CMDIChildWnd::OnMDIActivate (bActivate, pActivateWnd, pDeactivateWnd);
+}
+
+
diff --git a/src/ColorOptionPage.cpp b/src/ColorOptionPage.cpp
new file mode 100644
index 0000000..dca6534
--- /dev/null
+++ b/src/ColorOptionPage.cpp
@@ -0,0 +1,160 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// オプション(色)プロパティページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* This library is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Lesser Color 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 Color Public License for more details. */
+
+/* You should have received a copy of the GNU Lesser Color 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "ColorOptionPage.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CColorOptionPage::CColorOptionPage () : CPropertyPage (CColorOptionPage::IDD) {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CColorOptionPage::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+}
+
+// ダイアログの初期化
+BOOL CColorOptionPage::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ // カラー選択コンボボックスの生成と位置調整と色サンプルの追加
+ long i = 0;
+ long r, g, b;
+ // 前景色(トラックデフォルト色)
+ for (i = 0; i < 8; i++) {
+ m_theForeColorCombo[i].Create
+ (WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL,
+ CRect (10, 10, 300, 300), this, IDC_COLOROPTION_FORECOLOR_00 + 16 + i);
+ CRect rcComboDummy;
+ CWnd* pComboDummy = GetDlgItem (IDC_COLOROPTION_FORECOLOR_00 + i);
+ pComboDummy->GetWindowRect (&rcComboDummy);
+ this->ScreenToClient (&rcComboDummy);
+ m_theForeColorCombo[i].MoveWindow (&rcComboDummy);
+ pComboDummy->DestroyWindow ();
+ for (r = 0; r <= 256; r += 64) {
+ for (g = 0; g <= 256; g += 64) {
+ for (b = 0; b <= 256; b += 64) {
+ m_theForeColorCombo[i].AddSampleColor (RGB (MIN (r, 255), MIN (g, 255), MIN (b, 255)));
+ }
+ }
+ }
+ m_theForeColorCombo[i].AddSampleColor (COLORSELECTCOMBOBOX_OTHER);
+ }
+ // 背景色
+ for (i = 0; i < 2; i++) {
+ m_theBackColorCombo[i].Create
+ (WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL,
+ CRect (10, 10, 300, 300), this, IDC_COLOROPTION_BACKCOLOR_00 + 16 + i);
+ CRect rcComboDummy;
+ CWnd* pComboDummy = GetDlgItem (IDC_COLOROPTION_BACKCOLOR_00 + i);
+ pComboDummy->GetWindowRect (&rcComboDummy);
+ this->ScreenToClient (&rcComboDummy);
+ m_theBackColorCombo[i].MoveWindow (&rcComboDummy);
+ pComboDummy->DestroyWindow ();
+ for (r = 0; r <= 256; r += 64) {
+ for (g = 0; g <= 256; g += 64) {
+ for (b = 0; b <= 256; b += 64) {
+ m_theBackColorCombo[i].AddSampleColor (RGB (MIN (r, 255), MIN (g, 255), MIN (b, 255)));
+ }
+ }
+ }
+ m_theBackColorCombo[i].AddSampleColor (COLORSELECTCOMBOBOX_OTHER);
+ }
+ // 水平線色
+ for (i = 0; i < 2; i++) {
+ m_theHorzColorCombo[i].Create
+ (WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL,
+ CRect (10, 10, 300, 300), this, IDC_COLOROPTION_HORZCOLOR_00 + 16 + i);
+ CRect rcComboDummy;
+ CWnd* pComboDummy = GetDlgItem (IDC_COLOROPTION_HORZCOLOR_00 + i);
+ pComboDummy->GetWindowRect (&rcComboDummy);
+ this->ScreenToClient (&rcComboDummy);
+ m_theHorzColorCombo[i].MoveWindow (&rcComboDummy);
+ pComboDummy->DestroyWindow ();
+ for (r = 0; r <= 256; r += 64) {
+ for (g = 0; g <= 256; g += 64) {
+ for (b = 0; b <= 256; b += 64) {
+ m_theHorzColorCombo[i].AddSampleColor (RGB (MIN (r, 255), MIN (g, 255), MIN (b, 255)));
+ }
+ }
+ }
+ m_theHorzColorCombo[i].AddSampleColor (COLORSELECTCOMBOBOX_OTHER);
+ }
+ // 垂直線色
+ for (i = 0; i < 2; i++) {
+ m_theVertColorCombo[i].Create
+ (WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL,
+ CRect (10, 10, 300, 300), this, IDC_COLOROPTION_VERTCOLOR_00 + 16 + i);
+ CRect rcComboDummy;
+ CWnd* pComboDummy = GetDlgItem (IDC_COLOROPTION_VERTCOLOR_00 + i);
+ pComboDummy->GetWindowRect (&rcComboDummy);
+ this->ScreenToClient (&rcComboDummy);
+ m_theVertColorCombo[i].MoveWindow (&rcComboDummy);
+ pComboDummy->DestroyWindow ();
+ for (r = 0; r <= 256; r += 64) {
+ for (g = 0; g <= 256; g += 64) {
+ for (b = 0; b <= 256; b += 64) {
+ m_theVertColorCombo[i].AddSampleColor (RGB (MIN (r, 255), MIN (g, 255), MIN (b, 255)));
+ }
+ }
+ }
+ m_theVertColorCombo[i].AddSampleColor (COLORSELECTCOMBOBOX_OTHER);
+ }
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CColorOptionPage, CPropertyPage)
+END_MESSAGE_MAP ()
+
+
+
+
diff --git a/src/ColorOptionPage.h b/src/ColorOptionPage.h
new file mode 100644
index 0000000..a93ce85
--- /dev/null
+++ b/src/ColorOptionPage.h
@@ -0,0 +1,61 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// オプション(色)プロパティページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* This library is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Lesser Color 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 Color Public License for more details. */
+
+/* You should have received a copy of the GNU Lesser Color 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 */
+
+#ifndef _COLOROPTIONPAGE_H_
+#define _COLOROPTIONPAGE_H_
+
+#include "ColorSelectComboBox.h"
+
+class CColorOptionPage : public CPropertyPage {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CColorSelectComboBox m_theForeColorCombo[8];
+ CColorSelectComboBox m_theBackColorCombo[2];
+ CColorSelectComboBox m_theHorzColorCombo[2];
+ CColorSelectComboBox m_theVertColorCombo[2];
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CColorOptionPage (); // コンストラクタ
+ enum {IDD = IDD_COLOROPTION};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/ColorSelectComboBox.cpp b/src/ColorSelectComboBox.cpp
new file mode 100644
index 0000000..f014973
--- /dev/null
+++ b/src/ColorSelectComboBox.cpp
@@ -0,0 +1,190 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 色選択コンボボックスクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxdlgs.h>
+#include "ColorSelectComboBox.h"
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CColorSelectComboBox, CComboBox)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CColorSelectComboBox, CComboBox)
+ ON_CONTROL_REFLECT (CBN_SELCHANGE, OnSelChange)
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウスタイルの変更
+BOOL CColorSelectComboBox::PreCreateWindow (CREATESTRUCT& cs) {
+ if (!CComboBox::PreCreateWindow (cs)) {
+ return FALSE;
+ }
+ cs.dwExStyle |= WS_EX_CLIENTEDGE;
+ cs.style &= ~(CBS_DROPDOWN | CBS_SIMPLE | CBS_OWNERDRAWVARIABLE | CBS_SORT);
+ cs.style |= (CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS);
+ return TRUE;
+}
+
+// 項目の高さ
+void CColorSelectComboBox::MeasureItem (LPMEASUREITEMSTRUCT lpmis) {
+ lpmis->itemHeight = 14;
+}
+
+// 項目の描画
+void CColorSelectComboBox::DrawItem (LPDRAWITEMSTRUCT lpdis) {
+ CDC dc;
+ dc.Attach (lpdis->hDC);
+ CRect rect = lpdis->rcItem;
+ int nIndex = lpdis->itemID;
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateSolidBrush (::GetSysColor ((lpdis->itemState &
+ ODS_SELECTED) ? COLOR_HIGHLIGHT : COLOR_WINDOW));
+ dc.FillRect (rect, pBrush);
+ delete pBrush;
+
+ if (lpdis->itemState & ODS_FOCUS) {
+ dc.DrawFocusRect (rect);
+ }
+
+ if (nIndex != (UINT)-1) {
+ COLORREF clrSample = (COLORREF)GetItemData (nIndex);
+ if (clrSample == COLORSELECTCOMBOBOX_OTHER) {
+ CFont* pFont = CFont::FromHandle
+ ((HFONT)(::GetStockObject (DEFAULT_GUI_FONT)));
+ CFont* pOldFont = dc.SelectObject (pFont);
+ dc.SetBkMode (TRANSPARENT);
+ dc.DrawText (_T("Others..."), rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ dc.SelectObject (pOldFont);
+ }
+ else {
+ CRect rcSample (rect);
+ rcSample.DeflateRect (3, 3);
+ dc.FillSolidRect (rcSample, clrSample);
+ }
+ }
+ else {
+ CRect rcSample (rect);
+ rcSample.DeflateRect (3, 3);
+ dc.FillSolidRect (rcSample, m_clrCurColor);
+ }
+ dc.Detach ();
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 現在の色を設定する(この関数はいつでも使える。)
+BOOL CColorSelectComboBox::SetCurColor (COLORREF clr) {
+ if (clr < 0x00000000 || clr > 0x00FFFFFF) {
+ return FALSE;
+ }
+ m_clrCurColor = clr;
+ if (m_hWnd != NULL) {
+ int nCount = GetCount ();
+ int i;
+ // 一致するカラーサンプルを選択状態にする
+ for (i = 0; i <= nCount; i++) {
+ COLORREF clrSampleColor = GetItemData (i);
+ if (clrSampleColor == m_clrCurColor) {
+ SetCurSel (i);
+ break;
+ }
+ }
+ // 一致するカラーサンプルがなかったので選択解除
+ if (i >= nCount) {
+ SetCurSel (-1);
+ }
+ Invalidate ();
+ }
+ return TRUE;
+}
+
+// すべてのカラーサンプルをクリアする。
+void CColorSelectComboBox::ClearSampleColor () {
+ ResetContent ();
+}
+
+// カラーサンプルを追加する。
+int CColorSelectComboBox::AddSampleColor (COLORREF clr) {
+ int nIndex = AddString (_T(""));
+ if (nIndex == CB_ERR || nIndex == CB_ERRSPACE) {
+ return nIndex;
+ }
+ return SetSampleColor (nIndex , (DWORD)clr);
+}
+
+// カラーサンプルを取得する。
+COLORREF CColorSelectComboBox::GetSampleColor (int nIndex) const {
+ return (COLORREF)GetItemData (nIndex);
+}
+
+// カラーサンプルを設定する。
+int CColorSelectComboBox::SetSampleColor (int nIndex, COLORREF clr) {
+ int nRet = SetItemData (nIndex, (DWORD)clr);
+ int nCurSel = GetCurSel ();
+ // 新しいカラーサンプルとカレントカラーの一致チェック
+ if (nCurSel == CB_ERR || nCurSel == nIndex) {
+ COLORREF clrSampleColor = GetItemData (nIndex);
+ // 新しいカラーサンプルとカレントカラーは一致したので選択
+ if (clrSampleColor == m_clrCurColor) {
+ SetCurSel (nIndex);
+ }
+ // 新しいカラーサンプルとカレントカラーは一致しなかったので選択解除
+ else {
+ SetCurSel (-1);
+ }
+ }
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// カレントセルが変更されたとき(メッセージリフレクション)
+void CColorSelectComboBox::OnSelChange () {
+ int nCurSel = GetCurSel ();
+ if (0 <= nCurSel && nCurSel < GetCount ()) {
+ COLORREF clrCurColor = (COLORREF)GetItemData (nCurSel);
+ if (clrCurColor == COLORSELECTCOMBOBOX_OTHER) {
+ CColorDialog theDlg;
+ theDlg.m_cc.Flags |= (CC_FULLOPEN | CC_RGBINIT);
+ theDlg.m_cc.rgbResult = m_clrCurColor;
+ if (theDlg.DoModal () == IDOK) {
+ m_clrCurColor = theDlg.GetColor ();
+ }
+ SetCurSel (-1);
+ }
+ else {
+ m_clrCurColor = clrCurColor;
+ }
+ Invalidate ();
+ }
+}
diff --git a/src/ColorSelectComboBox.h b/src/ColorSelectComboBox.h
new file mode 100644
index 0000000..309ff44
--- /dev/null
+++ b/src/ColorSelectComboBox.h
@@ -0,0 +1,81 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 色選択コンボボックスクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+// 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
+
+#ifndef _COLORSELECTCOMBOBOX_H_
+#define _COLORSELECTCOMBOBOX_H_
+
+#define COLORSELECTCOMBOBOX_BLACK (RGB (0, 0, 0))
+#define COLORSELECTCOMBOBOX_DARKRED (RGB (128, 0, 0))
+#define COLORSELECTCOMBOBOX_DARKGREEN (RGB (0, 128, 0))
+#define COLORSELECTCOMBOBOX_DARKYELLOW (RGB (128, 128, 0))
+#define COLORSELECTCOMBOBOX_DARKBLUE (RGB (0, 0, 128))
+#define COLORSELECTCOMBOBOX_DARKMAGENTA (RGB (128, 0, 128))
+#define COLORSELECTCOMBOBOX_DARKCYAN (RGB (0, 128, 128))
+#define COLORSELECTCOMBOBOX_DARKGRAY (RGB (128, 128, 128))
+#define COLORSELECTCOMBOBOX_GRAY (RGB (192, 192, 192))
+#define COLORSELECTCOMBOBOX_RED (RGB (255, 0, 0))
+#define COLORSELECTCOMBOBOX_GREEN (RGB (0, 255, 0))
+#define COLORSELECTCOMBOBOX_YELLOW (RGB (255, 255, 0)
+#define COLORSELECTCOMBOBOX_BLUE (RGB (0, 0, 255))
+#define COLORSELECTCOMBOBOX_MAGENTA (RGB (255, 0, 255))
+#define COLORSELECTCOMBOBOX_CYAN (RGB (0, 255, 255))
+#define COLORSELECTCOMBOBOX_WHITE (RGB (255, 255, 255))
+#define COLORSELECTCOMBOBOX_OTHER 0xFFFFFFFF
+
+class CColorSelectComboBox : public CComboBox {
+ DECLARE_DYNCREATE (CColorSelectComboBox)
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ COLORREF m_clrCurColor;
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT&);
+ virtual void MeasureItem (LPMEASUREITEMSTRUCT);
+ virtual void DrawItem (LPDRAWITEMSTRUCT);
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetCurColor (COLORREF clr);
+ COLORREF GetCurColor () const { return m_clrCurColor; }
+ void ClearSampleColor ();
+ int AddSampleColor (COLORREF clr);
+ COLORREF GetSampleColor (int nIndex) const;
+ int SetSampleColor (int nIndex, COLORREF clr);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnSelChange ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/ColorfulCheckListBox.cpp b/src/ColorfulCheckListBox.cpp
new file mode 100644
index 0000000..d3d4951
--- /dev/null
+++ b/src/ColorfulCheckListBox.cpp
@@ -0,0 +1,186 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// カラフルなチェックリストボックスクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include "ColorfulCheckListBox.h"
+
+// TSIZEOFマクロ //20120211追加
+#ifndef TSIZEOF
+#define TSIZEOF(STR) (sizeof(STR)/sizeof(TCHAR))
+#endif
+#ifndef TCSLEN
+#ifdef UNICODE
+#define TCSLEN(STRING) wcslen(STRING)
+#else
+#define TCSLEN(STRING) strlen(STRING)
+#endif
+#endif
+#ifndef TCSNCPY
+#ifdef UNICODE
+#define TCSNCPY(STRING1,STRING2,N) wcsncpy(STRING1,STRING2,N)
+#else
+#define TCSNCPY(STRING1,STRING2,N) strncpy(STRING1,STRING2,N)
+#endif
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CColorfulCheckListBox, CCheckListBox)
+
+BEGIN_MESSAGE_MAP (CColorfulCheckListBox, CCheckListBox)
+ //ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+END_MESSAGE_MAP ()
+
+typedef struct {
+ TCHAR m_szText[1024];
+ COLORREF m_lForeColor;
+ COLORREF m_lBackColor;
+} ItemData;
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CColorfulCheckListBox::CColorfulCheckListBox () {
+ CCheckListBox::CCheckListBox ();
+}
+
+// デストラクタ
+CColorfulCheckListBox::~CColorfulCheckListBox () {
+ CCheckListBox::~CCheckListBox ();
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウスタイルの変更
+BOOL CColorfulCheckListBox::PreCreateWindow (CREATESTRUCT& cs) {
+ if (!CCheckListBox::PreCreateWindow (cs)) {
+ return FALSE;
+ }
+ cs.dwExStyle |= WS_EX_CLIENTEDGE;
+ cs.style &= ~(LBS_OWNERDRAWVARIABLE | LBS_SORT);
+ cs.style |= LBS_OWNERDRAWFIXED;
+ return TRUE;
+}
+
+// アイテム高さの変更
+void CColorfulCheckListBox::MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
+ lpMeasureItemStruct->itemHeight = 12;
+}
+
+// アイテム描画ルーチン
+void CColorfulCheckListBox::DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct) {
+ int nIndex = lpDrawItemStruct->itemID;
+ CRect rcItem = lpDrawItemStruct->rcItem;
+
+ CDC dc;
+ dc.Attach (lpDrawItemStruct->hDC);
+
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ if (lpDrawItemStruct->itemState & ODS_SELECTED) {
+ lBackColor = ::GetSysColor (COLOR_HIGHLIGHT);
+ }
+ if (nIndex != (UINT)-1) {
+ ItemData* pItemData = (ItemData*)GetItemDataPtr (nIndex);
+ if (lpDrawItemStruct->itemState & ODS_SELECTED) {
+ lBackColor = pItemData->m_lForeColor;
+ }
+ else {
+ lBackColor = pItemData->m_lBackColor;
+ }
+ }
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateSolidBrush (lBackColor);
+ dc.FillRect (rcItem, pBrush);
+ delete pBrush;
+
+ if (lpDrawItemStruct->itemState & ODS_FOCUS) {
+ dc.DrawFocusRect (rcItem);
+ }
+
+ if (nIndex != (UINT)-1) {
+ ItemData* pItemData = (ItemData*)GetItemDataPtr (nIndex);
+ CFont* pFont = CFont::FromHandle
+ ((HFONT)(::GetStockObject (DEFAULT_GUI_FONT)));
+ CFont* pOldFont = dc.SelectObject (pFont);
+ long lTextColor = (lpDrawItemStruct->itemState & ODS_SELECTED) ?
+ ::GetSysColor (COLOR_HIGHLIGHTTEXT) : pItemData->m_lForeColor;
+ dc.SetBkMode (TRANSPARENT);
+ dc.SetTextColor (lTextColor);
+ dc.DrawText (pItemData->m_szText, rcItem, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ dc.SelectObject (pOldFont);
+ }
+ dc.Detach ();
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// アイテムの追加
+int CColorfulCheckListBox::AddItem (LPCTSTR lpszText, COLORREF lForeColor, COLORREF lBackColor) {
+ int nIndex = AddString (_T(""));
+ if (nIndex == CB_ERR || nIndex == CB_ERRSPACE) {
+ return -1;
+ }
+ ItemData* pItemData = (ItemData*)calloc (sizeof (ItemData), 1);
+ if (pItemData == NULL) {
+ return -1;
+ }
+ TCSNCPY (pItemData->m_szText, lpszText, 1023);
+ pItemData->m_lForeColor = lForeColor;
+ pItemData->m_lBackColor = lBackColor;
+ int ret = SetItemDataPtr (nIndex, pItemData);
+ if (ret < 0) {
+ free (pItemData);
+ return -1;
+ }
+ return ret;
+
+}
+
+// 全アイテムの削除
+void CColorfulCheckListBox::RemoveAllItem () {
+ long i;
+ long lItemCount = this->GetCount ();
+ for (i = 0; i < lItemCount; i++) {
+ ItemData* pItemData = (ItemData*)GetItemDataPtr (i);
+ free (pItemData);
+ pItemData = NULL;
+ }
+ ResetContent ();
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ破壊時
+void CColorfulCheckListBox::OnDestroy () {
+ RemoveAllItem ();
+ CCheckListBox::OnDestroy ();
+}
diff --git a/src/ColorfulComboBox.cpp b/src/ColorfulComboBox.cpp
new file mode 100644
index 0000000..6e5d2fb
--- /dev/null
+++ b/src/ColorfulComboBox.cpp
@@ -0,0 +1,189 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// カラフルなコンボボックスボックスクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include "ColorfulComboBox.h"
+
+// TSIZEOFマクロ //20120211追加
+#ifndef TSIZEOF
+#define TSIZEOF(STR) (sizeof(STR)/sizeof(TCHAR))
+#endif
+#ifndef TCSLEN
+#ifdef UNICODE
+#define TCSLEN(STRING) wcslen(STRING)
+#else
+#define TCSLEN(STRING) strlen(STRING)
+#endif
+#endif
+#ifndef TCSNCPY
+#ifdef UNICODE
+#define TCSNCPY(STRING1,STRING2,N) wcsncpy(STRING1,STRING2,N)
+#else
+#define TCSNCPY(STRING1,STRING2,N) strncpy(STRING1,STRING2,N)
+#endif
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CColorfulComboBox, CComboBox)
+
+BEGIN_MESSAGE_MAP (CColorfulComboBox, CComboBox)
+ //ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+END_MESSAGE_MAP ()
+
+typedef struct {
+ TCHAR m_szText[1024];
+ COLORREF m_lForeColor;
+ COLORREF m_lBackColor;
+} ItemData;
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CColorfulComboBox::CColorfulComboBox () {
+ CComboBox::CComboBox ();
+}
+
+// デストラクタ
+CColorfulComboBox::~CColorfulComboBox () {
+ CComboBox::~CComboBox ();
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウスタイル変更
+BOOL CColorfulComboBox::PreCreateWindow (CREATESTRUCT& cs) {
+ if (!CComboBox::PreCreateWindow (cs)) {
+ return FALSE;
+ }
+ cs.dwExStyle |= WS_EX_CLIENTEDGE;
+ cs.style &= ~(CBS_OWNERDRAWVARIABLE | CBS_SORT);
+ cs.style |= CBS_OWNERDRAWFIXED;
+ return TRUE;
+}
+
+// アイテムの高さ指定
+void CColorfulComboBox::MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
+ lpMeasureItemStruct->itemHeight = 14;
+}
+
+// アイテムの描画
+void CColorfulComboBox::DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct) {
+ int nIndex = lpDrawItemStruct->itemID;
+ CRect rcItem = lpDrawItemStruct->rcItem;
+
+ CDC dc;
+ dc.Attach (lpDrawItemStruct->hDC);
+
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ if (lpDrawItemStruct->itemState & ODS_SELECTED) {
+ lBackColor = ::GetSysColor (COLOR_HIGHLIGHT);
+ }
+ if (nIndex != (UINT)-1) {
+ ItemData* pItemData = (ItemData*)GetItemDataPtr (nIndex);
+ if (lpDrawItemStruct->itemState & ODS_SELECTED) {
+ lBackColor = pItemData->m_lForeColor;
+ }
+ else {
+ lBackColor = pItemData->m_lBackColor;
+ }
+ }
+
+ CBrush* pBrush = new CBrush;
+ pBrush->CreateSolidBrush (lBackColor);
+ dc.FillRect (rcItem, pBrush);
+ delete pBrush;
+
+ if (lpDrawItemStruct->itemState & ODS_FOCUS) {
+ dc.DrawFocusRect (rcItem);
+ }
+
+ if (nIndex != (UINT)-1) {
+ ItemData* pItemData = (ItemData*)GetItemDataPtr (nIndex);
+ CFont* pFont = CFont::FromHandle
+ ((HFONT)(::GetStockObject (DEFAULT_GUI_FONT)));
+ CFont* pOldFont = dc.SelectObject (pFont);
+ long lTextColor = (lpDrawItemStruct->itemState & ODS_SELECTED) ?
+ ::GetSysColor (COLOR_HIGHLIGHTTEXT) : pItemData->m_lForeColor;
+ dc.SetBkMode (TRANSPARENT);
+ dc.SetTextColor (lTextColor);
+ dc.DrawText (pItemData->m_szText, rcItem, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ dc.SelectObject (pOldFont);
+ }
+ dc.Detach ();
+
+
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// アイテムの追加
+int CColorfulComboBox::AddItem (LPCTSTR lpszText, COLORREF lForeColor, COLORREF lBackColor) {
+ int nIndex = AddString (_T(""));
+ if (nIndex == CB_ERR || nIndex == CB_ERRSPACE) {
+ return -1;
+ }
+ ItemData* pItemData = (ItemData*)calloc (sizeof (ItemData), 1);
+ if (pItemData == NULL) {
+ return -1;
+ }
+ TCSNCPY (pItemData->m_szText, lpszText, 1023);
+ pItemData->m_lForeColor = lForeColor;
+ pItemData->m_lBackColor = lBackColor;
+ int ret = SetItemDataPtr (nIndex, pItemData);
+ if (ret < 0) {
+ free (pItemData);
+ return -1;
+ }
+ return ret;
+
+}
+
+// アイテムの全削除
+void CColorfulComboBox::RemoveAllItem () {
+ long i;
+ long lItemCount = this->GetCount ();
+ for (i = 0; i < lItemCount; i++) {
+ ItemData* pItemData = (ItemData*)GetItemDataPtr (i);
+ free (pItemData);
+ pItemData = NULL;
+ }
+ ResetContent ();
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ破壊時
+void CColorfulComboBox::OnDestroy () {
+ RemoveAllItem ();
+ CComboBox::OnDestroy ();
+}
+
+
diff --git a/src/ColorfulComboBox.h b/src/ColorfulComboBox.h
new file mode 100644
index 0000000..d41746a
--- /dev/null
+++ b/src/ColorfulComboBox.h
@@ -0,0 +1,58 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// カラフルなコンボボックスクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _COLORFULCOMBOBOX_H_
+#define _COLORFULCOMBOBOX_H_
+
+class CColorfulComboBox : public CComboBox {
+ DECLARE_DYNCREATE (CColorfulComboBox)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CColorfulComboBox ();
+ virtual ~CColorfulComboBox ();
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ int AddItem (LPCTSTR lpszText, COLORREF lForeColor, COLORREF lBackColor);
+ void RemoveAllItem ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+ virtual void MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct);
+ virtual void DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnDestroy ();
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/EditBeatScanDlg.cpp b/src/EditBeatScanDlg.cpp
new file mode 100644
index 0000000..d4bb426
--- /dev/null
+++ b/src/EditBeatScanDlg.cpp
@@ -0,0 +1,139 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ビート検出とテンポ自動挿入ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditBeatScanDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+// コンストラクタ
+CEditBeatScanDlg::CEditBeatScanDlg () : CDialog (CEditBeatScanDlg::IDD) {
+ m_lTimeMode = 0;
+ m_lTimeResolution = 0;
+ m_nBeatTrackIndex = 0;
+ m_nBeatIntervalIndex = 0;
+ m_nInsertTempo = 0;
+}
+
+// オペレーション
+
+// ビートトラックコンボボックスの充満
+BOOL CEditBeatScanDlg::FillBeatTrackCombo () {
+ CComboBox* pBeatTrackCombo = (CComboBox*)GetDlgItem (IDC_EDITBEATSCAN_BEATTRACK);
+ long lCount = m_theTrackNameArray.GetSize ();
+ long i;
+ CString strTextLine;
+ for (i = 0; i < lCount; i++) {
+ strTextLine.Format (_T("%d-%s"), i + 1, m_theTrackNameArray.GetAt (i));
+ pBeatTrackCombo->AddString (strTextLine);
+ }
+ return TRUE;
+}
+
+// ビート間隔コンボボックスの充満
+BOOL CEditBeatScanDlg::FillBeatIntervalCombo () {
+ CComboBox* pBeatIntervalCombo = (CComboBox*)GetDlgItem (IDC_EDITBEATSCAN_BEATINTERVAL);
+ CString strTextLine;
+ CString strFormat;
+ if (m_lTimeMode == 0) {
+ VERIFY (strFormat.LoadString (IDS_D_4DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 1);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 2);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 3);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_16DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 4);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_24DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 6);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_32DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 8);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_48DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 12);
+ pBeatIntervalCombo->AddString (strTextLine);
+ }
+ else {
+ VERIFY (strFormat.LoadString (IDS_D_1FRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 1);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_2DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 2);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_3DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 3);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_4DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 4);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_6DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 6);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 8);
+ pBeatIntervalCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 12);
+ pBeatIntervalCombo->AddString (strTextLine);
+ }
+ return TRUE;
+}
+
+// オーバーライド
+
+// ダイアログデータエクスチェンジ
+void CEditBeatScanDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_CBIndex (pDX, IDC_EDITBEATSCAN_BEATTRACK, m_nBeatTrackIndex);
+ DDX_CBIndex (pDX, IDC_EDITBEATSCAN_BEATINTERVAL, m_nBeatIntervalIndex);
+ DDX_Check (pDX, IDC_EDITBEATSCAN_INSERTTEMPO, m_nInsertTempo);
+}
+
+// ダイアログ初期化
+BOOL CEditBeatScanDlg::OnInitDialog () {
+ FillBeatTrackCombo ();
+ FillBeatIntervalCombo ();
+ BOOL bRet = CDialog::OnInitDialog ();
+ return bRet;
+}
+
+
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEditBeatScanDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditBeatScanDlg メッセージ ハンドラ
+
+
+
diff --git a/src/EditBeatScanDlg.h b/src/EditBeatScanDlg.h
new file mode 100644
index 0000000..9b8e8ed
--- /dev/null
+++ b/src/EditBeatScanDlg.h
@@ -0,0 +1,65 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ビート検出とテンポ自動挿入ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITBEATSCANDLG_H_
+#define _EDITBEATSCANDLG_H_
+
+class CEditBeatScanDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lTimeMode; // タイムモード
+ long m_lTimeResolution; // 分解能[tick/4分音符]又は[サブフレーム/1フレーム]
+ CStringArray m_theTrackNameArray; // トラック名の配列
+ int m_nBeatTrackIndex; // ビートの記録されたトラック番号(0〜65535)
+ int m_nBeatIntervalIndex; // ビートの間隔インデックス(0=4分音符〜)
+ int m_nInsertTempo; // テンポを自動挿入するか?
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditBeatScanDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITBEATSCAN};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL FillBeatTrackCombo ();
+ BOOL FillBeatIntervalCombo ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/EditBreakupAndTrillDlg.cpp b/src/EditBreakupAndTrillDlg.cpp
new file mode 100644
index 0000000..c7af825
--- /dev/null
+++ b/src/EditBreakupAndTrillDlg.cpp
@@ -0,0 +1,143 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 細分化とトリルダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditBreakupAndTrillDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+// コンストラクタ
+CEditBreakupAndTrillDlg::CEditBreakupAndTrillDlg () : CDialog (CEditBreakupAndTrillDlg::IDD) {
+ m_lTimeMode = 0;
+ m_lTimeResolution = 0;
+ m_nDurationIndex = 0;
+ m_nEnableTrill = 0;
+ m_nKeyShift = 0;
+}
+
+// オペレーション
+BOOL CEditBreakupAndTrillDlg::FillDurationCombo () {
+ CComboBox* pDurationCombo = (CComboBox*)GetDlgItem (IDC_EDITBREAKUPANDTRILL_DURATION);
+ CString strTextLine;
+ CString strFormat;
+ if (m_lTimeMode == 0) {
+ VERIFY (strFormat.LoadString (IDS_D_4DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 1);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 2);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 3);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_16DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 4);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_24DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 6);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_32DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 8);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_48DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 12);
+ pDurationCombo->AddString (strTextLine);
+ }
+ else {
+ VERIFY (strFormat.LoadString (IDS_D_1FRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 1);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_2DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 2);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_3DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 3);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_4DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 4);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_6DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 6);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 8);
+ pDurationCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 12);
+ pDurationCombo->AddString (strTextLine);
+ }
+
+ return TRUE;
+}
+
+BOOL CEditBreakupAndTrillDlg::SetKeyShiftRange () {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITBREAKUPANDTRILL_KEYSHIFTSP))->SetRange (-127, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITBREAKUPANDTRILL_KEYSHIFTSP))->SetPos (CLIP (-127, m_nKeyShift, 127));
+ return TRUE;
+}
+
+BOOL CEditBreakupAndTrillDlg::UpdateKeyShift () {
+ int nEnableTrill = ((CButton*)GetDlgItem (IDC_EDITBREAKUPANDTRILL_ENABLETRILL))->GetCheck ();
+ GetDlgItem (IDC_EDITBREAKUPANDTRILL_KEYSHIFT)->EnableWindow (nEnableTrill);
+ GetDlgItem (IDC_EDITBREAKUPANDTRILL_KEYSHIFTSP)->EnableWindow (nEnableTrill);
+ return TRUE;
+}
+
+
+// オーバーライド
+
+// データエクスチェンジ
+void CEditBreakupAndTrillDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_CBIndex (pDX, IDC_EDITBREAKUPANDTRILL_DURATION, m_nDurationIndex);
+ DDX_Check (pDX, IDC_EDITBREAKUPANDTRILL_ENABLETRILL, m_nEnableTrill);
+ DDX_Text (pDX, IDC_EDITBREAKUPANDTRILL_KEYSHIFT, m_nKeyShift);
+}
+
+
+BOOL CEditBreakupAndTrillDlg::OnInitDialog () {
+ FillDurationCombo ();
+ BOOL bRet = CDialog::OnInitDialog ();
+ UpdateKeyShift ();
+ SetKeyShiftRange ();
+ return bRet;
+}
+
+
+
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEditBreakupAndTrillDlg, CDialog)
+ ON_BN_CLICKED (IDC_EDITBREAKUPANDTRILL_ENABLETRILL, OnChangeEnableTrill)
+END_MESSAGE_MAP ()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditBreakupAndTrillDlg メッセージ ハンドラ
+
+void CEditBreakupAndTrillDlg::OnChangeEnableTrill () {
+ UpdateKeyShift ();
+}
+
diff --git a/src/EditBreakupAndTrillDlg.h b/src/EditBreakupAndTrillDlg.h
new file mode 100644
index 0000000..bd21cc4
--- /dev/null
+++ b/src/EditBreakupAndTrillDlg.h
@@ -0,0 +1,65 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 細分化とトリルダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITBREAKUPANDTRILLDLG_H_
+#define _EDITBREAKUPANDTRILLDLG_H_
+
+class CEditBreakupAndTrillDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lTimeMode; // タイムモード
+ long m_lTimeResolution; // 分解能[tick/4分音符]又は[サブフレーム/1フレーム]
+ int m_nDurationIndex; // 細分化後の1音の長さインデックス(0=4分音符〜)
+ int m_nEnableTrill; // トリルを有効にするか?
+ int m_nKeyShift; // トリル音のキーシフト
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditBreakupAndTrillDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITBREAKUPANDTRILL};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL FillDurationCombo (); // 音長さコンボボックスの充満
+ BOOL SetKeyShiftRange (); // トリル音のキーシフトの有効範囲設定
+ BOOL UpdateKeyShift (); // トリル音のキーシフトエディットボックス更新
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+ afx_msg void OnChangeEnableTrill ();
+};
+
+#endif
diff --git a/src/EditChannelDlg.cpp b/src/EditChannelDlg.cpp
new file mode 100644
index 0000000..c775d07
--- /dev/null
+++ b/src/EditChannelDlg.cpp
@@ -0,0 +1,109 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// チャンネルの変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditChannelDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+// コンストラクタ
+CEditChannelDlg::CEditChannelDlg () : CDialog (CEditChannelDlg::IDD) {
+ m_nAmount = 0; // チャンネル値又は変更量
+ m_nUnit = 0; // 単位
+}
+
+// オペレーション
+BOOL CEditChannelDlg::SetAmountRange () {
+ CButton* pByTrackUnitButton = (CButton*)GetDlgItem (IDC_EDITCHANNEL_BYTRACKUNIT);
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITCHANNEL_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITCHANNEL_RELATIVEUNIT);
+ CString strValue;
+ GetDlgItem (IDC_EDITCHANNEL_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pByTrackUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNT))->EnableWindow (FALSE);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNTSP))->EnableWindow (FALSE);
+ }
+ else if (pAbsoluteUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNT))->EnableWindow (TRUE);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNTSP))->EnableWindow (TRUE);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNTSP))->SetRange (1, 16);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNTSP))->SetPos (CLIP (1, lValue, 16));
+ }
+ else if (pRelativeUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNT))->EnableWindow (TRUE);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNTSP))->EnableWindow (TRUE);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNTSP))->SetRange (-15, 15);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITCHANNEL_AMOUNTSP))->SetPos (CLIP (-15, lValue, 15));
+ }
+ return TRUE;
+}
+
+
+// オーバーライド
+
+// データエクスチェンジ
+void CEditChannelDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITCHANNEL_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITCHANNEL_BYTRACKUNIT, m_nUnit);
+ CButton* pByTrackUnitButton = (CButton*)GetDlgItem (IDC_EDITCHANNEL_BYTRACKUNIT);
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITCHANNEL_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITCHANNEL_RELATIVEUNIT);
+ if (pByTrackUnitButton->GetCheck ()) {
+ ;
+ }
+ else if (pAbsoluteUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 1, 16);
+ }
+ else if (pRelativeUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -15, 15);
+ }
+}
+
+
+BOOL CEditChannelDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEditChannelDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITCHANNEL_BYTRACKUNIT, IDC_EDITCHANNEL_RELATIVEUNIT, OnChangeUnit)
+END_MESSAGE_MAP ()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditChannelDlg メッセージ ハンドラ
+
+// 単位が変更された
+void CEditChannelDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+
diff --git a/src/EditChannelDlg.h b/src/EditChannelDlg.h
new file mode 100644
index 0000000..3dbd4d8
--- /dev/null
+++ b/src/EditChannelDlg.h
@@ -0,0 +1,61 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// チャンネルの変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITCHANNELDLG_H_
+#define _EDITCHANNELDLG_H_
+
+class CEditChannelDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // チャンネル番号又は変更量
+ int m_nUnit; // モード(※1)
+ // ※1: 0=トラックの出力チャンネルに合わせる, 1=絶対指定, 2=相対変化
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditChannelDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITCHANNEL};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetAmountRange ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
+
diff --git a/src/EditDurationDlg.cpp b/src/EditDurationDlg.cpp
new file mode 100644
index 0000000..3ee871e
--- /dev/null
+++ b/src/EditDurationDlg.cpp
@@ -0,0 +1,113 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 音長さの変更ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditDurationDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditDurationDlg::CEditDurationDlg () : CDialog (CEditDurationDlg::IDD) {
+ m_nAmount = 0;
+ m_nUnit = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditDurationDlg::SetAmountRange () {
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_RELATIVEUNIT);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_PERCENTUNIT);
+ CButton* pRandomUpDownUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_RANDOMUPDOWNUNIT);
+ CString strValue;
+ GetDlgItem (IDC_EDITDURATION_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITDURATION_AMOUNTSP))->SetRange (1, 16383);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITDURATION_AMOUNTSP))->SetPos (CLIP (1, lValue, 16383));
+ }
+ else if (pRelativeUnitButton->GetCheck () || pRandomUpDownUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITDURATION_AMOUNTSP))->SetRange (-16383, 16383);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITDURATION_AMOUNTSP))->SetPos (CLIP (-16383, lValue, 16383));
+ }
+ else if (pPercentUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITDURATION_AMOUNTSP))->SetRange (0, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITDURATION_AMOUNTSP))->SetPos (CLIP (0, lValue, 1000));
+ }
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditDurationDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITDURATION_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITDURATION_ABSOLUTEUNIT, m_nUnit);
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_RELATIVEUNIT);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_PERCENTUNIT);
+ CButton* pRandomUpDownUnitButton = (CButton*)GetDlgItem (IDC_EDITDURATION_RANDOMUPDOWNUNIT);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 0, 16383);
+ }
+ else if (pRelativeUnitButton->GetCheck () || pRandomUpDownUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -16383, 16383);
+ }
+ else if (pPercentUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 0, 1000);
+ }
+}
+
+// ダイアログ初期化時
+BOOL CEditDurationDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditDurationDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITDURATION_ABSOLUTEUNIT, IDC_EDITDURATION_RANDOMUPDOWNUNIT, OnChangeUnit)
+END_MESSAGE_MAP ()
+
+// 単位が変更された
+void CEditDurationDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+
diff --git a/src/EditDurationDlg.h b/src/EditDurationDlg.h
new file mode 100644
index 0000000..44c6894
--- /dev/null
+++ b/src/EditDurationDlg.h
@@ -0,0 +1,61 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 音長さの変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITDURATIONDLG_H_
+#define _EDITDURATIONDLG_H_
+
+class CEditDurationDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // 音長さの変更量
+ int m_nUnit; // 単位(0=ティック, 1=パーセント)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditDurationDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITDURATION};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetAmountRange (); // 音長さの変更量の有効範囲設定
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif \ No newline at end of file
diff --git a/src/EditInsertMeasureDlg.cpp b/src/EditInsertMeasureDlg.cpp
new file mode 100644
index 0000000..13baf9c
--- /dev/null
+++ b/src/EditInsertMeasureDlg.cpp
@@ -0,0 +1,98 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 小節の挿入ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditInsertMeasureDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditInsertMeasureDlg::CEditInsertMeasureDlg () : CDialog (CEditInsertMeasureDlg::IDD) {
+ m_nPosition = 0;
+ m_nNumMeasure = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditInsertMeasureDlg::SetAmountRange () {
+ CString strValue;
+ GetDlgItem (IDC_EDITINSERTMEASURE_POSITION)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (m_bZeroOrigin) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITINSERTMEASURE_POSITIONSP))->SetRange (0, 32767);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITINSERTMEASURE_POSITIONSP))->SetPos (CLIP (0, lValue, 32767));
+ }
+ else {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITINSERTMEASURE_POSITIONSP))->SetRange (1, 32767);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITINSERTMEASURE_POSITIONSP))->SetPos (CLIP (1, lValue, 32767));
+ }
+ GetDlgItem (IDC_EDITINSERTMEASURE_NUMMEASURE)->GetWindowText (strValue);
+ lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITINSERTMEASURE_NUMMEASURESP))->SetRange (1, 256);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITINSERTMEASURE_NUMMEASURESP))->SetPos (CLIP (1, lValue, 256));
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditInsertMeasureDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITINSERTMEASURE_POSITION, m_nPosition);
+ if (m_bZeroOrigin) {
+ DDV_MinMaxInt (pDX, m_nPosition, 0, 32767);
+ }
+ else {
+ DDV_MinMaxInt (pDX, m_nPosition, 1, 32767);
+ }
+ DDX_Text (pDX, IDC_EDITINSERTMEASURE_NUMMEASURE, m_nNumMeasure);
+ DDV_MinMaxInt (pDX, m_nNumMeasure, 1, 256);
+}
+
+// ダイアログ初期化時
+BOOL CEditInsertMeasureDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditInsertMeasureDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
+
diff --git a/src/EditInsertMeasureDlg.h b/src/EditInsertMeasureDlg.h
new file mode 100644
index 0000000..b4ded69
--- /dev/null
+++ b/src/EditInsertMeasureDlg.h
@@ -0,0 +1,59 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 小節の挿入ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITINSERTMEASUREDLG_H_
+#define _EDITINSERTMEASUREDLG_H_
+
+class CEditInsertMeasureDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nPosition; // 位置
+ int m_nNumMeasure; // 小節数
+ BOOL m_bZeroOrigin; // ゼロオリジンか?
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditInsertMeasureDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITINSERTMEASURE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ BOOL SetAmountRange ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログ初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EditKeyDlg.cpp b/src/EditKeyDlg.cpp
new file mode 100644
index 0000000..e1f8579
--- /dev/null
+++ b/src/EditKeyDlg.cpp
@@ -0,0 +1,112 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 音程の変更ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditKeyDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditKeyDlg::CEditKeyDlg () : CDialog (CEditKeyDlg::IDD) {
+ m_nAmount = 0;
+ m_nUnit = 0;
+ m_nTargetNote = 0;
+ m_nTargetKeyAfter = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditKeyDlg::SetAmountRange () {
+ CButton* pHalfUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_HALFUNIT);
+ CButton* pOctaveUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_OCTAVEUNIT);
+ CButton* pRandomHalfUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_RANDOMHALFUNIT);
+ CButton* pRandomOctaveUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_RANDOMOCTAVEUNIT);
+ CString strValue;
+ GetDlgItem (IDC_EDITKEY_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pHalfUnitButton->GetCheck () || pRandomHalfUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITKEY_AMOUNTSP))->SetRange (-127, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITKEY_AMOUNTSP))->SetPos (CLIP (-127, lValue, 127));
+ }
+ else if (pOctaveUnitButton->GetCheck () || pRandomOctaveUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITKEY_AMOUNTSP))->SetRange (-10, 10);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITKEY_AMOUNTSP))->SetPos (CLIP (-10, lValue, 10));
+ }
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditKeyDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITKEY_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITKEY_HALFUNIT, m_nUnit);
+ DDX_Check (pDX, IDC_EDITKEY_TARGETNOTE, m_nTargetNote);
+ DDX_Check (pDX, IDC_EDITKEY_TARGETKEYAFTER, m_nTargetKeyAfter);
+ CButton* pHalfUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_HALFUNIT);
+ CButton* pOctaveUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_OCTAVEUNIT);
+ CButton* pRandomHalfUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_RANDOMHALFUNIT);
+ CButton* pRandomOctaveUnitButton = (CButton*)GetDlgItem (IDC_EDITKEY_RANDOMOCTAVEUNIT);
+ if (pHalfUnitButton->GetCheck () || pRandomHalfUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -127, 127);
+ }
+ else if (pOctaveUnitButton->GetCheck () || pRandomOctaveUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -10, 10);
+ }
+}
+
+
+BOOL CEditKeyDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditKeyDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITKEY_HALFUNIT, IDC_EDITKEY_RANDOMOCTAVEUNIT, OnChangeUnit)
+END_MESSAGE_MAP ()
+
+// 単位が変更された
+void CEditKeyDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+
diff --git a/src/EditKeyDlg.h b/src/EditKeyDlg.h
new file mode 100644
index 0000000..b64d696
--- /dev/null
+++ b/src/EditKeyDlg.h
@@ -0,0 +1,63 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 音程の変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITKEYDLG_H_
+#define _EDITKEYDLG_H_
+
+class CEditKeyDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // 音程の変更量
+ int m_nUnit; // 単位(0=半音, 1=オクターブ)
+ int m_nTargetNote; // ノートオン・ノートオフを対象とする(0/1)
+ int m_nTargetKeyAfter; // キーアフタータッチを対象とする(0/1)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditKeyDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITKEY};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetAmountRange (); // 音程の変更量の範囲設定
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif \ No newline at end of file
diff --git a/src/EditQuantizeDlg.cpp b/src/EditQuantizeDlg.cpp
new file mode 100644
index 0000000..1fc6b22
--- /dev/null
+++ b/src/EditQuantizeDlg.cpp
@@ -0,0 +1,142 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// クォンタイズダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditQuantizeDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//-----------------------------------------------------------------------------
+// 構築と破壊
+//-----------------------------------------------------------------------------
+
+// コンストラクタ
+CEditQuantizeDlg::CEditQuantizeDlg () : CDialog (CEditQuantizeDlg::IDD) {
+ m_lTimeMode = 0;
+ m_lTimeResolution = 0;
+ m_nSnapTimeIndex = 3;
+ //m_strSnapTime = _T("");
+ m_nStrength = 0;
+ m_nTargetNoteOn = 0;
+ m_nTargetNoteOff = 0;
+}
+
+//-----------------------------------------------------------------------------
+// オペレーション
+//-----------------------------------------------------------------------------
+
+// 値の範囲設定
+BOOL CEditQuantizeDlg::SetAmountRange () {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITQUANTIZE_STRENGTHSP))->SetRange (0, 100);
+ return TRUE;
+}
+
+// スナップタイムコンボボックスの充満
+BOOL CEditQuantizeDlg::FillSnapTimeCombo () {
+ CComboBox* pSnapTimeCombo = (CComboBox*)GetDlgItem (IDC_EDITQUANTIZE_SNAPTIME);
+ CString strTextLine;
+ CString strFormat;
+ if (m_lTimeMode == 0) {
+ VERIFY (strFormat.LoadString (IDS_D_4DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 1);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 2);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 3);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_16DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 4);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_24DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 6);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_32DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 8);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_48DIVNOTE));
+ strTextLine.Format (strFormat, m_lTimeResolution / 12);
+ pSnapTimeCombo->AddString (strTextLine);
+ }
+ else {
+ VERIFY (strFormat.LoadString (IDS_D_1FRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 1);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_2DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 2);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_3DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 3);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_4DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 4);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_6DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 6);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 8);
+ pSnapTimeCombo->AddString (strTextLine);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVFRAME));
+ strTextLine.Format (strFormat, m_lTimeResolution / 12);
+ pSnapTimeCombo->AddString (strTextLine);
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// オーバーライド
+//-----------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditQuantizeDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ //DDX_CBString (pDX, IDC_EDITQUANTIZE_SNAPTIME, m_strSnapTime);
+ DDX_CBIndex (pDX, IDC_EDITQUANTIZE_SNAPTIME, m_nSnapTimeIndex);
+ DDX_Text (pDX, IDC_EDITQUANTIZE_STRENGTH, m_nStrength);
+ DDX_Check (pDX, IDC_EDITQUANTIZE_TARGETNOTEON, m_nTargetNoteOn);
+ DDX_Check (pDX, IDC_EDITQUANTIZE_TARGETNOTEOFF, m_nTargetNoteOff);
+ DDV_MinMaxInt (pDX, m_nStrength, 0, 100);
+}
+
+// ダイアログ初期化時
+BOOL CEditQuantizeDlg::OnInitDialog () {
+ FillSnapTimeCombo ();
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+//-----------------------------------------------------------------------------
+// メッセージマップ
+//-----------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CEditQuantizeDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
+
diff --git a/src/EditQuantizeDlg.h b/src/EditQuantizeDlg.h
new file mode 100644
index 0000000..aeb990a
--- /dev/null
+++ b/src/EditQuantizeDlg.h
@@ -0,0 +1,64 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// クォンタイズダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITQUANTIZEDLG_H_
+#define _EDITQUANTIZEDLG_H_
+
+class CEditQuantizeDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_lTimeMode; // タイムモード(0=TPQNベース, ...)
+ int m_lTimeResolution; // 分解能[tick/4分音符]又は[サブフレーム/1フレーム]
+ int m_nSnapTimeIndex; // スナップタイムインデックス(0=4分音符,1=8分音符...)
+ int m_nStrength; // 強度[%]
+ int m_nTargetNoteOn; // ノートオンを対象とする(0/1)
+ int m_nTargetNoteOff; // ノートオフを対象とする(0/1)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditQuantizeDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITQUANTIZE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ BOOL SetAmountRange (); // 強度の有効範囲を設定する
+ BOOL FillSnapTimeCombo (); // スナップタイムコンボボックスを充満させる
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EditRemoveMeasureDlg.cpp b/src/EditRemoveMeasureDlg.cpp
new file mode 100644
index 0000000..0bc3e97
--- /dev/null
+++ b/src/EditRemoveMeasureDlg.cpp
@@ -0,0 +1,98 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 小節の除去ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditRemoveMeasureDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditRemoveMeasureDlg::CEditRemoveMeasureDlg () : CDialog (CEditRemoveMeasureDlg::IDD) {
+ m_nPosition = 0;
+ m_nNumMeasure = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditRemoveMeasureDlg::SetAmountRange () {
+ CString strValue;
+ GetDlgItem (IDC_EDITREMOVEMEASURE_POSITION)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (m_bZeroOrigin) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITREMOVEMEASURE_POSITIONSP))->SetRange (0, 32767);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITREMOVEMEASURE_POSITIONSP))->SetPos (CLIP (0, lValue, 32767));
+ }
+ else {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITREMOVEMEASURE_POSITIONSP))->SetRange (1, 32767);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITREMOVEMEASURE_POSITIONSP))->SetPos (CLIP (1, lValue, 32767));
+ }
+ GetDlgItem (IDC_EDITREMOVEMEASURE_NUMMEASURE)->GetWindowText (strValue);
+ lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITREMOVEMEASURE_NUMMEASURESP))->SetRange (1, 256);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITREMOVEMEASURE_NUMMEASURESP))->SetPos (CLIP (1, lValue, 256));
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditRemoveMeasureDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITREMOVEMEASURE_POSITION, m_nPosition);
+ if (m_bZeroOrigin) {
+ DDV_MinMaxInt (pDX, m_nPosition, 0, 32767);
+ }
+ else {
+ DDV_MinMaxInt (pDX, m_nPosition, 1, 32767);
+ }
+ DDX_Text (pDX, IDC_EDITREMOVEMEASURE_NUMMEASURE, m_nNumMeasure);
+ DDV_MinMaxInt (pDX, m_nNumMeasure, 1, 256);
+}
+
+// ダイアログ初期化時
+BOOL CEditRemoveMeasureDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditRemoveMeasureDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
+
diff --git a/src/EditRemoveMeasureDlg.h b/src/EditRemoveMeasureDlg.h
new file mode 100644
index 0000000..f65d0c9
--- /dev/null
+++ b/src/EditRemoveMeasureDlg.h
@@ -0,0 +1,59 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 小節の除去ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITREMOVEMEASUREDLG_H_
+#define _EDITREMOVEMEASUREDLG_H_
+
+class CEditRemoveMeasureDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nPosition; // 位置
+ int m_nNumMeasure; // 小節数
+ BOOL m_bZeroOrigin; // ゼロオリジンか?
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditRemoveMeasureDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITREMOVEMEASURE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ BOOL SetAmountRange ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログ初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EditTimeDlg.cpp b/src/EditTimeDlg.cpp
new file mode 100644
index 0000000..148fe79
--- /dev/null
+++ b/src/EditTimeDlg.cpp
@@ -0,0 +1,102 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// タイムの変更(TPQNベース用)ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditTimeDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditTimeDlg::CEditTimeDlg () : CDialog (CEditTimeDlg::IDD) {
+ m_nAmount = 0;
+ m_nUnit = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditTimeDlg::SetAmountRange () {
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITTIME_PERCENTUNIT);
+ CString strValue;
+ GetDlgItem (IDC_EDITTIME_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pPercentUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIME_AMOUNTSP))->SetRange (0, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIME_AMOUNTSP))->SetPos (CLIP (0, lValue, 1000));
+ }
+ else {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIME_AMOUNTSP))->SetRange (-8192, 8192);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIME_AMOUNTSP))->SetPos (CLIP (-8192, lValue, 8192));
+ }
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditTimeDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITTIME_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITTIME_TICKUNIT, m_nUnit);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITTIME_PERCENTUNIT);
+ if (pPercentUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 0, 1000);
+ }
+ else {
+ DDV_MinMaxInt (pDX, m_nAmount, -8192, 8192);
+ }
+}
+
+
+BOOL CEditTimeDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditTimeDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITTIME_TICKUNIT, IDC_EDITTIME_RANDOMTICKUNIT, OnChangeUnit)
+END_MESSAGE_MAP ()
+
+// 単位が変更された
+void CEditTimeDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+
diff --git a/src/EditTimeDlg.h b/src/EditTimeDlg.h
new file mode 100644
index 0000000..2b60fd3
--- /dev/null
+++ b/src/EditTimeDlg.h
@@ -0,0 +1,62 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// タイムの変更(TPQNベース用)ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITTIMEDLG_H_
+#define _EDITTIMEDLG_H_
+
+
+class CEditTimeDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // タイムの変更量
+ int m_nUnit; // 単位(0=小節,1=拍,2=ティック,3=パーセント)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditTimeDlg (); // コンストラクタ
+ enum {IDD = IDD_EDITTIME};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetAmountRange (); // タイムの変更量の有効範囲設定
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EditTimeSmpDlg.cpp b/src/EditTimeSmpDlg.cpp
new file mode 100644
index 0000000..775fe90
--- /dev/null
+++ b/src/EditTimeSmpDlg.cpp
@@ -0,0 +1,102 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// タイムの変更(SMPTEベース用)ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditTimeSmpDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditTimeSmpDlg::CEditTimeSmpDlg () : CDialog (CEditTimeSmpDlg::IDD) {
+ m_nAmount = 0;
+ m_nUnit = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditTimeSmpDlg::SetAmountRange () {
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITTIMESMP_PERCENTUNIT);
+ CString strValue;
+ GetDlgItem (IDC_EDITTIMESMP_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pPercentUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIMESMP_AMOUNTSP))->SetRange (0, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIMESMP_AMOUNTSP))->SetPos (CLIP (0, lValue, 1000));
+ }
+ else {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIMESMP_AMOUNTSP))->SetRange (-8192, 8192);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTIMESMP_AMOUNTSP))->SetPos (CLIP (-8192, lValue, 8192));
+ }
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditTimeSmpDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITTIMESMP_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITTIMESMP_TICKUNIT, m_nUnit);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITTIMESMP_PERCENTUNIT);
+ if (pPercentUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 0, 1000);
+ }
+ else {
+ DDV_MinMaxInt (pDX, m_nAmount, -8192, 8192);
+ }
+}
+
+
+BOOL CEditTimeSmpDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditTimeSmpDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITTIMESMP_TICKUNIT, IDC_EDITTIMESMP_RANDOMTICKUNIT, OnChangeUnit)
+END_MESSAGE_MAP ()
+
+// 単位が変更された
+void CEditTimeSmpDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+
diff --git a/src/EditTimeSmpDlg.h b/src/EditTimeSmpDlg.h
new file mode 100644
index 0000000..f8073d3
--- /dev/null
+++ b/src/EditTimeSmpDlg.h
@@ -0,0 +1,61 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// タイムの変更(SMPTEベース用)ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITTIMESMPDLG_H_
+#define _EDITTIMESMPDLG_H_
+
+
+class CEditTimeSmpDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // タイムの変更量
+ int m_nUnit; // 単位(0=サブフレーム,1=フレーム,2=パーセント)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditTimeSmpDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITTIMESMP};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetAmountRange (); // タイムの変更量の有効範囲を設定
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EditTrackDlg.cpp b/src/EditTrackDlg.cpp
new file mode 100644
index 0000000..5f335e2
--- /dev/null
+++ b/src/EditTrackDlg.cpp
@@ -0,0 +1,109 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックの変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "resource.h"
+#include "SekaijuApp.h"
+#include "EditTrackDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+// コンストラクタ
+CEditTrackDlg::CEditTrackDlg () : CDialog (CEditTrackDlg::IDD) {
+ m_nAmount = 1;
+ m_nUnit = 0;
+ m_nFitChannel = 0;
+}
+
+// オペレーション
+BOOL CEditTrackDlg::SetAmountRange () {
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITTRACK_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITTRACK_RELATIVEUNIT);
+ CString strValue;
+ GetDlgItem (IDC_EDITTRACK_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTRACK_AMOUNTSP))->SetRange (1, 256);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTRACK_AMOUNTSP))->SetPos (CLIP (1, lValue, 256));
+ }
+ else if (pRelativeUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTRACK_AMOUNTSP))->SetRange (-255, 2555);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITTRACK_AMOUNTSP))->SetPos (CLIP (-255, lValue, 255));
+ }
+ return TRUE;
+}
+
+
+// オーバーライド
+
+// データエクスチェンジ
+void CEditTrackDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITTRACK_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITTRACK_ABSOLUTEUNIT, m_nUnit);
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITTRACK_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITTRACK_RELATIVEUNIT);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ DDV_MinMaxInt (pDX, m_nAmount,
+ (bTrackZeroOrigin ? 0 : 1),
+ (bTrackZeroOrigin ? 255 : 256)); // TODO:
+ }
+ else if (pRelativeUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -255, 255);
+ }
+ DDX_Check (pDX, IDC_EDITTRACK_FITCHANNEL, m_nFitChannel);
+}
+
+
+BOOL CEditTrackDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEditTrackDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITTRACK_ABSOLUTEUNIT, IDC_EDITTRACK_RELATIVEUNIT, OnChangeUnit)
+END_MESSAGE_MAP ()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditTrackDlg メッセージ ハンドラ
+
+// 単位が変更された
+void CEditTrackDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+
diff --git a/src/EditTrackDlg.h b/src/EditTrackDlg.h
new file mode 100644
index 0000000..40c1278
--- /dev/null
+++ b/src/EditTrackDlg.h
@@ -0,0 +1,60 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックの変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITTRACKDLG_H_
+#define _EDITTRACKDLG_H_
+
+class CEditTrackDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // トラック番号又は変更量
+ int m_nUnit; // 単位(0=絶対指定,1=相対変化)
+ BOOL m_nFitChannel; // 各イベントのチャンネルをトラックの出力チャンネルに合わせる
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditTrackDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITTRACK};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetAmountRange (); // トラック番号又は変更量の有効範囲設定
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif \ No newline at end of file
diff --git a/src/EditValueDlg.cpp b/src/EditValueDlg.cpp
new file mode 100644
index 0000000..dfec8da
--- /dev/null
+++ b/src/EditValueDlg.cpp
@@ -0,0 +1,149 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 値の変更ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditValueDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditValueDlg::CEditValueDlg () : CDialog (CEditValueDlg::IDD) {
+ m_nAmount = 0;
+ m_nUnit = 0;
+ m_nTargetKeyAfter = 0;
+ m_nTargetControlChange = 0;
+ m_nTargetChannelAfter = 0;
+ m_nTargetPitchBend = 0;
+
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditValueDlg::SetAmountRange () {
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_RELATIVEUNIT);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_PERCENTUNIT);
+ CButton* pRandomUpDownUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_RANDOMUPDOWNUNIT);
+ CButton* pTargetPitchBendButton = (CButton*)GetDlgItem (IDC_EDITVALUE_TARGETPITCHBEND);
+ CString strValue;
+ GetDlgItem (IDC_EDITVALUE_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ if (pTargetPitchBendButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetRange (-8192, 8191);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetPos (CLIP (-8192, lValue, 8191));
+ }
+ else {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetRange (0, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetPos (CLIP (0, lValue, 127));
+ }
+ }
+ else if (pRelativeUnitButton->GetCheck () || pRandomUpDownUnitButton->GetCheck ()) {
+ if (pTargetPitchBendButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetRange (-16384, 16383);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetPos (CLIP (-16384, lValue, 16383));
+ }
+ else {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetRange (-127, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetPos (CLIP (-127, lValue, 127));
+ }
+ }
+ else if (pPercentUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetRange (0, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVALUE_AMOUNTSP))->SetPos (CLIP (0, lValue, 1000));
+ }
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditValueDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITVALUE_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITVALUE_ABSOLUTEUNIT, m_nUnit);
+ DDX_Check (pDX, IDC_EDITVALUE_TARGETKEYAFTER, m_nTargetKeyAfter);
+ DDX_Check (pDX, IDC_EDITVALUE_TARGETCONTROLCHANGE, m_nTargetControlChange);
+ DDX_Check (pDX, IDC_EDITVALUE_TARGETCHANNELAFTER, m_nTargetChannelAfter);
+ DDX_Check (pDX, IDC_EDITVALUE_TARGETPITCHBEND, m_nTargetPitchBend);
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_RELATIVEUNIT);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_PERCENTUNIT);
+ CButton* pRandomUpDownUnitButton = (CButton*)GetDlgItem (IDC_EDITVALUE_RANDOMUPDOWNUNIT);
+ CButton* pTargetPitchBendButton = (CButton*)GetDlgItem (IDC_EDITVALUE_TARGETPITCHBEND);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ if (pTargetPitchBendButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -8192, 8191);
+ }
+ else {
+ DDV_MinMaxInt (pDX, m_nAmount, 0, 127);
+ }
+ }
+ else if (pRelativeUnitButton->GetCheck () || pRandomUpDownUnitButton->GetCheck ()) {
+ if (pTargetPitchBendButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -16384, 16383);
+ }
+ else {
+ DDV_MinMaxInt (pDX, m_nAmount, -127, 127);
+ }
+ }
+ else if (pPercentUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 0, 1000);
+ }
+}
+
+// ダイアログ初期化時
+BOOL CEditValueDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditValueDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITVALUE_ABSOLUTEUNIT, IDC_EDITVALUE_RANDOMUPDOWNUNIT, OnChangeUnit)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITVALUE_TARGETKEYAFTER, IDC_EDITVALUE_TARGETPITCHBEND, OnChangeTarget)
+END_MESSAGE_MAP ()
+
+// 単位が変更された
+void CEditValueDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+// 対象が変更された
+void CEditValueDlg::OnChangeTarget (UINT nID) {
+ SetAmountRange ();
+}
diff --git a/src/EditValueDlg.h b/src/EditValueDlg.h
new file mode 100644
index 0000000..8cb2742
--- /dev/null
+++ b/src/EditValueDlg.h
@@ -0,0 +1,65 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 値の変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITVALUEDLG_H_
+#define _EDITVALUEDLG_H_
+
+class CEditValueDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // 値の変更量
+ int m_nUnit; // 単位(0=増減,1=パーセント)
+ int m_nTargetKeyAfter; // キーアフタータッチを対象とする(0/1)
+ int m_nTargetControlChange; // コントロールチェンジを対象とする(0/1)
+ int m_nTargetChannelAfter; // チャンネルアフタータッチを対象とする(0/1)
+ int m_nTargetPitchBend; // ピッチベンドを対象とする(0/1)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditValueDlg (); // コンストラクタ
+ enum {IDD = IDD_EDITVALUE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetAmountRange (); // 値の変更量の有効範囲を設定する
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ afx_msg void OnChangeTarget (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EditVelocityDlg.cpp b/src/EditVelocityDlg.cpp
new file mode 100644
index 0000000..069c557
--- /dev/null
+++ b/src/EditVelocityDlg.cpp
@@ -0,0 +1,117 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ベロシティの変更ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "EditVelocityDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEditVelocityDlg::CEditVelocityDlg () : CDialog (CEditVelocityDlg::IDD) {
+ m_nAmount = 0;
+ m_nUnit = 0;
+ m_nTargetNoteOn = 0;
+ m_nTargetNoteOff = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+BOOL CEditVelocityDlg::SetAmountRange () {
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_RELATIVEUNIT);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_PERCENTUNIT);
+ CButton* pRandomUpDownUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_RANDOMUPDOWNUNIT);
+ CString strValue;
+ GetDlgItem (IDC_EDITVELOCITY_AMOUNT)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVELOCITY_AMOUNTSP))->SetRange (1, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVELOCITY_AMOUNTSP))->SetPos (CLIP (1, lValue, 127));
+ }
+ else if (pRelativeUnitButton->GetCheck () || pRandomUpDownUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVELOCITY_AMOUNTSP))->SetRange (-127, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVELOCITY_AMOUNTSP))->SetPos (CLIP (-127, lValue, 127));
+ }
+ else if (pPercentUnitButton->GetCheck ()) {
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVELOCITY_AMOUNTSP))->SetRange (0, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EDITVELOCITY_AMOUNTSP))->SetPos (CLIP (0, lValue, 1000));
+ }
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEditVelocityDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EDITVELOCITY_AMOUNT, m_nAmount);
+ DDX_Radio (pDX, IDC_EDITVELOCITY_ABSOLUTEUNIT, m_nUnit);
+ DDX_Check (pDX, IDC_EDITVELOCITY_TARGETNOTEON, m_nTargetNoteOn);
+ DDX_Check (pDX, IDC_EDITVELOCITY_TARGETNOTEOFF, m_nTargetNoteOff);
+ CButton* pAbsoluteUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_ABSOLUTEUNIT);
+ CButton* pRelativeUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_RELATIVEUNIT);
+ CButton* pPercentUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_PERCENTUNIT);
+ CButton* pRandomUpDownUnitButton = (CButton*)GetDlgItem (IDC_EDITVELOCITY_RANDOMUPDOWNUNIT);
+ if (pAbsoluteUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 1, 127);
+ }
+ else if (pRelativeUnitButton->GetCheck () || pRandomUpDownUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, -127, 127);
+ }
+ else if (pPercentUnitButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nAmount, 0, 1000);
+ }
+}
+
+// ダイアログ初期化時
+BOOL CEditVelocityDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetAmountRange ();
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CEditVelocityDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_EDITVELOCITY_ABSOLUTEUNIT, IDC_EDITVELOCITY_RANDOMUPDOWNUNIT, OnChangeUnit)
+END_MESSAGE_MAP ()
+
+// 単位が変更された
+void CEditVelocityDlg::OnChangeUnit (UINT nID) {
+ SetAmountRange ();
+}
+
+
diff --git a/src/EditVelocityDlg.h b/src/EditVelocityDlg.h
new file mode 100644
index 0000000..8bc901f
--- /dev/null
+++ b/src/EditVelocityDlg.h
@@ -0,0 +1,61 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ベロシティの変更ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EDITVELOCITYDLG_H_
+#define _EDITVELOCITYDLG_H_
+
+class CEditVelocityDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nAmount; // ベロシティの変更量
+ int m_nUnit; // 単位(0=増減,1=パーセント)
+ int m_nTargetNoteOn; // ノートオンを対象にする(0/1)
+ int m_nTargetNoteOff; // ノートオフを対象にする(0/1)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEditVelocityDlg(); // コンストラクタ
+ enum {IDD = IDD_EDITVELOCITY};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ BOOL SetAmountRange ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログ初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeUnit (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EventKindListBox.cpp b/src/EventKindListBox.cpp
new file mode 100644
index 0000000..f7b0b4b
--- /dev/null
+++ b/src/EventKindListBox.cpp
@@ -0,0 +1,135 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントの種類リストボックスクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "resource.h"
+#include "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuDoc.h"
+#include "EventKindListBox.h"
+
+// TSIZEOFマクロ //20120211追加
+#ifndef TSIZEOF
+#define TSIZEOF(STR) (sizeof(STR)/sizeof(TCHAR))
+#endif
+#ifndef TCSLEN
+#ifdef UNICODE
+#define TCSLEN(STRING) wcslen(STRING)
+#else
+#define TCSLEN(STRING) strlen(STRING)
+#endif
+#endif
+#ifndef TCSNCPY
+#ifdef UNICODE
+#define TCSNCPY(STRING1,STRING2,N) wcsncpy(STRING1,STRING2,N)
+#else
+#define TCSNCPY(STRING1,STRING2,N) strncpy(STRING1,STRING2,N)
+#endif
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CEventKindListBox, CCheckListBox)
+
+BEGIN_MESSAGE_MAP (CEventKindListBox, CCheckListBox)
+ ON_WM_RBUTTONDOWN ()
+END_MESSAGE_MAP ()
+
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventKindListBox::CEventKindListBox () {
+ m_pDocument = NULL;
+ m_lMenuID = 0;
+ m_lLastRButtonDownIndex = 0;
+ CCheckListBox::CCheckListBox ();
+}
+
+// コンストラクタ
+CEventKindListBox::CEventKindListBox (CDocument* pDocument, long lMenuID) {
+ m_pDocument = pDocument;
+ m_lMenuID = lMenuID;
+ m_lLastRButtonDownIndex = 0;
+ CCheckListBox::CCheckListBox ();
+}
+
+// デストラクタ
+CEventKindListBox::~CEventKindListBox () {
+ CCheckListBox::~CCheckListBox ();
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+CSekaijuDoc* CEventKindListBox::GetDocument () {
+ return (CSekaijuDoc*)m_pDocument;
+}
+
+long CEventKindListBox::GetLastRButtonDownIndex () {
+ return m_lLastRButtonDownIndex;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// マウス右ボタン押された時
+void CEventKindListBox::OnRButtonDown (UINT nFlags, CPoint point) {
+ this->SetFocus ();
+ if (m_lMenuID == 0) {
+ return;
+ }
+ BOOL bOutside;
+ long lIndex = this->ItemFromPoint (point, bOutside);
+ if (bOutside) {
+ return;
+ }
+ if (lIndex < 0 || lIndex >= GetCount ()) {
+ return;
+ }
+ m_lLastRButtonDownIndex = lIndex;
+ // ポップアップメニューの表示
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (m_lMenuID));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, GetParentFrame ());
+}
+
+
diff --git a/src/EventKindListBox.h b/src/EventKindListBox.h
new file mode 100644
index 0000000..ec5f37f
--- /dev/null
+++ b/src/EventKindListBox.h
@@ -0,0 +1,64 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントの種類リストボックスクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTKINDLISTBOX_H_
+#define _EVENTKINDLISTBOX_H_
+
+class CEventKindListBox : public CCheckListBox {
+ DECLARE_DYNCREATE (CEventKindListBox)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CDocument* m_pDocument; // ドキュメントへのポインタ
+ long m_lMenuID; // 右クリックしたときに現れるメニューのID
+ long m_lLastRButtonDownIndex; // 最後に右クリックした項目番号(0〜)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEventKindListBox (); // コンストラクタ
+ CEventKindListBox (CDocument* pDocument, long lMenuID); // コンストラクタ
+ virtual ~CEventKindListBox (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ void CEventKindListBox::SetDocument (CDocument* pDocument);
+ CSekaijuDoc* GetDocument ();
+ long GetLastRButtonDownIndex ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EventListFrame.cpp b/src/EventListFrame.cpp
new file mode 100644
index 0000000..46045c1
--- /dev/null
+++ b/src/EventListFrame.cpp
@@ -0,0 +1,3301 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストフレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "resource.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "SekaijuFileDlg.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "EventListFrame.h"
+#include "EventListPrintView.h"
+#include "EventListScaleView.h"
+#include "EventListIndexScaleView.h"
+#include "EventListPropertyScaleView.h"
+#include "EventListIndexPropertyView.h"
+#include "TrackListBox.h"
+#include "EventKindListBox.h"
+#include "common.h"
+
+
+// アロケーションの監視
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// 子ウィンドウのサイズ
+#define EVENTLISTFRAME_SCALEHEIGHT 16
+#define EVENTLISTFRAME_SCALEWIDTH 64
+#define EVENTLISTFRAME_PROPERTYWIDTH 600
+#define EVENTLISTFRAME_TRACKLISTWIDTH 200
+#define EVENTLISTFRAME_INDEXHEIGHT 256
+#define EVENTLISTFRAME_SCROLLBARHEIGHT 16
+#define EVENTLISTFRAME_SCROLLBARWIDTH 16
+#define EVENTLISTFRAME_BORDERWIDTH 2
+#define EVENTLISTFRAME_BORDERHEIGHT 2
+#define EVENTLISTFRAME_SPLITTERWIDTH 4
+#define EVENTLISTFRAME_SPLITTERHEIGHT 4
+#define EVENTLISTFRAME_TRACKLISTHEIGHT 128
+#define EVENTLISTFRAME_EVENTKINDLISTHEIGHT 128
+
+// 子ウィンドウIDを定義
+#define EVENTLISTFRAME_DUMMYVIEW (AFX_IDW_PANE_FIRST + 0)
+#define EVENTLISTFRAME_PRINTVIEW (AFX_IDW_PANE_FIRST + 31)
+#define EVENTLISTFRAME_SCALEVIEW (AFX_IDW_PANE_FIRST + 32)
+#define EVENTLISTFRAME_PROPERTYSCALEVIEW (AFX_IDW_PANE_FIRST + 33)
+#define EVENTLISTFRAME_INDEXSCALEVIEW (AFX_IDW_PANE_FIRST + 34)
+#define EVENTLISTFRAME_INDEXPROPERTYVIEW (AFX_IDW_PANE_FIRST + 35)
+#define EVENTLISTFRAME_ROWSCROLL (AFX_IDW_PANE_FIRST + 48)
+#define EVENTLISTFRAME_COLUMNSCROLL (AFX_IDW_PANE_FIRST + 49)
+#define EVENTLISTFRAME_SIZEBOX (AFX_IDW_PANE_FIRST + 51)
+#define EVENTLISTFRAME_ROWZOOMDOWN (AFX_IDW_PANE_FIRST + 52)
+#define EVENTLISTFRAME_ROWZOOMUP (AFX_IDW_PANE_FIRST + 53)
+#define EVENTLISTFRAME_COLUMNZOOMDOWN (AFX_IDW_PANE_FIRST + 54)
+#define EVENTLISTFRAME_COLUMNZOOMUP (AFX_IDW_PANE_FIRST + 55)
+#define EVENTLISTFRAME_TRACKLIST (AFX_IDW_PANE_FIRST + 61)
+#define EVENTLISTFRAME_EVENTKINDLIST (AFX_IDW_PANE_FIRST + 62)
+
+//
+// イベントリストフレームのクライアント領域に配置されたオブジェクト
+//                                  
+// m_lVSc ┃
+// ┃←m_lScale→│← m_lPropertyWidth →│←rollBa→★
+// Width     rWidth ┃   
+//  ─
+// ↑ ┏───────────────────────────────────┓
+// m_lToolBar1Height ┃CSekaijuToolBar ┃
+// ↓ ┃m_wndToolBar1 ┃
+// ━ ┣━━━━━━┯━━━━━━━━━━━━━━┯━┳━━━━━━━━━┯━┫
+// ↑ ┃CView* │CView* │↑┃ │↑┃
+// m_lScaleHeight ┃m_pScaleView│m_pPrepertyScaleView   ├─┨CCheckListBox ├─┨
+// ↓ ┠──────┼──────────────┤ ┃m_wndTrackList │□┃
+// ─ ┃CView* │CView*       │□★(with ScrollBar) ├─┨
+// ↑ ┃m_pIndexScal│m_pPrepertyIndexView   │ ┃ │↓┃
+// ┃eView │              │ ┠─┬─────┬─┼─┨
+// ┃    │  │ ┃←│□ │→│ ┃
+// m_lIndexHeight ┃    │              ├─╂━┷━━━★━┷━┿━┫
+// ┃    │  CScrollBar m_wndRowScroll│↓┃ │↑┃
+// ┃    │              ├─┨CCheckListBox ├─┨
+// ┃    │ CButton m_wndRowZoomDwon│−★m_wndEventKindList│□┃
+// ↓ ┃    │              ├─┨(with ScrollBar) ├─┨
+// ─ ┃    │   CButton m_wndRowZoomUp│+┃ │↓┃
+// ↑ ┠─┬────┴────────┬─┬─┬─┼─╂─┬─────┬─┼─┨
+//m_lHScrollBarHeight┃←│   □         │→│−│+│⊿┃←│□ │→│ ┃
+// ↓ ┗━┷━━━━━━━━━━━━━┷━┷━┷━┷━┻━┷━━━━━┷━┷━┛
+// ━ CScrollBar CButton CButton
+// m_wndColumn m_wndCo m_wndCo
+// Scroll lumnZoo lumnZoo
+// mDown mUp
+//
+// (あ)———:単純な境界(0px)。
+// (い)━━━:太く立体的な境界線。BORDERWIDTH(2px)又はBORDERHEIGHT(2px)で示す幅を占領
+// (う)━★━:スプリッター境界線。(い)*2+SPRITTERWIDTH(4px)又はSPRITTERHEIGHT(4px)で示す幅を占領。
+
+
+
+
+// 関数マクロ
+#ifndef CLIP
+#define CLIP(A,B,C) ((A)>(B)?(A):((B)>(C)?(C):(B)))
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE(CEventListFrame, CChildFrame)
+
+BEGIN_MESSAGE_MAP(CEventListFrame, CChildFrame)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_SIZE ()
+ ON_WM_TIMER ()
+ ON_WM_ERASEBKGND ()
+ ON_WM_MDIACTIVATE ()
+ ON_WM_CLOSE ()
+ ON_WM_PAINT ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_HSCROLL ()
+ ON_WM_VSCROLL ()
+ ON_BN_CLICKED (EVENTLISTFRAME_COLUMNZOOMDOWN, OnColumnZoomDown)
+ ON_BN_CLICKED (EVENTLISTFRAME_COLUMNZOOMUP, OnColumnZoomUp)
+ ON_BN_CLICKED (EVENTLISTFRAME_ROWZOOMDOWN, OnRowZoomDown)
+ ON_BN_CLICKED (EVENTLISTFRAME_ROWZOOMUP, OnRowZoomUp)
+ ON_COMMAND (ID_EVENTLIST_INSERTEVENT, OnEventListInsertEvent)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_INSERTEVENT, OnUpdateEventListInsertEventUI)
+ ON_COMMAND (ID_EVENTLIST_DUPLICATEEVENT, OnEventListDuplicateEvent)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_DUPLICATEEVENT, OnUpdateEventListDuplicateEventUI)
+ ON_COMMAND (ID_EVENTLIST_DELETEEVENT, OnEventListDeleteEvent)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_DELETEEVENT, OnUpdateEventListDeleteEventUI)
+ ON_COMMAND (ID_EVENTLIST_ONLYCURTRACK, OnEventListOnlyCurTrack)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_ONLYCURTRACK, OnUpdateEventListOnlyCurTrackUI)
+ ON_COMMAND (ID_EVENTLIST_SHOWALLTRACK, OnEventListShowAllTrack)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_SHOWALLTRACK, OnUpdateEventListShowAllTrackUI)
+ ON_COMMAND (ID_EVENTLIST_ONLYCUREVENTKIND, OnEventListOnlyCurEventKind)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_ONLYCUREVENTKIND, OnUpdateEventListOnlyCurEventKindUI)
+ ON_COMMAND (ID_EVENTLIST_SHOWALLEVENTKIND, OnEventListShowAllEventKind)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_SHOWALLEVENTKIND, OnUpdateEventListShowAllEventKindUI)
+ ON_COMMAND (ID_EVENTLIST_AUTOPAGEUPDATE, OnEventListAutoPageUpdate)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_AUTOPAGEUPDATE, OnUpdateEventListAutoPageUpdateUI)
+ ON_COMMAND (ID_EVENTLIST_SAVEAS, OnEventListSaveAs)
+ ON_UPDATE_COMMAND_UI (ID_EVENTLIST_SAVEAS, OnUpdateEventListSaveAsUI)
+
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEON, OnPopupTrackVisibleOn)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEON, OnUpdatePopupTrackVisibleOnUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEOFF, OnPopupTrackVisibleOff)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEOFF, OnUpdatePopupTrackVisibleOffUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEALL, OnPopupTrackVisibleAll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEALL, OnUpdatePopupTrackVisibleAllUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_EVENTKINDVISIBLEON, OnPopupEventKindVisibleOn)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_EVENTKINDVISIBLEON, OnUpdatePopupEventKindVisibleOnUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_EVENTKINDVISIBLEOFF, OnPopupEventKindVisibleOff)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_EVENTKINDVISIBLEOFF, OnUpdatePopupEventKindVisibleOffUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_EVENTKINDVISIBLEALL, OnPopupEventKindVisibleAll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_EVENTKINDVISIBLEALL, OnUpdatePopupEventKindVisibleAllUI) // 20100429追加
+
+ ON_CBN_SELENDOK (IDC_EVENTTRACKCOMBO, OnTrackComboSelEndOK)
+ ON_CLBN_CHKCHANGE (EVENTLISTFRAME_TRACKLIST, OnTrackListChkChange)
+ ON_LBN_SELCHANGE (EVENTLISTFRAME_TRACKLIST, OnTrackListSelChange)
+ ON_CBN_SELENDOK (IDC_EVENTKINDCOMBO, OnEventKindComboSelEndOK)
+ ON_CLBN_CHKCHANGE (EVENTLISTFRAME_EVENTKINDLIST, OnEventKindListChkChange)
+ ON_LBN_SELCHANGE (EVENTLISTFRAME_EVENTKINDLIST, OnEventKindListSelChange)
+END_MESSAGE_MAP()
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventListFrame::CEventListFrame () {
+ long i;
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_lIndexHeight = EVENTLISTFRAME_INDEXHEIGHT;
+ m_lScaleHeight = EVENTLISTFRAME_SCALEHEIGHT;
+ m_lScaleWidth = EVENTLISTFRAME_SCALEWIDTH;
+ m_lPropertyWidth = EVENTLISTFRAME_PROPERTYWIDTH;
+ m_lTrackListWidth = EVENTLISTFRAME_TRACKLISTWIDTH;
+ m_lTrackListHeight = EVENTLISTFRAME_TRACKLISTHEIGHT;
+ m_lEventKindListHeight = EVENTLISTFRAME_EVENTKINDLISTHEIGHT;
+ m_lHScrollBarHeight = ::GetSystemMetrics (SM_CYHSCROLL);
+ m_lVScrollBarWidth = ::GetSystemMetrics (SM_CXVSCROLL);
+ m_lRowZoom = pSekaijuApp->m_theEventListOption.m_lDefRowZoom;
+ m_lColumnZoom = pSekaijuApp->m_theEventListOption.m_lDefColumnZoom;
+ m_lRowScrollPos = 0;
+ m_lColumnScrollPos = 0;
+ // 列幅の定義
+ m_lColumnBaseWidth[0] = pSekaijuApp->m_theEventListOption.m_lDefTrackWidth;
+ m_lColumnBaseWidth[1] = pSekaijuApp->m_theEventListOption.m_lDefMillisecWidth;
+ m_lColumnBaseWidth[2] = pSekaijuApp->m_theEventListOption.m_lDefTimeWidth;
+ m_lColumnBaseWidth[3] = pSekaijuApp->m_theEventListOption.m_lDefKindWidth;
+ m_lColumnBaseWidth[4] = pSekaijuApp->m_theEventListOption.m_lDefChWidth;
+ m_lColumnBaseWidth[5] = pSekaijuApp->m_theEventListOption.m_lDefVal1Width;
+ m_lColumnBaseWidth[6] = pSekaijuApp->m_theEventListOption.m_lDefVal2Width;
+ m_lColumnBaseWidth[7] = pSekaijuApp->m_theEventListOption.m_lDefVal3Width;
+ // 列タイトルの定義
+ VERIFY (m_strColumnTitle[0].LoadString (IDS_TRACK));
+ VERIFY (m_strColumnTitle[1].LoadString (IDS_HOUR_MINUTE_SECOND_MILLISEC));
+ VERIFY (m_strColumnTitle[2].LoadString (IDS_MEASURE_BEAT_TICK));
+ VERIFY (m_strColumnTitle[3].LoadString (IDS_EVENT_KIND));
+ VERIFY (m_strColumnTitle[4].LoadString (IDS_CHANNEL));
+ VERIFY (m_strColumnTitle[5].LoadString (IDS_VALUE1));
+ VERIFY (m_strColumnTitle[6].LoadString (IDS_VALUE2));
+ VERIFY (m_strColumnTitle[7].LoadString (IDS_VALUE3));
+ // デフォルトフォントの作成
+ CString strDefaultFontName;
+ VERIFY (strDefaultFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (12, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strDefaultFontName);
+ m_bAutoPageUpdate = FALSE;
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ for (i = 0; i < MAXMIDITRACKNUM; i++) {
+ m_bTrackVisible[i] = TRUE;
+ }
+ m_bOnlyCurEventKind = FALSE;
+ m_bShowAllEventKind = FALSE;
+ for (i = 0; i < 256; i++) {
+ m_bEventKindVisible[i] = TRUE;
+ }
+
+}
+
+// デストラクタ
+CEventListFrame::~CEventListFrame () {
+ m_theFont.DeleteObject ();
+}
+
+
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// ドキュメントの取得
+CSekaijuDoc* CEventListFrame::GetDocument () {
+ ASSERT (m_pDummyView);
+ return (CSekaijuDoc*)m_pDummyView->GetDocument ();
+}
+
+// ウィンドウのフォントを取得
+CFont* CEventListFrame::GetParentFont () {
+ return &(m_theFont);
+}
+
+// 最も上に表示されている行を取得
+long CEventListFrame::GetVisibleTopRow () {
+ return m_lRowScrollPos / m_lRowZoom;
+}
+
+// 最も下に表示されている行を取得
+long CEventListFrame::GetVisibleBottomRow () {
+ CRect rcClient;
+ m_pIndexScaleView->GetClientRect (&rcClient);
+ return (m_lRowScrollPos + rcClient.Height ()) / m_lRowZoom;
+}
+
+// 列方向のズーム倍率取得
+long CEventListFrame::GetColumnZoom () {
+ return m_lColumnZoom;
+}
+
+// 行方向のズーム倍率取得
+long CEventListFrame::GetRowZoom () {
+ return m_lRowZoom;
+}
+
+// 指定した列の基本幅を取得
+long CEventListFrame::GetColumnBaseWidth (long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ return m_lColumnBaseWidth[lColumn];
+}
+
+// 指定した列の基本幅を設定
+long CEventListFrame::SetColumnBaseWidth (long lColumn, long lBaseWidth) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ m_lColumnBaseWidth[lColumn] = lBaseWidth;
+ return 1;
+}
+
+// 指定した列のタイトルを取得
+CString CEventListFrame::GetColumnTitle (long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ return m_strColumnTitle[lColumn];
+}
+
+// 指定した列のタイトルを取得
+long CEventListFrame::SetColumnTitle (long lColumn, const TCHAR* pszColumnTitle) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ m_strColumnTitle[lColumn] = pszColumnTitle;
+ return 1;
+}
+
+
+// 指定の列の左座標を取得
+long CEventListFrame::GetColumnLeft (long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ long lSum = 0;
+ for (long j = 0; j < lColumn; j++) {
+ lSum += m_lColumnBaseWidth[j];
+ }
+ return lSum * m_lColumnZoom;
+}
+
+// 指定の列の幅を取得
+long CEventListFrame::GetColumnWidth (long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ return m_lColumnBaseWidth[lColumn] * m_lColumnZoom;
+}
+
+// y座標をインデックスに変換
+long CEventListFrame::YtoRow (long y) {
+ return y / m_lRowZoom;
+}
+
+// インデックスをy座標に変換
+long CEventListFrame::RowtoY (long lRow) {
+ return m_lRowZoom * lRow;
+}
+
+// x座標からプロパティを取得
+long CEventListFrame::XtoColumn (long x) {
+ long lSum = 0;
+ long lNextSum = 0;
+ for (long j = 0; j < 8; j++) {
+ lNextSum += m_lColumnBaseWidth[j] * m_lColumnZoom;
+ if (lSum <= x && x < lNextSum) {
+ return j;
+ }
+ lSum = lNextSum;
+ }
+ return -1;
+}
+
+// プロパティをx座標に変換
+long CEventListFrame::ColumntoX (long lColumn) {
+ return GetColumnLeft (lColumn);
+}
+
+// 列方向のスクロールポジションを取得
+long CEventListFrame::GetColumnScrollPos () {
+ return m_lColumnScrollPos;
+}
+
+// 行方向のスクロールポジションを取得
+long CEventListFrame::GetRowScrollPos () {
+ return m_lRowScrollPos;
+}
+
+// 列方向スクロールポジションの設定
+long CEventListFrame::SetColumnScrollPos (long lColumnScrollPos) {
+ long lOldColumnScrollPos = m_lColumnScrollPos;
+ m_wndColumnScroll.SetScrollPos (lColumnScrollPos);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+ long lDeltaColumnScrollPos = m_lColumnScrollPos - lOldColumnScrollPos;
+ m_pPropertyScaleView->ScrollWindow (-lDeltaColumnScrollPos, 0);
+ m_pIndexPropertyView->ScrollWindow (-lDeltaColumnScrollPos, 0);
+ m_pPropertyScaleView->UpdateWindow ();
+ m_pIndexPropertyView->UpdateWindow ();
+ return m_lColumnScrollPos;
+}
+
+// 行方向スクロールポジションの設定
+long CEventListFrame::SetRowScrollPos (long lRowScrollPos) {
+ long lOldRowScrollPos = m_lRowScrollPos;
+ m_wndRowScroll.SetScrollPos (lRowScrollPos);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+ long lDeltaRowScrollPos = m_lRowScrollPos - lOldRowScrollPos;
+ m_pIndexScaleView->ScrollWindow (0, -lDeltaRowScrollPos);
+ m_pIndexPropertyView->ScrollWindow (0, -lDeltaRowScrollPos);
+ m_pIndexScaleView->UpdateWindow ();
+ m_pIndexPropertyView->UpdateWindow ();
+ return m_lRowScrollPos;
+}
+
+// 可視のMIDIイベント数を取得
+long CEventListFrame::GetVisibleEventCount () {
+ return m_theVisibleEventArray.GetSize ();
+}
+
+// 可視のMIDIイベントを取得
+MIDIEvent* CEventListFrame::GetVisibleEvent (long lIndex) {
+ if (0 <= lIndex && lIndex < m_theVisibleEventArray.GetSize ()) {
+ return (MIDIEvent*)(m_theVisibleEventArray.GetAt (lIndex));
+ }
+ return NULL;
+}
+
+// スプリッターキャプターの描画
+void CEventListFrame::DrawSplitterCaptor (CDC* pDC, CPoint pt) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CPen pen;
+ CPen* pOldPen;
+ pen.CreatePen (PS_SOLID, 4, ::GetSysColor(COLOR_BTNSHADOW));
+ pDC->SetROP2 (R2_XORPEN);
+ pOldPen = pDC->SelectObject (&pen);
+ if (m_bSplitterMovingH) {
+ pDC->MoveTo (0, pt.y);
+ pDC->LineTo (rcClient.Width (), pt.y);
+ }
+ if (m_bSplitterMovingV) {
+ pDC->MoveTo (pt.x, 0);
+ pDC->LineTo (pt.x, rcClient.Height ());
+ }
+ pDC->SelectObject (pOldPen);
+}
+
+
+
+/* "0シーケンス番号",
+ "1テキストイベント",
+ "2著作権",
+ "3シーケンス名/トラック名",
+ "4インストゥルメント名",
+ "5歌詞",
+ "6マーカー",
+ "7キューポイント",
+ "8プログラム名",
+ "9デバイス名",
+ "10チャンネルプリフィックス",
+ "11ポートプリフィックス",
+ "12エンドオブトラック",
+ "13テンポ設定",
+ "14SMPTEオフセット",
+ "15拍子記号",
+ "16調性記号",
+ "17シーケンサ独自のイベント",
+ "18ノートオフ",
+ "19ノートオン",
+ "20キーアフタータッチ",
+ "21コントローラー",
+ "22プログラムチェンジ",
+ "23チャンネルアフタータッチ",
+ "24ピッチベンド",
+ "25システムエクスクルーシヴ",
+ "26不明な種類のイベント"};
+*/
+
+// 可視のイベント配列の作成
+BOOL CEventListFrame::MakeVisibleEventArray () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pMIDIData->m_pFirstTrack;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ // 旧選択イベントをpOldMIDIEventに保持しておく
+ long lOldVisibleEventCount = m_theVisibleEventArray.GetSize ();
+ long lOldRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ MIDIEvent* pOldMIDIEvent = NULL;
+ if (0 <= lOldRow && lOldRow < lOldVisibleEventCount) {
+ pOldMIDIEvent = (MIDIEvent*)m_theVisibleEventArray.GetAt (lOldRow);
+ }
+
+ // 現在配列の初期化
+ m_theVisibleEventArray.RemoveAll ();
+ MIDIEvent* pTempEvent[MAXMIDITRACKNUM];
+ long lTime = 0;
+ long lMinimumTime = 0;
+ long lMinimumTrackIndex = 0;
+ long lTrackNum = 0;
+ long i = 0;
+ // 各トラック用の一時イベント保持スペースを初期化
+ forEachTrack (pMIDIData, pMIDITrack) {
+ pTempEvent[i] = MIDITrack_GetFirstEvent (pMIDITrack);
+ i++;
+ if (i >= MAXMIDITRACKNUM) break;
+ }
+ // 各トラックのイベントをタイム順に配列に登録する
+ while (1) {
+ lMinimumTime = 0x7FFFFFFF;
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (IsTrackVisible (i)) {
+ if (pTempEvent[i] != NULL) {
+ lTime = pTempEvent[i]->m_lTime;
+ if (lTime < lMinimumTime) {
+ lMinimumTime = lTime;
+ lMinimumTrackIndex = i;
+ }
+ }
+ }
+ i++;
+ if (i >= MAXMIDITRACKNUM) break;
+ }
+ if (lMinimumTrackIndex < MAXMIDITRACKNUM && lMinimumTime != 0x7FFFFFFF) {
+ for (pMIDIEvent = pTempEvent[lMinimumTrackIndex];
+ pMIDIEvent; pMIDIEvent = pMIDIEvent->m_pNextEvent) {
+ if (pMIDIEvent->m_lTime == lMinimumTime) {
+ long lEventKind = MIDIEvent_GetKind (pMIDIEvent);
+ if (MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ lEventKind &= 0x0F;
+ lEventKind |= 0x80;
+ }
+ long lListIndex = EventKindtoListIndex (lEventKind);
+ ASSERT (0 <= lListIndex && lListIndex <= 0xFF);
+ if (IsEventKindVisible (lListIndex)) {
+ m_theVisibleEventArray.Add (pMIDIEvent);
+ }
+ }
+ else {
+ break;
+ }
+ }
+ pTempEvent[lMinimumTrackIndex] = pMIDIEvent;
+ }
+ else {
+ break;
+ }
+ }
+ // 行スクロールバーの再調整
+ RecalcRowScrollInfo ();
+
+ // 旧イベントにフォーカスを合わせる
+ long lNewCount = m_theVisibleEventArray.GetSize ();
+ long lNewRow = CLIP (0, lOldRow, lNewCount - 1);
+ if (lNewRow < 0) {
+ lNewRow = 0; // lNewCount == 0の場合に備える
+ }
+ if (pOldMIDIEvent) {
+ // 一致するイベントが見つかった場合、そのイベントにフォーカスを合わせる
+ for (i = 0; i < lNewCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pOldMIDIEvent) {
+ break;
+ }
+ }
+ if (i < lNewCount) {
+ lNewRow = i;
+ }
+ // 一致するイベントがない場合、時刻が同じかその次のイベントにフォーカスを合わせる
+ // 一致するイベントが無い場合、m_lCurRowはそのままの値とする
+ //else {
+ //for (i = 0; i < lNewCount; i++) {
+ // MIDIEvent* pTempEvent = (MIDIEvent*)m_theVisibleEventArray.GetAt (i);
+ // if (MIDIEvent_GetTime (pTempEvent) >= MIDIEvent_GetTime (pOldMIDIEvent)) {
+ // break;
+ // }
+ //}
+ //lNewRow = i;
+ //lNewRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ //}
+ }
+ if (((CEventListIndexPropertyView*)m_pIndexPropertyView)->IsTextEditing ()) {
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->EndTextEditingCancel ();
+ }
+ if (((CEventListIndexPropertyView*)m_pIndexPropertyView)->IsListSelecting ()) {
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->EndListSelectingCancel ();
+ }
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow = lNewRow;
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lNewRow, lCurColumn);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (lNewRow, lCurColumn);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (lNewRow, lCurColumn);
+ return TRUE;
+}
+
+BOOL CEventListFrame::ReplaceVisibleEvent (MIDIEvent* pOldEvent, MIDIEvent* pNewEvent) {
+ long lCount = 0;
+ long lVisibleEventCount = m_theVisibleEventArray.GetSize ();
+ pOldEvent = MIDIEvent_GetFirstCombinedEvent (pOldEvent);
+ pNewEvent = MIDIEvent_GetFirstCombinedEvent (pNewEvent);
+ while (pOldEvent && pNewEvent) {
+ long i = 0;
+ for (i = 0; i < lVisibleEventCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pOldEvent) {
+ m_theVisibleEventArray.SetAt (i, pNewEvent);
+ lCount++;
+ }
+ }
+ pOldEvent = pOldEvent->m_pNextCombinedEvent;
+ pNewEvent = pNewEvent->m_pNextCombinedEvent;
+ }
+ return lCount;
+}
+
+
+// 現在のトラックのインデックスを取得
+long CEventListFrame::GetCurTrackIndex () {
+ return m_pTrackListBox->GetCurSel ();
+}
+
+// 現在のグラフの種類を取得
+long CEventListFrame::GetCurEventKind () {
+ return m_pEventKindListBox->GetCurSel ();
+}
+
+// 現在のトラックのインデックスを設定
+BOOL CEventListFrame::SetCurTrackIndex (long lCurTrackIndex) {
+ ASSERT (0 <= lCurTrackIndex && lCurTrackIndex < MAXMIDITRACKNUM);
+ m_wndEventTrackCombo.SetCurSel (lCurTrackIndex);
+ m_pTrackListBox->SetCurSel (lCurTrackIndex);
+ if (m_bOnlyCurTrack) {
+ long lCount = m_pTrackListBox->GetCount ();
+ for (long i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, (i == lCurTrackIndex ? 1 : 0));
+ }
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+ }
+ return TRUE;
+}
+
+// 現在のグラフの種類を設定
+BOOL CEventListFrame::SetCurEventKind (long lCurEventKind) {
+ ASSERT (0 <= lCurEventKind && lCurEventKind < 256);
+ m_wndEventKindCombo.SetCurSel (lCurEventKind);
+ m_pEventKindListBox->SetCurSel (lCurEventKind);
+ if (m_bOnlyCurEventKind) {
+ long lCount = m_pEventKindListBox->GetCount ();
+ for (long i = 0; i < lCount; i++) {
+ m_pEventKindListBox->SetCheck (i, (i == lCurEventKind ? 1 : 0));
+ }
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+ }
+ return TRUE;
+}
+
+// 現在のチャンネルを設定
+BOOL CEventListFrame::SetCurChannel (long lCurChannel) {
+ ASSERT (-1 <= lCurChannel && lCurChannel < 16);
+ m_wndEventChannelCombo.SetCurSel (lCurChannel + 1);
+ return TRUE;
+}
+
+// 指定インデックスのトラックが表示状態か調べる
+BOOL CEventListFrame::IsTrackVisible (long lTrackIndex) {
+ // (1)現在のトラックのみ表示がONのときは、現在のトラックのみがVisible、他はUnVisible。
+ // (2)すべてのトラックを表示がONのときは、全てのトラックがVisible。
+ // (3)その他の場合(通常時)は、m_bTrackVisible[MAXMIDITRACKNUM]の値に従う。
+ ASSERT (0 <= lTrackIndex && lTrackIndex < MAXMIDITRACKNUM);
+ if (m_bOnlyCurTrack == TRUE &&
+ GetCurTrackIndex () == lTrackIndex ||
+ m_bShowAllTrack == TRUE ||
+ m_bShowAllTrack == FALSE &&
+ m_bOnlyCurTrack == FALSE &&
+ m_bTrackVisible[lTrackIndex] == TRUE) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// 指定インデックスのトラックを表示状態にする
+BOOL CEventListFrame::SetTrackVisible (long lTrackIndex) {
+ // (1)現在のトラックのみ表示がONのときは、現在のトラックを指定トラックに変更する
+ // (2)すべてのトラックを表示がONのときは、何もしない。
+ // (3)その他の場合(通常時)は、m_bTrackVisible[lTrackIndex]をチェック・可視化する。
+ ASSERT (0 <= lTrackIndex && lTrackIndex < MAXMIDITRACKNUM);
+ if (m_bOnlyCurTrack == TRUE) {
+ m_wndEventTrackCombo.SetCurSel (lTrackIndex);
+ m_pTrackListBox->SetCurSel (lTrackIndex);
+ }
+ else if (m_bShowAllTrack == TRUE) {
+ ;
+ }
+ else {
+ m_pTrackListBox->SetCheck (lTrackIndex, TRUE);
+ m_bTrackVisible[lTrackIndex] = TRUE;
+ }
+ return TRUE;
+}
+
+// 指定種類のイベントが表示状態か調べる
+BOOL CEventListFrame::IsEventKindVisible (long lEventKind) {
+ // (1)現在のイベント種類のみ表示がONのときは、現在のグラフのみがVisible、他はUnVisible。
+ // (2)すべてのイベント種類を表示がONのときは、全てのグラフがVisible。
+ // (3)その他の場合(通常時)は、m_bEventKindVisible[MAXMIDITRACKNUM]の値に従う。
+ ASSERT (0 <= lEventKind && lEventKind < 128);
+ if (m_bOnlyCurEventKind == TRUE &&
+ GetCurEventKind () == lEventKind ||
+ m_bShowAllEventKind == TRUE ||
+ m_bShowAllEventKind == FALSE &&
+ m_bOnlyCurEventKind == FALSE &&
+ m_bEventKindVisible[lEventKind] == TRUE) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// 指定種類のイベントを表示状態にする
+BOOL CEventListFrame::SetEventKindVisible (long lEventKind) {
+ // (1)現在のイベント種類のみ表示がONのときは、現在のイベントの種類を変更する
+ // (2)すべてのイベント種類を表示がONのときは、何もしない。
+ // (3)その他の場合(通常時)は、m_bEventKindVisible[lEventKind]をチェック・可視化する。
+ ASSERT (0 <= lEventKind && lEventKind < m_pEventKindListBox->GetCount ());
+ if (m_bOnlyCurEventKind == TRUE) {
+ m_wndEventKindCombo.SetCurSel (lEventKind);
+ m_pEventKindListBox->SetCurSel (lEventKind);
+ }
+ else if (m_bShowAllEventKind == TRUE) {
+ ;
+ }
+ else {
+ m_pEventKindListBox->SetCheck (lEventKind, TRUE);
+ m_bEventKindVisible[lEventKind] = TRUE;
+ }
+ return TRUE;
+}
+
+// トラックコンボボックスの充満
+BOOL CEventListFrame::UpdateTrackCombo () {
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(m_pDummyView->GetDocument ());
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ //pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+
+ // 旧状態の保持
+ static MIDITrack* pOldMIDITrack[MAXMIDITRACKNUM];
+ BOOL bOldTrackVisible[MAXMIDITRACKNUM];
+ memcpy (bOldTrackVisible, m_bTrackVisible, sizeof (BOOL) * MAXMIDITRACKNUM);
+ long lOldCurSel = m_wndEventTrackCombo.GetCurSel ();
+ long lOldCount = m_wndEventTrackCombo.GetCount ();
+ MIDITrack* pOldCurTrack = NULL;
+ if (0 <= lOldCurSel && lOldCurSel < __min (lOldCount, MAXMIDITRACKNUM)) {
+ pOldCurTrack = pOldMIDITrack[lOldCurSel];
+ }
+
+ // コンボの初期化
+ m_wndEventTrackCombo.RemoveAllItem ();
+
+ // コンボに項目追加
+ TCHAR szTrackName1[1024];
+ TCHAR szTrackName2[1024];
+ CString strText;
+ long i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ memset (szTrackName1, 0, sizeof (szTrackName1));
+ memset (szTrackName2, 0, sizeof (szTrackName2));
+ MIDITrack_GetName (pMIDITrack, szTrackName1, TSIZEOF (szTrackName1) - 1);
+ codestr2str (szTrackName1, TCSLEN (szTrackName1), szTrackName2, TSIZEOF (szTrackName2) - 1);
+ strText.Format (_T("%d-%s"), i + (bTrackZeroOrigin ? 0 : 1), szTrackName2);
+ long lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ m_wndEventTrackCombo.AddItem (strText, lForeColor, lBackColor);
+
+ // 現在のトラックである場合選択
+ if (pMIDITrack == pOldCurTrack) {
+ m_wndEventTrackCombo.SetCurSel (i);
+ }
+ i++;
+ }
+
+ // 現在選択しているものがない場合は強制選択
+ long lNewCount = m_wndEventTrackCombo.GetCount ();
+ long lNewCurSel = m_wndEventTrackCombo.GetCurSel ();
+ if (m_wndEventTrackCombo.GetCurSel () == CB_ERR) {
+ if (0 <= lOldCurSel && lOldCurSel < lNewCount) {
+ m_wndEventTrackCombo.SetCurSel (lOldCurSel);
+ }
+ else if (lNewCount >= 2) {
+ m_wndEventTrackCombo.SetCurSel (1);
+ }
+ else {
+ m_wndEventTrackCombo.SetCurSel (0);
+ }
+ lNewCurSel = m_wndEventTrackCombo.GetCurSel ();
+ }
+
+ // 次回のアップデート呼び出しに備えて現状を保持する。
+ i = 0;
+ memset (pOldMIDITrack, 0, sizeof (MIDITrack*) * MAXMIDITRACKNUM);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ pOldMIDITrack[i] = pMIDITrack;
+ i++;
+ }
+
+ //pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+// トラックリストボックスの充満
+BOOL CEventListFrame::UpdateTrackList () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ //pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ // 旧状態の保持
+ static MIDITrack* pOldMIDITrack[MAXMIDITRACKNUM];
+ BOOL bOldTrackVisible[MAXMIDITRACKNUM];
+ memcpy (bOldTrackVisible, m_bTrackVisible, sizeof (BOOL) * MAXMIDITRACKNUM);
+ long lOldCurSel = m_pTrackListBox->GetCurSel ();
+ long lOldCount = m_pTrackListBox->GetCount ();
+ MIDITrack* pOldCurTrack = NULL;
+ if (0 <= lOldCurSel && lOldCurSel < __min (lOldCount, MAXMIDITRACKNUM)) {
+ pOldCurTrack = pOldMIDITrack[lOldCurSel];
+ }
+
+ // リストの初期化
+ ((CTrackListBox*)m_pTrackListBox)->RemoveAllItem ();
+
+ // リストに項目を追加
+ long i = 0;
+ long j = 0;
+ TCHAR szTrackName1[1024];
+ TCHAR szTrackName2[1024];
+ CString strText;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ memset (szTrackName1, 0, sizeof (szTrackName1));
+ memset (szTrackName2, 0, sizeof (szTrackName2));
+ MIDITrack_GetName (pMIDITrack, szTrackName1, TSIZEOF (szTrackName1) - 1);
+ codestr2str (szTrackName1, TCSLEN (szTrackName1), szTrackName2, TSIZEOF (szTrackName2) - 1);
+ strText.Format (_T("%d-%s"), i + (bTrackZeroOrigin ? 0 : 1), szTrackName2);
+ long lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ ((CTrackListBox*)m_pTrackListBox)->AddItem (strText, lForeColor, lBackColor);
+ // チェック状態変数の更新
+ m_bTrackVisible[i] = 1;
+ for (j = 0; j < MAXMIDITRACKNUM; j++) {
+ if (pOldMIDITrack[j] == NULL) {
+ break;
+ }
+ if (pOldMIDITrack[j] == pMIDITrack) {
+ m_bTrackVisible[i] = bOldTrackVisible[j];
+ break;
+ }
+ }
+ // 現在のトラックである場合選択
+ if (pMIDITrack == pOldCurTrack) {
+ m_pTrackListBox->SetCurSel (i);
+ }
+ i++;
+ }
+
+ // 現在選択しているものがない場合は強制選択
+ long lNewCount = m_pTrackListBox->GetCount ();
+ long lNewCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_pTrackListBox->GetCurSel () == LB_ERR) {
+ if (0 <= lOldCurSel && lOldCurSel < lNewCount) {
+ m_pTrackListBox->SetCurSel (lOldCurSel);
+ }
+ else if (lNewCount >= 2) {
+ m_pTrackListBox->SetCurSel (1);
+ }
+ else {
+ m_pTrackListBox->SetCurSel (0);
+ }
+ lNewCurSel = m_pTrackListBox->GetCurSel ();
+ }
+
+ // チェックボックスの完全更新
+ if (m_bShowAllTrack) {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, 1);
+ }
+ }
+ else if (m_bOnlyCurTrack) {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, 0);
+ }
+ if (0 <= lNewCurSel && lNewCurSel < lNewCount) {
+ m_pTrackListBox->SetCheck (lNewCurSel, 1);
+ }
+ }
+ else {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, m_bTrackVisible[i]);
+ }
+ }
+
+ // 次回のアップデート呼び出しに備えて現状を保持する。
+ i = 0;
+ memset (pOldMIDITrack, 0, sizeof (MIDITrack*) * MAXMIDITRACKNUM);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ pOldMIDITrack[i] = pMIDITrack;
+ i++;
+ }
+
+ //pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+// イベントの種類からリストインデックスを取得
+long CEventListFrame::EventKindtoListIndex (long lEventKind) {
+ long lEventKindtoListIndex[256] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 10, 11, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 12,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 13, 27, 27, 14, 27, 27, 27, 15, 16, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 17,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 25, 27, 27, 27, 27, 27, 27, 26, 27, 27, 27, 27, 27, 27, 27, 27
+ };
+ ASSERT (0 <= lEventKind && lEventKind <= 0xFF);
+ if (0 <= lEventKind && lEventKind < 256) {
+ return lEventKindtoListIndex[lEventKind];
+ }
+ return -1;
+}
+
+// リストインデックスからイベントの種類を取得
+long CEventListFrame::ListIndextoEventKind (long lListIndex) {
+ ASSERT (0 <= lListIndex && lListIndex <= 0xFF);
+ for (long i = 0; i < 256; i++) {
+ if (EventKindtoListIndex (i) == lListIndex) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+// 行方向スクロールバー(縦)のデザイン設定
+void CEventListFrame::RecalcRowScrollInfo () {
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = (m_theVisibleEventArray.GetSize () + 4) * m_lRowZoom;
+ si.nPage = m_lIndexHeight;
+ m_wndRowScroll.SetScrollInfo (&si, TRUE);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+}
+
+// 列方向スクロールバー(横)のデザイン設定
+void CEventListFrame::RecalcColumnScrollInfo () {
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ long lSum = 0;
+ for (long j = 0; j < 8; j++) {
+ lSum += m_lColumnBaseWidth[j];
+ }
+ si.nMax = lSum * m_lColumnZoom;
+ si.nPage = m_lPropertyWidth;
+ m_wndColumnScroll.SetScrollInfo (&si, TRUE);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+}
+
+
+
+
+
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成直前の構造体設定
+BOOL CEventListFrame::PreCreateWindow (CREATESTRUCT& cs) {
+ return CWnd::PreCreateWindow (cs);
+}
+
+// ウィンドウタイトルの自動設定(CMDIChildWnd::OnUpdateFrameTitleのオーバーライド)
+void CEventListFrame::OnUpdateFrameTitle (BOOL bAddToTitle) {
+ // update our parent window first
+ GetMDIFrame()->OnUpdateFrameTitle (bAddToTitle);
+ if ((GetStyle() & FWS_ADDTOTITLE) == 0) {
+ return; // leave child window alone!
+ }
+ CDocument* pDocument = GetActiveDocument();
+ if (bAddToTitle && pDocument != NULL) {
+ CString strEventList;
+ strEventList.LoadString (IDS_EVENTLIST);
+ CString strTitle;
+ if (m_nWindow > 0) {
+ strTitle.Format (_T("%s:%d(%s)"), pDocument->GetTitle (), m_nWindow, strEventList);
+ }
+ else {
+ strTitle.Format (_T("%s(%s)"), pDocument->GetTitle (), strEventList);
+ }
+ this->SetWindowText (strTitle);
+ }
+}
+
+// 再配置用関数(CFrameWnd::RecalcLayoutのオーバーライド)
+void CEventListFrame::RecalcLayout (BOOL bNotify) {
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+
+ // 基本クラスの関数を処理
+ CFrameWnd::RecalcLayout (bNotify);
+
+ // アイコン化時には各コントロールのサイズを再計算しない。
+ if (rcClient.Width () == 0 || rcClient.Height () == 0) {
+ return;
+ }
+
+ // ツールバー1の高さ取得
+ CRect rcToolBar1;
+ m_wndToolBar1.GetWindowRect (rcToolBar1);
+ m_lToolBar1Height = rcToolBar1.Height ();
+
+ // 高さ方向の位置計算
+ if (rcClient.Height () <
+ m_lToolBar1Height + EVENTLISTFRAME_SCALEHEIGHT + m_lHScrollBarHeight +
+ EVENTLISTFRAME_BORDERHEIGHT * 2) {
+ m_lScaleHeight = rcClient.Height () - m_lHScrollBarHeight -
+ EVENTLISTFRAME_BORDERHEIGHT * 2 - m_lToolBar1Height;
+ m_lIndexHeight = 0;
+ }
+ else {
+ m_lScaleHeight = EVENTLISTFRAME_SCALEHEIGHT;
+ m_lIndexHeight = rcClient.Height () -
+ m_lScaleHeight - m_lHScrollBarHeight -
+ EVENTLISTFRAME_BORDERHEIGHT * 2 - m_lToolBar1Height;
+ }
+ if (rcClient.Height () <
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT * 4 +
+ EVENTLISTFRAME_SPLITTERHEIGHT + m_lTrackListHeight) {
+ m_lTrackListHeight = rcClient.Height () -
+ m_lToolBar1Height - EVENTLISTFRAME_BORDERHEIGHT * 4 -
+ EVENTLISTFRAME_SPLITTERHEIGHT;
+ m_lEventKindListHeight = 0;
+ }
+ else {
+ m_lTrackListHeight = m_lTrackListHeight;
+ m_lEventKindListHeight = rcClient.Height () -
+ m_lToolBar1Height - EVENTLISTFRAME_BORDERHEIGHT * 4 -
+ EVENTLISTFRAME_SPLITTERHEIGHT - m_lTrackListHeight;
+ }
+
+ // 幅方向の位置計算
+ if (rcClient.Width () <
+ EVENTLISTFRAME_SCALEWIDTH + m_lVScrollBarWidth +
+ EVENTLISTFRAME_BORDERWIDTH * 4 + EVENTLISTFRAME_SPLITTERWIDTH) {
+ m_lScaleWidth = rcClient.Width () -
+ m_lVScrollBarWidth - EVENTLISTFRAME_BORDERWIDTH * 4 - EVENTLISTFRAME_SPLITTERWIDTH;
+ m_lTrackListWidth = 0;
+ m_lPropertyWidth = 0;
+ }
+ else if (rcClient.Width () <
+ EVENTLISTFRAME_SCALEWIDTH + m_lVScrollBarWidth +
+ EVENTLISTFRAME_BORDERWIDTH * 4 + EVENTLISTFRAME_SPLITTERWIDTH + m_lTrackListWidth) {
+ m_lScaleWidth = EVENTLISTFRAME_SCALEWIDTH;
+ m_lPropertyWidth = 0;
+ m_lTrackListWidth = rcClient.Width () - m_lScaleWidth -
+ m_lVScrollBarWidth - EVENTLISTFRAME_BORDERWIDTH * 4 - EVENTLISTFRAME_SPLITTERWIDTH;
+
+ }
+ else {
+ m_lScaleWidth = EVENTLISTFRAME_SCALEWIDTH;
+ m_lTrackListWidth = m_lTrackListWidth;
+ m_lPropertyWidth = rcClient.Width () - m_lScaleWidth - m_lTrackListWidth -
+ m_lVScrollBarWidth - EVENTLISTFRAME_BORDERWIDTH * 4 - EVENTLISTFRAME_SPLITTERWIDTH;
+ }
+
+ // ビューの整列
+ if (m_pScaleView) {
+ m_pScaleView->MoveWindow (EVENTLISTFRAME_BORDERWIDTH,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT,
+ m_lScaleWidth, m_lScaleHeight);
+ }
+
+ if (m_pPropertyScaleView) {
+ m_pPropertyScaleView->MoveWindow (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT,
+ m_lPropertyWidth, m_lScaleHeight);
+ }
+
+ if (m_pIndexScaleView) {
+ m_pIndexScaleView->MoveWindow (EVENTLISTFRAME_BORDERWIDTH,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lScaleWidth, m_lIndexHeight);
+ }
+
+ if (m_pIndexPropertyView) {
+ m_pIndexPropertyView->MoveWindow (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lPropertyWidth, m_lIndexHeight);
+ }
+
+ // スクロールバーの整列
+ m_wndColumnScroll.MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lIndexHeight,
+ m_lScaleWidth + m_lPropertyWidth - m_lVScrollBarWidth * 2,
+ m_lHScrollBarHeight);
+
+ m_wndRowScroll.MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth + m_lPropertyWidth,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT,
+ m_lVScrollBarWidth,
+ m_lScaleHeight + m_lIndexHeight - m_lVScrollBarWidth * 2);
+
+ m_wndSizeScroll.MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth + m_lPropertyWidth,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lIndexHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ // ズームボタンの整列
+ m_wndColumnZoomDown.MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lPropertyWidth - m_lVScrollBarWidth * 2,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lIndexHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndColumnZoomUp.MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lPropertyWidth - m_lVScrollBarWidth,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lIndexHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndRowZoomDown.MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth + m_lPropertyWidth,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lIndexHeight -
+ m_lVScrollBarWidth * 2,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndRowZoomUp.MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH + m_lScaleWidth + m_lPropertyWidth,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lIndexHeight -
+ m_lVScrollBarWidth,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ // トラックリストの整列
+ m_pTrackListBox->MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lPropertyWidth + m_lVScrollBarWidth + EVENTLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT,
+ m_lTrackListWidth, m_lTrackListHeight);
+
+ // イベントの種類リストの整列
+ m_pEventKindListBox->MoveWindow
+ (EVENTLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lPropertyWidth + m_lVScrollBarWidth + EVENTLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT * 3 + m_lTrackListHeight +
+ EVENTLISTFRAME_SPLITTERHEIGHT,
+ m_lTrackListWidth, m_lEventKindListHeight);
+
+ // スクロールバーのサイズが変化したので、バーのデザインを再調整する。
+ RecalcRowScrollInfo ();
+ RecalcColumnScrollInfo ();
+
+}
+
+
+
+// クライアント領域の生成(CFrameWnd::OnCreateClientのオーバーライド)
+BOOL CEventListFrame::OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext) {
+
+ // サイズ調整用のダミービュー生成(Visible = FALSE)
+ CWnd* pWnd = NULL;
+ m_pDummyView = (CView*)CFrameWnd::CreateView (pContext, EVENTLISTFRAME_DUMMYVIEW);
+ if (m_pDummyView == NULL) {
+ return FALSE;
+ }
+ m_pDummyView->ShowWindow (SW_HIDE);
+
+ // 印刷用のビュー生成(Visible = FALSE)
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CEventListPrintView);
+ m_pPrintView = (CView*)CFrameWnd::CreateView (pContext, EVENTLISTFRAME_PRINTVIEW);
+ if (m_pPrintView == NULL) {
+ return FALSE;
+ }
+ m_pPrintView->ShowWindow (SW_HIDE);
+
+ // 左上ビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CEventListScaleView);
+ m_pScaleView = (CView*)CFrameWnd::CreateView (pContext, EVENTLISTFRAME_SCALEVIEW);
+ if (m_pScaleView == NULL) {
+ return FALSE;
+ }
+ m_pScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // 上部項目名部ビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CEventListPropertyScaleView);
+ m_pPropertyScaleView = (CView*)CFrameWnd::CreateView (pContext, EVENTLISTFRAME_PROPERTYSCALEVIEW);
+ if (m_pPropertyScaleView == NULL) {
+ return FALSE;
+ }
+ m_pPropertyScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // 左部番号部ビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CEventListIndexScaleView);
+ m_pIndexScaleView = (CView*)CFrameWnd::CreateView (pContext, EVENTLISTFRAME_INDEXSCALEVIEW);
+ if (m_pIndexScaleView == NULL) {
+ return FALSE;
+ }
+ m_pIndexScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // リスト部ビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CEventListIndexPropertyView);
+ m_pIndexPropertyView = (CView*)CFrameWnd::CreateView (pContext, EVENTLISTFRAME_INDEXPROPERTYVIEW);
+ if (m_pIndexPropertyView == NULL) {
+ return FALSE;
+ }
+ m_pIndexPropertyView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // スクロールバーの生成
+ m_wndColumnScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_HORZ, CRect(0,0,0,0), this, EVENTLISTFRAME_COLUMNSCROLL);
+ m_wndRowScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_VERT, CRect(0,0,0,0), this, EVENTLISTFRAME_ROWSCROLL);
+ m_wndSizeScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_SIZEBOX, CRect(0,0,0,0), this, EVENTLISTFRAME_SIZEBOX);
+
+ // ズームボタン類の生成
+ m_wndColumnZoomDown.Create
+ (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, EVENTLISTFRAME_COLUMNZOOMDOWN);
+ m_wndColumnZoomUp.Create
+ (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, EVENTLISTFRAME_COLUMNZOOMUP);
+ m_wndRowZoomDown.Create
+ (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, EVENTLISTFRAME_ROWZOOMDOWN);
+ m_wndRowZoomUp.Create
+ (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, EVENTLISTFRAME_ROWZOOMUP);
+
+ // トラックリストの生成
+ m_pTrackListBox =
+ new CTrackListBox (pContext->m_pCurrentDoc, IDR_POPUPMENU23);
+ m_pTrackListBox->Create
+ (WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|
+ LBS_NOTIFY|LBS_DISABLENOSCROLL|LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOINTEGRALHEIGHT,
+ CRect(0,0,0,0), this, EVENTLISTFRAME_TRACKLIST);
+
+ // イベントの種類の生成
+ m_pEventKindListBox =
+ new CEventKindListBox (pContext->m_pCurrentDoc, IDR_POPUPMENU24);
+ m_pEventKindListBox->Create
+ (WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|
+ LBS_NOTIFY|LBS_DISABLENOSCROLL|LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOINTEGRALHEIGHT,
+ CRect(0,0,0,0), this, EVENTLISTFRAME_EVENTKINDLIST);
+
+ // フォーカスの設定
+ SetActiveView ((CView*)m_pIndexPropertyView);
+
+ // コントロールの位置合わせはWM_SIZEなどによるRecalcLaoyoutに任せる。
+ return TRUE;
+
+}
+
+// 印刷用のコマンドをトラップ(CFrameWnd::OnCmdMsgのオーバーライド)
+BOOL CEventListFrame::OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 印刷用のコマンドの場合、強制的にCEventListPrintViewに渡す。
+ if ((nID == ID_FILE_PRINT || nID == ID_FILE_PRINT_DIRECT || nID == ID_FILE_PRINT_PREVIEW) &&
+ pSekaijuApp->m_bRecording == FALSE) {
+ if (m_pPrintView) {
+ return ((CEventListPrintView*)m_pPrintView)->OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+ }
+ return FALSE;
+ }
+ // その他のコマンドはデフォルトの処理とする。
+ return CFrameWnd::OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CEventListFrame::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+ CRect rcTemp;
+
+ // ツールバー1の作成
+ if (!m_wndToolBar1.Create (this) ||
+ !m_wndToolBar1.LoadToolBar (IDR_EVENTLIST1)) {
+ TRACE0 ("Failed to create toolbar\n");
+ return -1;
+ }
+ m_wndToolBar1.SetBarStyle (m_wndToolBar1.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ //m_wndToolBar1.EnableDocking (CBRS_ALIGN_ANY);
+ //EnableDocking (CBRS_ALIGN_ANY);
+ //DockControlBar (&m_wndToolBar1);
+
+ LoadAccelTable (MAKEINTRESOURCE (IDR_EVENTLIST));
+
+ // イベントトラックコンボボックスの作成
+ m_wndToolBar1.SetButtonInfo (4, IDC_EVENTTRACKCOMBO, TBBS_SEPARATOR, 120);
+ m_wndToolBar1.GetItemRect (4, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndEventTrackCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_EVENTTRACKCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndEventTrackCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // イベントタイムエディットの作成
+ m_wndToolBar1.SetButtonInfo (6, IDC_EVENTTIMEEDIT, TBBS_SEPARATOR, 120);
+ m_wndToolBar1.GetItemRect (6, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 22;
+ if (!m_wndEventTimeEdit.CreateEx (
+ WS_EX_CLIENTEDGE, _T("EDIT"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_EVENTTIMEEDIT)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndEventTimeEdit.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // イベント種類コンボボックスの作成
+ m_wndToolBar1.SetButtonInfo (8, IDC_EVENTKINDCOMBO, TBBS_SEPARATOR, 150);
+ m_wndToolBar1.GetItemRect (8, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndEventKindCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_EVENTKINDCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndEventKindCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // イベントチャンネルコンボボックスの作成
+ m_wndToolBar1.SetButtonInfo (10, IDC_EVENTCHANNELCOMBO, TBBS_SEPARATOR, 60);
+ m_wndToolBar1.GetItemRect (10, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 22;
+ if (!m_wndEventChannelCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_EVENTCHANNELCOMBO)) {
+ TRACE0 ("Failed to create combo box\n");
+ return -1;
+ }
+ m_wndEventChannelCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // 親クラスの関数呼び出し
+ int nRet = CChildFrame::OnCreate (lpCreateStruct);
+
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+
+ // トラックコンボの充満
+ UpdateTrackCombo ();
+ m_wndEventTrackCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // イベントの時刻エディットの充満
+ CString strText;
+ strText.Format (_T("%05d:%02d:%03d"), 1, 1, 0);
+ m_wndEventTimeEdit.SetWindowText (strText);
+
+ // イベントの種類コンボの充満
+
+ m_wndEventKindCombo.ResetContent ();
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x00]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x01]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x02]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x03]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x04]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x05]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x06]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x07]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x08]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x09]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x20]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x21]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x2F]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x51]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x54]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x58]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x59]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x7F]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x80]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0x90]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0xA0]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0xB0]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0xC0]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0xD0]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0xE0]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0xF0]);
+ m_wndEventKindCombo.AddString (pSekaijuApp->m_strEventKindName[0xF7]);
+ m_wndEventKindCombo.SetCurSel (0);
+ m_wndEventKindCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // イベントのチャンネルコンボの充満
+ strText = _T("n/a");
+ m_wndEventChannelCombo.AddString (strText);
+ int i = 0;
+ for (i = 0; i < 16; i++) {
+ strText.Format (_T("%d"), i + 1);
+ m_wndEventChannelCombo.AddString (strText);
+ }
+ m_wndEventChannelCombo.SetCurSel (0);
+ m_wndEventChannelCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // トラックリストの充満
+ UpdateTrackList ();
+ m_pTrackListBox->SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+ long lCount = m_pTrackListBox->GetCount ();
+ i = 0;
+ if (pSekaijuDoc->m_pTempTrack) {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (0 <= i && i < lCount) {
+ m_pTrackListBox->SetCheck (i, pMIDITrack == pSekaijuDoc->m_pTempTrack ? TRUE : FALSE);
+ m_bTrackVisible[i] = (pMIDITrack == pSekaijuDoc->m_pTempTrack ? TRUE : FALSE);
+ }
+ i++;
+ }
+ }
+ else {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (0 <= i && i < lCount) {
+ m_pTrackListBox->SetCheck (i, TRUE);
+ m_bTrackVisible[i] = (TRUE);
+ }
+ i++;
+ }
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+
+ // カレントトラックとカレントチャンネルを更新
+ long lTrackIndex = 0;
+ if (pSekaijuDoc->m_pTempTrack) {
+ lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ }
+ else if (MIDIData_GetFormat (pMIDIData) == 1 && lCount >= 2) {
+ lTrackIndex = 1;
+ }
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ }
+
+ // グラフの種類リストの充満
+ CString strIncludingVelocity0NoteOn;
+ CString strUnknownEventKind;
+ VERIFY (strIncludingVelocity0NoteOn.LoadString (IDS_INCLUDING_VELOCITY0_NOTEON));
+ VERIFY (strUnknownEventKind.LoadString (IDS_UNKNOWN_EVENT_KIND));
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x00]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x01]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x02]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x03]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x04]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x05]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x06]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x07]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x08]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x09]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x20]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x21]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x2F]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x51]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x54]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x58]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x59]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x7F]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x80] + strIncludingVelocity0NoteOn);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0x90]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0xA0]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0xB0]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0xC0]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0xD0]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0xE0]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0xF0]);
+ m_pEventKindListBox->AddString (pSekaijuApp->m_strEventKindName[0xF7]);
+ m_pEventKindListBox->AddString (strUnknownEventKind);
+ m_pEventKindListBox->SetCurSel (0);
+ m_pEventKindListBox->SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+ lCount = m_pEventKindListBox->GetCount ();
+ for (i = 0; i < lCount; i++) {
+ m_pEventKindListBox->SetCheck (i, IsEventKindVisible (i) ? 1 : 0);
+ }
+
+ // カレントチャンネルの自動選択
+ if (pSekaijuDoc->m_pTempTrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+
+ // 可視のイベントリストの作成
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+
+ // 自動ページ更新の設定
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) {
+ m_bAutoPageUpdate = TRUE;
+ }
+
+ SetActiveView (m_pIndexPropertyView, FALSE);
+ m_pIndexPropertyView->SetFocus ();
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+
+ return nRet;
+}
+
+// ウィンドウ破棄時
+void CEventListFrame::OnDestroy () {
+ m_pTrackListBox->DestroyWindow ();
+ delete m_pTrackListBox;
+ m_pEventKindListBox->DestroyWindow ();
+ delete m_pEventKindListBox;
+ CChildFrame::OnDestroy ();
+}
+
+// ウィンドウサイズ変更時
+void CEventListFrame::OnSize (UINT nType, int cx, int cy) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ // 基本クラスの関数呼び出し
+ CChildFrame::OnSize (nType, cx, cy);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// タイマー呼び出し時
+void CEventListFrame::OnTimer (UINT nIDEvent) {
+ ;
+}
+
+// 背景消去(CFrameWnd::OnEraseBkgndのオーバーライド)
+BOOL CEventListFrame::OnEraseBkgnd (CDC* pDC) {
+ return 0;
+}
+
+// ウィンドウがアクティブになったとき
+void CEventListFrame::OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd) {
+ CChildFrame::OnMDIActivate (bActivate, pActivateWnd, pDeactivateWnd);
+}
+
+// 閉じるボタンが押されたとき
+void CEventListFrame::OnClose () {
+ _RPTF0 (_CRT_WARN, ("CEventListFrame::OnClose ()\n"));
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // インプレースエディット及びインプレースリストボックスの終了
+ if (m_pIndexPropertyView) {
+ CEventListIndexPropertyView* pIndexPropertyView = (CEventListIndexPropertyView*)m_pIndexPropertyView;
+ if (pIndexPropertyView->IsTextEditing ()) {
+ pIndexPropertyView->EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ if (pIndexPropertyView->IsListSelecting ()) {
+ pIndexPropertyView->EndListSelectingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ }
+ CChildFrame::OnClose ();
+}
+
+// 描画するとき
+void CEventListFrame::OnPaint () {
+ CPaintDC dc (this);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ // 左部分のくぼみ描画
+ CRect rcClient1 (rcClient);
+ rcClient1.top = m_lToolBar1Height;
+ rcClient1.right = EVENTLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth +
+ m_lPropertyWidth + m_lVScrollBarWidth;
+ dc.Draw3dRect (&rcClient1, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient1.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient1, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 右上部分のくぼみ描画
+ CRect rcClient2 (rcClient);
+ rcClient2.top = m_lToolBar1Height;
+ rcClient2.left = EVENTLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth +
+ m_lPropertyWidth + m_lVScrollBarWidth + EVENTLISTFRAME_SPLITTERWIDTH;
+ rcClient2.bottom = m_lToolBar1Height +
+ EVENTLISTFRAME_BORDERHEIGHT * 2 + m_lTrackListHeight;
+ dc.Draw3dRect (&rcClient2, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient2.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient2, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 右下部分のくぼみ描画
+ CRect rcClient3 (rcClient);
+ rcClient3.top = m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT * 2 +
+ EVENTLISTFRAME_SPLITTERHEIGHT + m_lTrackListHeight;
+ rcClient3.left = EVENTLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth +
+ m_lPropertyWidth + m_lVScrollBarWidth + EVENTLISTFRAME_SPLITTERWIDTH;
+ dc.Draw3dRect (&rcClient3, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient3.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient3, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 横境界部分の描画
+ CBrush brush;
+ brush.CreateSolidBrush (::GetSysColor (COLOR_3DFACE));
+ CRect rcClient5 (rcClient);
+ rcClient5.left = rcClient2.left - 1;
+ rcClient5.top = rcClient2.bottom + 1;
+ rcClient5.bottom = rcClient3.top - 1;
+ dc.FillRect (&rcClient5, &brush);
+ // 縦境界部分の描画
+ CRect rcClient6 (rcClient);
+ rcClient6.left = rcClient1.right + 1;
+ rcClient6.right = rcClient2.left - 1;
+ dc.FillRect (&rcClient6, &brush);
+
+}
+
+// キー押し下げ時
+void CEventListFrame::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CWnd* pOldFocus = GetFocus ();
+ switch (nChar) {
+ // ↑
+ case VK_UP:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // ↓
+ case VK_DOWN:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // PageUp
+ case VK_PRIOR:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // PageDown
+ case VK_NEXT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // ←
+ case VK_LEFT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // →
+ case VK_RIGHT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // Home
+ case VK_HOME:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // End
+ case VK_END:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // '-'(ズームダウン)
+ case 189:
+ case VK_SUBTRACT:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_theEventListOption.m_bEnableRowZoomKey) {
+ this->PostMessage (WM_COMMAND, EVENTLISTFRAME_ROWZOOMDOWN, 0);
+ }
+ if (pSekaijuApp->m_theEventListOption.m_bEnableColumnZoomKey) {
+ this->PostMessage (WM_COMMAND, EVENTLISTFRAME_COLUMNZOOMDOWN, 0);
+ }
+ }
+ break;
+ // '+'(ズームアップ)
+ case 187:
+ case VK_ADD:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_theEventListOption.m_bEnableRowZoomKey) {
+ this->PostMessage (WM_COMMAND, EVENTLISTFRAME_ROWZOOMUP, 0);
+ }
+ if (pSekaijuApp->m_theEventListOption.m_bEnableColumnZoomKey) {
+ this->PostMessage (WM_COMMAND, EVENTLISTFRAME_COLUMNZOOMUP, 0);
+ }
+ }
+ break;
+ }
+}
+
+// マウス左ボタン押された時
+void CEventListFrame::OnLButtonDown (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 上半分(トラックリスト部)と下半分(イベントの種類部)の境界線上をドラッグすると、境界線が上下に移動
+ if (m_bSplitterMovingH || m_bSplitterMovingV) {
+ SetCapture ();
+ m_ptMouseDown = m_ptMouseMoveOld = point;
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ if (m_bSplitterMovingH && m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeAll);
+ }
+ else if (m_bSplitterMovingH) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeNS);
+ }
+ else if (m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+ }
+
+}
+
+// マウス右ボタン押された時
+void CEventListFrame::OnRButtonDown (UINT nFlags, CPoint point) {
+
+}
+
+// マウス左ボタン離されたとき
+void CEventListFrame::OnLButtonUp (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (GetCapture () == this) {
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ ReleaseDC (pDC);
+ ReleaseCapture ();
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ CPoint ptDelta = point - m_ptMouseDown;
+ if (m_bSplitterMovingH) {
+ m_lTrackListHeight = CLIP (0, (m_lTrackListHeight + ptDelta.y), 1200);
+ }
+ if (m_bSplitterMovingV) {
+ m_lTrackListWidth = CLIP (0, (m_lTrackListWidth - ptDelta.x), 1600);
+ }
+ RecalcLayout ();
+ m_bSplitterMovingH = FALSE;
+ m_bSplitterMovingV = FALSE;
+ Invalidate ();
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CEventListFrame::OnRButtonUp (UINT nFlags, CPoint point) {
+
+}
+
+// マウスが動かされたとき
+void CEventListFrame::OnMouseMove (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // キャプター中
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ m_ptMouseMoveOld = point;
+ }
+ // 非キャプター中
+ else {
+ // カーソルが水平スプリッター上にあるか
+ m_bSplitterMovingH =
+ m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT * 2 + m_lTrackListHeight <= point.y &&
+ point.y < m_lToolBar1Height + EVENTLISTFRAME_BORDERHEIGHT * 2 + m_lTrackListHeight +
+ EVENTLISTFRAME_SPLITTERHEIGHT &&
+ point.x >= EVENTLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lPropertyWidth + m_lVScrollBarWidth;
+ // カーソルが垂直スプリッター上にあるか
+ m_bSplitterMovingV =
+ EVENTLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lPropertyWidth + m_lVScrollBarWidth <= point.x &&
+ point.x < EVENTLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lPropertyWidth + m_lVScrollBarWidth +
+ EVENTLISTFRAME_SPLITTERWIDTH;
+ // カーソルが水平スプリッターと垂直スプリッターの交差部にある場合
+ if (m_bSplitterMovingH && m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeAll);
+ }
+ // カーソルが水平スプリッター上にある場合
+ else if (m_bSplitterMovingH) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeNS);
+ }
+ // カーソルが垂直スプリッター上にある場合
+ else if (m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+ // カーソルがスプリッターにない場合
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ }
+ }
+
+}
+
+// 列方向ズームダウン(20091220:左端位置保持機能追加)
+void CEventListFrame::OnColumnZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldColumnZoom = m_lColumnZoom;
+ long lOldColumnPos = m_wndColumnScroll.GetScrollPos ();
+ long lNewColumnZoom = CLIP (2, m_lColumnZoom - 1, 16);
+ long lNewColumnPos = lOldColumnPos * lNewColumnZoom / lOldColumnZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lColumnZoom = lNewColumnZoom;
+ RecalcColumnScrollInfo ();
+ m_wndColumnScroll.SetScrollPos (lNewColumnPos);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+ m_pPropertyScaleView->Invalidate ();
+ //long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ //long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (lCurRow, lCurColumn);
+ m_pIndexPropertyView->Invalidate ();
+ m_pIndexPropertyView->SetFocus ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 列方向ズームアップ(20091220:左端位置保持機能追加)
+void CEventListFrame::OnColumnZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldColumnZoom = m_lColumnZoom;
+ long lOldColumnPos = m_wndColumnScroll.GetScrollPos ();
+ long lNewColumnZoom = CLIP (2, m_lColumnZoom + 1, 16);
+ long lNewColumnPos = lOldColumnPos * lNewColumnZoom / lOldColumnZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lColumnZoom = lNewColumnZoom;
+ RecalcColumnScrollInfo ();
+ m_wndColumnScroll.SetScrollPos (lNewColumnPos);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+ m_pPropertyScaleView->Invalidate ();
+ //long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ //long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (lCurRow, lCurColumn);
+ m_pIndexPropertyView->Invalidate ();
+ m_pIndexPropertyView->SetFocus ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 行方向ズームダウン(20091220:上端位置保持機能追加、自動ページ更新自動オフ追加)
+void CEventListFrame::OnRowZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldRowZoom = m_lRowZoom;
+ long lOldRowPos = m_wndRowScroll.GetScrollPos ();
+ long lNewRowZoom = CLIP (16, m_lRowZoom - 2, 32);
+ long lNewRowPos = lOldRowPos * lNewRowZoom / lOldRowZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lRowZoom = lNewRowZoom;
+ RecalcRowScrollInfo ();
+ m_wndRowScroll.SetScrollPos (lNewRowPos);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+ m_pIndexScaleView->Invalidate ();
+ //long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ //long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (lCurRow, lCurColumn);
+ m_pIndexPropertyView->Invalidate ();
+ m_pIndexPropertyView->SetFocus ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 行方向ズームアップ(20091220:上端位置保持機能追加、自動ページ更新自動オフ追加)
+void CEventListFrame::OnRowZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldRowZoom = m_lRowZoom;
+ long lOldRowPos = m_wndRowScroll.GetScrollPos ();
+ long lNewRowZoom = CLIP (16, m_lRowZoom + 2, 32);
+ long lNewRowPos = lOldRowPos * lNewRowZoom / lOldRowZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lRowZoom = lNewRowZoom;
+ RecalcRowScrollInfo ();
+ m_wndRowScroll.SetScrollPos (lNewRowPos);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+ m_pIndexScaleView->Invalidate ();
+ //long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ //long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (lCurRow, lCurColumn);
+ //((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (lCurRow, lCurColumn);
+ m_pIndexPropertyView->Invalidate ();
+ m_pIndexPropertyView->SetFocus ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 水平スクロール
+void CEventListFrame::OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndColumnScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lColumnScrollPos;
+ switch (nSBCode) {
+ case SB_LINELEFT:
+ lNewPos = m_lColumnScrollPos - m_lColumnZoom;
+ break;
+ case SB_LINERIGHT:
+ lNewPos = m_lColumnScrollPos + m_lColumnZoom;
+ break;
+ case SB_PAGELEFT:
+ lNewPos = m_lColumnScrollPos - m_lColumnZoom * 4;
+ break;
+ case SB_PAGERIGHT:
+ lNewPos = m_lColumnScrollPos + m_lColumnZoom * 4;
+ break;
+ case SB_LEFT: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_RIGHT: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetColumnScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_pIndexPropertyView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 垂直スクロール
+void CEventListFrame::OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndRowScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lRowScrollPos;
+ switch (nSBCode) {
+ case SB_LINEUP:
+ lNewPos = m_lRowScrollPos - m_lRowZoom;
+ break;
+ case SB_LINEDOWN:
+ lNewPos = m_lRowScrollPos + m_lRowZoom;
+ break;
+ case SB_PAGEUP:
+ lNewPos = m_lRowScrollPos -
+ __max (1, GetVisibleBottomRow () - GetVisibleTopRow ()) * m_lRowZoom;;
+ break;
+ case SB_PAGEDOWN:
+ lNewPos = m_lRowScrollPos +
+ __max (1, GetVisibleBottomRow () - GetVisibleTopRow ()) * m_lRowZoom;
+ break;
+ case SB_TOP: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_BOTTOM: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetRowScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_bAutoPageUpdate = FALSE;
+ m_pIndexPropertyView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+
+// 『ツール(&T)』-『イベントの挿入(&I)』
+void CEventListFrame::OnEventListInsertEvent () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+ CString strText;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ // 挿入トラック
+ long lTargetTrackIndex = m_wndEventTrackCombo.GetCurSel ();
+ MIDITrack* pTargetTrack = pSekaijuDoc->GetTrack (lTargetTrackIndex);
+ if (pTargetTrack == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_THE_EVENT_TO_THIS_TRACK));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+
+ // 挿入時刻
+ long lTargetTime = 0;
+ m_wndEventTimeEdit.GetWindowText (strText);
+ long lErrorID = pSekaijuDoc->StringTimeToLongTime (pMIDIData, strText, &lTargetTime);
+ if (lErrorID > 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+
+ // 挿入イベントの種類
+ long lTargetKindIndex = m_wndEventKindCombo.GetCurSel ();
+ long lTargetKind = ListIndextoEventKind (lTargetKindIndex);
+ ASSERT (0x00 <= lTargetKind && lTargetKind <= 0xFF);
+
+ // 既にEOTがある場合、EOTの二重挿入はできない。
+ if (lTargetKind == MIDIEVENT_ENDOFTRACK) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pTargetTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_ENDOFTRACK_TO_THIS_TRACK_ANY_MORE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+ }
+ }
+
+ // MIDIチャンネルイベントの場合はチャンネル情報無視
+ if (0x80 <= lTargetKind && lTargetKind <= 0xEF) {
+ lTargetKind &= 0xF0;
+ }
+
+ // フォーマット1のMIDIデータに対するイベント種類の正当性検査
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ if (lFormat == 1) {
+ // 最初のトラックの場合
+ if (pTargetTrack == MIDIData_GetFirstTrack (pMIDIData)) {
+ if (0x80 <= lTargetKind && lTargetKind <= 0xEF) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_THIS_EVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+ }
+ // 2番目以降のトラックの場合
+ else {
+ if (lTargetKind == MIDIEVENT_TEMPO ||
+ lTargetKind == MIDIEVENT_SMPTEOFFSET ||
+ lTargetKind == MIDIEVENT_TIMESIGNATURE ||
+ lTargetKind == MIDIEVENT_KEYSIGNATURE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_THIS_EVENT_TO_THE_SECOND_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+ }
+ }
+
+ // ノートオフはノートオン+ノートオフイベントに修正
+ if (0x80 <=lTargetKind && lTargetKind <= 0x8F) {
+ lTargetKind = MIDIEVENT_NOTEONNOTEOFF;
+ }
+ // ノートオンはノートオン+ノートオン0イベントに修正
+ else if (0x90 <=lTargetKind && lTargetKind <= 0x9F) {
+ lTargetKind = MIDIEVENT_NOTEONNOTEON0;
+ }
+
+ // 挿入チャンネル
+ long lTargetCh = m_wndEventChannelCombo.GetCurSel () - 1;
+
+ long i = 0;
+ long lRet = 0;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+
+ // 新しいイベントの作成
+ MIDIEvent* pNewMIDIEvent = MIDIEvent_CreateTextEvent (lTargetTime, _T(""));
+ if (pNewMIDIEvent == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INSUFFICIENT_MEMORY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+ // イベントの種類を変更
+ MIDIEvent_SetKind (pNewMIDIEvent, lTargetKind);
+
+ // MIDIイベントの場合チャンネルを変更する。
+ if (MIDIEvent_IsMIDIEvent (pNewMIDIEvent) && 0 <= lTargetCh && lTargetCh < 16) {
+ MIDIEvent_SetChannel (pNewMIDIEvent, lTargetCh);
+ }
+
+ // ノートイベントで長さ0以下の場合長さは4分音符とする。
+ if (MIDIEvent_IsNoteOn (pNewMIDIEvent) && MIDIEvent_IsNote (pNewMIDIEvent)) {
+ if (MIDIEvent_GetDuration (pNewMIDIEvent) <= 0) {
+ long lNewDuration = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ MIDIEvent_SetDuration (pNewMIDIEvent, CLIP (1, lNewDuration, 65535));
+ }
+ }
+
+ // 履歴の保持
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_EVENT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pTargetTrack);
+ MIDIEvent* pNewLastEvent = NULL;
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pNewLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ this->ReplaceVisibleEvent (pLastEvent, pNewLastEvent);
+ }
+ }
+
+ // ターゲットタイムより挿入する直前又は直後のイベントを取得(20100226修正)
+ MIDIEvent* pTargetMIDIEvent = NULL;
+ // 同時刻イベントの後方に挿入する場合(20100226修正)
+ if (pSekaijuApp->m_theEventListOption.m_bInsertEventAfter) {
+ MIDIEvent* pEvent = NULL;
+ forEachEventInverse (pTargetTrack, pEvent) {
+ long lTime = MIDIEvent_GetTime (pEvent);
+ if (lTime <= lTargetTime && !MIDIEvent_IsEndofTrack (pEvent)) {
+ break;
+ }
+ }
+ pTargetMIDIEvent = pEvent;
+ }
+ // 同時刻イベントの前方に挿入する場合(20100226修正)
+ else {
+ MIDIEvent* pEvent = NULL;
+ forEachEvent (pTargetTrack, pEvent) {
+ long lTime = MIDIEvent_GetTime (pEvent);
+ if (lTime == lTargetTime && !MIDIEvent_IsNoteOff (pEvent) ||
+ lTime > lTargetTime) {
+ break;
+ }
+ }
+ pTargetMIDIEvent = pEvent;
+ }
+
+ // ターゲットトラックへ新しいイベントを挿入する(20100226修正)
+ if (pSekaijuApp->m_theEventListOption.m_bInsertEventAfter) { // 20090226追加
+ lRet = MIDITrack_InsertEventAfter (pTargetTrack, pNewMIDIEvent, pTargetMIDIEvent);
+ }
+ else { // 20090226追加
+ lRet = MIDITrack_InsertEventBefore (pTargetTrack, pNewMIDIEvent, pTargetMIDIEvent);
+ }
+ if (lRet == 0) {
+ MIDIEvent_Delete (pNewMIDIEvent);
+ if (pNewLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewLastEvent));
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INSERT_EVENT_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+
+ // 履歴の保持
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewMIDIEvent));
+ if (pNewLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewLastEvent));
+ }
+
+ // 指定したトラックが非表示の場合、表示状態にする。
+ if (IsTrackVisible (lTargetTrackIndex) == FALSE) {
+ this->SetTrackVisible (lTargetTrackIndex);
+ }
+ // 指定したイベントの種類が非表示の場合、表示状態にする。
+ if (IsEventKindVisible (lTargetKindIndex) == FALSE) {
+ this->SetEventKindVisible (lTargetKindIndex);
+ }
+ // ビューの更新
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 行方向スクロール情報の更新
+ this->RecalcRowScrollInfo ();
+ // フォーカスを新しいイベントに合わせる。
+ long lCount = m_theVisibleEventArray.GetSize ();
+ for (i = 0; i < lCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pNewMIDIEvent) {
+ long j = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow = i;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (i, j);
+ return;
+ }
+ }
+ return;
+}
+
+// 『ツール(&T)』-『イベントの挿入(&I)』
+void CEventListFrame::OnUpdateEventListInsertEventUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ long lCount = m_theVisibleEventArray.GetSize ();
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ if (0 <= lCurRow && lCurRow < lCount) {
+ pCmdUI->Enable (TRUE);
+ }
+ else {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ツール(&T)』-『イベントの複写(&D)』
+void CEventListFrame::OnEventListDuplicateEvent () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+ CString strText;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ long i = 0;
+ long lRet = 0;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ MIDIEvent* pSrcMIDIEvent = NULL;
+ MIDIEvent* pSrcPrevEvent = NULL;
+ MIDIEvent* pSrcNextEvent = NULL;
+ MIDITrack* pSrcMIDITrack = NULL;
+ MIDIEvent* pNewMIDIEvent = NULL;
+ pSrcMIDIEvent = GetVisibleEvent (lCurRow);
+
+ // 複写元イベントチェック
+ if (pSrcMIDIEvent == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CURRENT_MIDIEVENT_IS_EMPTY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+ pSrcMIDIEvent = MIDIEvent_GetFirstCombinedEvent (pSrcMIDIEvent); // 20100226追加
+ pSrcPrevEvent = GetVisibleEvent (lCurRow - 1);
+
+ pSrcNextEvent = GetVisibleEvent (lCurRow + 1);
+ pSrcMIDITrack = MIDIEvent_GetParent (pSrcMIDIEvent);
+ long lSrcTime = MIDIEvent_GetTime (pSrcMIDIEvent);
+ long lSrcTrackIndex = pSekaijuDoc->GetTrackIndex (pSrcMIDITrack);
+ long lSrcEventKind = MIDIEvent_GetKind (pSrcMIDIEvent);
+ long lSrcKindIndex = EventKindtoListIndex (lSrcEventKind);
+
+ // 既にEOTがある場合、EOTの二重挿入はできない。
+ if (lSrcEventKind == MIDIEVENT_ENDOFTRACK) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pSrcMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_ENDOFTRACK_TO_THIS_TRACK_ANY_MORE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+ }
+ }
+
+ // 新しいイベントの作成
+ pNewMIDIEvent = MIDIEvent_CreateClone (pSrcMIDIEvent);
+ if (pNewMIDIEvent == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INSUFFICIENT_MEMORY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+
+ // ノートイベントで長さ0以下の場合長さは4分音符とする。
+ if (MIDIEvent_IsNoteOn (pNewMIDIEvent) && MIDIEvent_IsNote (pNewMIDIEvent)) {
+ if (MIDIEvent_GetDuration (pNewMIDIEvent) <= 0) {
+ long lNewDur = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ MIDIEvent_SetDuration (pNewMIDIEvent, CLIP (1, lNewDur, 65535));
+ }
+ }
+
+ // 履歴の保持
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_EVENT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pSrcMIDITrack);
+ MIDIEvent* pNewLastEvent = NULL;
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pNewLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ this->ReplaceVisibleEvent (pLastEvent, pNewLastEvent);
+ }
+ }
+
+ // ReplaceEventによるイベント交換が起こったため複写元イベント再設定
+ pSrcMIDIEvent = GetVisibleEvent (lCurRow);
+ pSrcMIDIEvent = MIDIEvent_GetFirstCombinedEvent (pSrcMIDIEvent); // 20100226追加
+ pSrcPrevEvent = GetVisibleEvent (lCurRow - 1);
+ pSrcNextEvent = GetVisibleEvent (lCurRow + 1);
+ lSrcTime = MIDIEvent_GetTime (pSrcMIDIEvent);
+ if (pSrcMIDIEvent) {
+ pSrcMIDITrack = MIDIEvent_GetParent (pSrcMIDIEvent);
+ }
+
+ // 挿入先トラックへ新しいイベントを挿入する
+ if (pSekaijuApp->m_theEventListOption.m_bDuplicateEventAfter) { // 20100226追加
+ lRet = MIDITrack_InsertEventAfter (pSrcMIDITrack, pNewMIDIEvent, pSrcMIDIEvent);
+ }
+ else { // 20100226追加
+ lRet = MIDITrack_InsertEventBefore (pSrcMIDITrack, pNewMIDIEvent, pSrcMIDIEvent);
+ }
+ if (lRet == 0) {
+ MIDIEvent_Delete (pNewMIDIEvent);
+ if (pNewLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewLastEvent));
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_MIDIEVENT_DUPLICATE_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+
+ // 履歴の保持
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewMIDIEvent));
+ if (pNewLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewLastEvent));
+ }
+
+ // 指定したトラックが非表示の場合、表示状態にする。
+ if (IsTrackVisible (lSrcTrackIndex) == FALSE) {
+ this->SetTrackVisible (lSrcTrackIndex);
+ }
+ // 指定したイベントの種類が非表示の場合、表示状態にする。
+ if (IsEventKindVisible (lSrcKindIndex) == FALSE) {
+ this->SetEventKindVisible (lSrcKindIndex);
+ }
+ // ビューの更新
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 行方向スクロール情報の更新
+ this->RecalcRowScrollInfo ();
+ // フォーカスを新しいイベントに合わせる。
+ long lCount = m_theVisibleEventArray.GetSize ();
+ for (i = 0; i < lCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pNewMIDIEvent) {
+ long j = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow = i;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (i, j);
+ return;
+ }
+ }
+ return;
+}
+
+
+// 『ツール(&T)』-『イベントの複写(&D)』
+void CEventListFrame::OnUpdateEventListDuplicateEventUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ long lCount = m_theVisibleEventArray.GetSize ();
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ if (0 <= lCurRow && lCurRow < lCount) {
+ pCmdUI->Enable (TRUE);
+ }
+ else {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+
+// 『ツール(&T)』-『イベントを1行削除(&D)』
+void CEventListFrame::OnEventListDeleteEvent () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ MIDIEvent* pSrcMIDIEvent = NULL;
+ MIDIEvent* pSrcPrevEvent = NULL;
+ MIDIEvent* pSrcPrevPrevEvent = NULL;
+ MIDIEvent* pSrcNextEvent = NULL;
+ MIDIEvent* pSrcNextNextEvent = NULL;
+ long i;
+ long lCount = m_theVisibleEventArray.GetSize ();
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ // 削除するイベントの特定
+ if (0 <= lCurRow && lCurRow < lCount) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ pSrcMIDIEvent = (MIDIEvent*)(m_theVisibleEventArray.GetAt (lCurRow));
+ if (lCurRow >= 1) {
+ pSrcPrevEvent = (MIDIEvent*)(m_theVisibleEventArray.GetAt (lCurRow - 1));
+ }
+ if (lCurRow >= 2) {
+ pSrcPrevPrevEvent = (MIDIEvent*)(m_theVisibleEventArray.GetAt (lCurRow - 2));
+ }
+ if (lCurRow < lCount - 1) {
+ pSrcNextEvent = (MIDIEvent*)(m_theVisibleEventArray.GetAt (lCurRow + 1));
+ }
+ if (lCurRow < lCount - 2) {
+ pSrcNextNextEvent = (MIDIEvent*)(m_theVisibleEventArray.GetAt (lCurRow + 2));
+ }
+ // トラック最後のエンドオブトラックイベントは削除できない。
+ if (MIDIEvent_IsEndofTrack (pSrcMIDIEvent) && MIDIEvent_GetNextEvent (pSrcMIDIEvent) == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_DELETE_THE_LAST_ENDOFTRACK_IN_A_TRACK));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+ // 履歴記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_EVENT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pSrcMIDIEvent));
+
+ // イベントを除去
+ MIDITrack* pSrcMIDITrack = MIDIEvent_GetParent (pSrcMIDIEvent);
+ MIDITrack_RemoveEvent (pSrcMIDITrack, pSrcMIDIEvent);
+ // ビューの更新
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 行方向スクロール情報の更新
+ RecalcRowScrollInfo ();
+ // 直前のイベントにフォーカスを合わせる
+ if (!pSekaijuApp->m_theEventListOption.m_bDeleteEventAfter) {
+ // 前のイベントがあればそれにフォーカスを合わせる。
+ if (pSrcPrevEvent) {
+ lCount = m_theVisibleEventArray.GetSize ();
+ for (i = 0; i < lCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pSrcPrevEvent) {
+ long j = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow = i;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (i, j);
+ return;
+ }
+ }
+ }
+ // 前の前のイベントがあればそれにフォーカスを合わせる。
+ if (pSrcPrevPrevEvent) {
+ lCount = m_theVisibleEventArray.GetSize ();
+ for (i = 0; i < lCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pSrcPrevPrevEvent) {
+ long j = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow = i;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (i, j);
+ return;
+ }
+ }
+ }
+ // 上記のいずれでもない場合、同じインデックスのものにフォーカスを合わせる。
+ }
+ // 直後のイベントにフォーカスを合わせる
+ else {
+ // 次のイベントがあればそれにフォーカスを合わせる。
+ if (pSrcNextEvent) {
+ lCount = m_theVisibleEventArray.GetSize ();
+ for (i = 0; i < lCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pSrcNextEvent) {
+ long j = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow = i;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (i, j);
+ return;
+ }
+ }
+ }
+ // 次の次のイベントがあればそれにフォーカスを合わせる。
+ if (pSrcNextNextEvent) {
+ lCount = m_theVisibleEventArray.GetSize ();
+ for (i = 0; i < lCount; i++) {
+ if (m_theVisibleEventArray.GetAt (i) == pSrcNextNextEvent) {
+ long j = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow = i;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveTextBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->MoveListBox (i, j);
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (i, j);
+ return;
+ }
+ }
+ }
+ // 上記のいずれでもない場合、同じインデックスのものにフォーカスを合わせる。
+ }
+ }
+ // 何もない行は削除できない。
+ else {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CURRENT_MIDIEVENT_IS_EMPTY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ return;
+ }
+}
+
+// 『ツール(&T)』-『イベントを1行削除(&D)』
+void CEventListFrame::OnUpdateEventListDeleteEventUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ MIDIEvent* pMIDIEvent = NULL;
+ long lCount = m_theVisibleEventArray.GetSize ();
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ if (0 <= lCurRow && lCurRow < lCount) {
+ pMIDIEvent = (MIDIEvent*)(m_theVisibleEventArray.GetAt (lCurRow));
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent) && MIDIEvent_GetNextEvent (pMIDIEvent) == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+ else {
+ pCmdUI->Enable (TRUE);
+ }
+ }
+ else {
+ pCmdUI->Enable (FALSE);
+ }
+
+}
+
+
+// 『ツール(&T)』-『現在のトラックのみ表示(&C)』
+void CEventListFrame::OnEventListOnlyCurTrack () {
+ int nCount = m_pTrackListBox->GetCount ();
+ int nCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bOnlyCurTrack) {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ }
+ else {
+ m_bOnlyCurTrack = TRUE;
+ m_bShowAllTrack = FALSE;
+ }
+ for (int i = 0; i < nCount; i++) {
+ m_pTrackListBox->SetCheck (i, IsTrackVisible (i) ? 1 : 0);
+ }
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ツール(&T)』-『現在のトラックのみ表示(&C)』
+void CEventListFrame::OnUpdateEventListOnlyCurTrackUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bOnlyCurTrack);
+}
+
+// 『ツール(&T)』-『全てのトラックを表示(&A)』
+void CEventListFrame::OnEventListShowAllTrack () {
+ int nCount = m_pTrackListBox->GetCount ();
+ int nCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bShowAllTrack) {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ }
+ else {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = TRUE;
+ }
+ for (int i = 0; i < nCount; i++) {
+ m_pTrackListBox->SetCheck (i, IsTrackVisible (i) ? 1 : 0);
+ }
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+
+}
+
+
+// 『ツール(&T)』-『全てのトラックを表示(&A)』
+void CEventListFrame::OnUpdateEventListShowAllTrackUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bShowAllTrack);
+}
+
+// 『ツール(&T)』-『現在のグラフのみ表示(&C)』
+void CEventListFrame::OnEventListOnlyCurEventKind () {
+ int nCount = m_pEventKindListBox->GetCount ();
+ int nCurSel = m_pEventKindListBox->GetCurSel ();
+ if (m_bOnlyCurEventKind) {
+ m_bOnlyCurEventKind = FALSE;
+ m_bShowAllEventKind = FALSE;
+ }
+ else {
+ m_bOnlyCurEventKind = TRUE;
+ m_bShowAllEventKind = FALSE;
+ }
+ for (int i = 0; i < nCount; i++) {
+ m_pEventKindListBox->SetCheck (i, IsEventKindVisible (i) ? 1 : 0);
+ }
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ツール(&T)』-『現在のグラフのみ表示(&C)』
+void CEventListFrame::OnUpdateEventListOnlyCurEventKindUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bOnlyCurEventKind);
+}
+
+
+// 『ツール(&T)』-『全てのグラフを表示(&A)』
+void CEventListFrame::OnEventListShowAllEventKind () {
+ int nCount = m_pEventKindListBox->GetCount ();
+ int nCurSel = m_pEventKindListBox->GetCurSel ();
+ if (m_bShowAllEventKind) {
+ m_bOnlyCurEventKind = FALSE;
+ m_bShowAllEventKind = FALSE;
+ }
+ else {
+ m_bOnlyCurEventKind = FALSE;
+ m_bShowAllEventKind = TRUE;
+ }
+ for (int i = 0; i < nCount; i++) {
+ m_pEventKindListBox->SetCheck (i, IsEventKindVisible (i) ? 1 : 0);
+ }
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+
+}
+
+// 『ツール(&T)』-『全てのグラフを表示(&A)』
+void CEventListFrame::OnUpdateEventListShowAllEventKindUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bShowAllEventKind);
+}
+
+// 『自動ページ更新』
+void CEventListFrame::OnEventListAutoPageUpdate () {
+ m_bAutoPageUpdate = !m_bAutoPageUpdate;
+}
+
+// 『自動ページ更新』
+void CEventListFrame::OnUpdateEventListAutoPageUpdateUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bAutoPageUpdate);
+}
+
+// 『イベントリストをCSV又はテキストで保存』
+void CEventListFrame::OnEventListSaveAs () {
+ CString strFileName;
+ CSekaijuFileDlg theFileDlg (FALSE);
+
+ CString strTitle;
+ VERIFY (strTitle.LoadString (AFX_IDS_APP_TITLE));
+
+ // 注意事項:MSDN2002/4のOPENFILENAME構造体の説明
+ // For compatibility reasons, the Places Bar is hidden if Flags is set to
+ // OFN_ENABLEHOOK and lStructSize is OPENFILENAME_SIZE_VERSION_400.
+ // CFileDialogクラスでは強制的にOFN_ENABLEHOOKでAfxCommDlgProcにフックする。
+
+ // 20081028 : m_ofnの値の設定(76or88)は次による
+ //#ifndef OPENFILENAME_SIZE_VERSION_400
+ // theFileDlg.m_ofn.lStructSize = sizeof(OPENFILENAME); //=76(Windows95/98/ME style)
+ //#else
+ // theFileDlg.m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; //=76(Windows95/98/ME style)
+ //#endif
+
+ #if (_WIN32_WINNT >= 0x0500)
+ theFileDlg.m_ofn.lStructSize = 88; //=88(With placebar)
+ theFileDlg.m_ofn.pvReserved = NULL;
+ theFileDlg.m_ofn.dwReserved = 0;
+ theFileDlg.m_ofn.FlagsEx = 0;
+ #else
+ theFileDlg.m_ofn.lStructSize = 76; //=76(Without placebar if OFN_ENABLEHOOK used)
+ #endif
+
+ theFileDlg.m_ofn.nMaxFileTitle = _MAX_PATH;
+
+ //theFileDlg.m_ofn.Flags |= lFlags;
+
+ CString strFilter;
+ CString strDefault;
+ CString strFilterCSV[3];
+ CString strFilterTXT[3];
+ VERIFY (strFilterCSV[0].LoadString (IDS_COMMA_SEPARATED_TEXT_FILES_AD_CSV));
+ VERIFY (strFilterCSV[1].LoadString (IDS_AD_CSV));
+ VERIFY (strFilterCSV[2].LoadString (IDS_D_CSV));
+ VERIFY (strFilterTXT[0].LoadString (IDS_TAB_SEPARATED_TEXT_FILES_AD_TXT));
+ VERIFY (strFilterTXT[1].LoadString (IDS_AD_TXT));
+ VERIFY (strFilterTXT[2].LoadString (IDS_D_TXT));
+
+ // 拡張子フィルター追加した部分
+ strFilter += strFilterCSV[0]; // カンマ区切りテキストファイル(*.csv)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterCSV[1]; // *.csv
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterTXT[0]; // タブ区切りテキストファイル(*.txt)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterTXT[1]; // *.txt
+ strFilter += (TCHAR)_T('\0');
+ strFilter += (TCHAR)_T('\0');
+ theFileDlg.m_ofn.nMaxCustFilter = 1024;
+
+ theFileDlg.m_ofn.lpstrFilter = strFilter;
+#ifndef _MAC
+ theFileDlg.m_ofn.lpstrTitle = strTitle;
+#else
+ theFileDlg.m_ofn.lpstrPrompt = strTitle;
+#endif
+
+ // デフォルトの拡張子設定
+ theFileDlg.m_strDefExt = strFilterCSV[2];
+ theFileDlg.m_ofn.lpstrDefExt = theFileDlg.m_strDefExt;
+
+ // フィルターコンボボックスのデフォルト選択
+ if ((strFileName.Right (4)).CompareNoCase (strFilterCSV[2]) == 0) { // .csv
+ theFileDlg.m_ofn.nFilterIndex = 1;
+ }
+ else if ((strFileName.Right (4)).CompareNoCase (strFilterTXT[2]) == 0) { // .txt
+ theFileDlg.m_ofn.nFilterIndex = 2;
+ }
+
+ theFileDlg.m_ofn.lpstrFile = strFileName.GetBuffer(_MAX_PATH);
+
+ // ファイルダイアログ.DoModal
+ BOOL bResult = theFileDlg.DoModal() == IDOK ? TRUE : FALSE;
+
+ strFileName.ReleaseBuffer();
+
+ // 拡張子が付いていない場合は、選択したファイルタイプの拡張子を自動的に付ける
+ if (theFileDlg.m_ofn.nFilterIndex == 1 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterCSV[2]) != 0) { // .csv
+ strFileName += strFilterCSV[2];
+ }
+ else if (theFileDlg.m_ofn.nFilterIndex == 2 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterTXT[2]) != 0) { // .txt
+ strFileName += strFilterTXT[2];
+ }
+
+ // キャンセルが押された場合は却下
+ if (bResult == FALSE) {
+ return;
+ }
+
+ // ビューがない場合は却下
+ if (m_pIndexPropertyView == NULL) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CURRENT_VIEW_IS_NOT_EXIST));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ CEventListIndexPropertyView* pIndexPropertyView = (CEventListIndexPropertyView*)m_pIndexPropertyView;
+
+ // 文字列バッファ確保
+ CString strTextLine;
+ CString strCell;
+ CString strSeparator;
+ if (theFileDlg.m_ofn.nFilterIndex == 1) {
+ strSeparator = _T(", ");
+ }
+ else {
+ strSeparator = _T("\t");
+ }
+
+ // ファイルオープン
+ CStdioFile theFile;
+ BOOL bRet = theFile.Open (strFileName, CFile::modeCreate | CFile::modeWrite);
+ if (bRet == FALSE) {
+ CString strMsg;
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_N_FILE_OPEN_FAILED));
+ strMsg.Format (strFormat, strFileName);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // 先頭行の文字列書き込み
+ long i = 0;
+ long j = 0;
+ long jMax = 0;
+ strTextLine.Format (_T(""));
+ strTextLine += strSeparator;
+ for (j = 0; j < 8; j++) {
+ strCell = GetColumnTitle (j);
+ strTextLine += strCell;
+ if (j < 7) {
+ strTextLine += strSeparator;
+ }
+ else {
+ strTextLine += _T("\n");
+ }
+ }
+ theFile.WriteString (strTextLine);
+
+ // 各行の文字列書き込み
+ long lRowCount = GetVisibleEventCount ();
+ for (i = 0; i < lRowCount; i++) {
+ strTextLine.Format (_T("%d"), i + 1);
+ strTextLine += strSeparator;
+ MIDIEvent* pMIDIEvent = GetVisibleEvent (i);
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ jMax = 6;
+ }
+ else {
+ jMax = 8;
+ }
+ for (j = 0; j < jMax; j++) {
+ strCell = pIndexPropertyView->GetCellString (i, j);
+ strTextLine += strCell;
+ if (j < jMax - 1) {
+ strTextLine += strSeparator;
+ }
+ else {
+ strTextLine += _T("\n");
+ }
+ }
+ theFile.WriteString (strTextLine);
+ }
+
+ // ファイルクローズ
+ theFile.Close ();
+}
+
+// 『イベントリストをCSV又はテキストで保存』
+void CEventListFrame::OnUpdateEventListSaveAsUI (CCmdUI* pCmdUI) {
+}
+
+
+
+// トラックコンボボックスが選択され終わった時
+void CEventListFrame::OnTrackComboSelEndOK () {
+ // カレントトラックを更新する
+ long lCurTrackIndex = m_wndEventTrackCombo.GetCurSel ();
+ SetCurTrackIndex (lCurTrackIndex);
+ SetTrackVisible (lCurTrackIndex);
+ // カレントチャンネルも更新する
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // ビューの作り直しと再描画
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+
+}
+
+// トラックインデックスリストのチェックボックスが変化したとき
+void CEventListFrame::OnTrackListChkChange () {
+ // トラックの表示/非表示をチェックボックスの状態に合わせる
+ long lCount = m_pTrackListBox->GetCount ();
+ long lCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bOnlyCurTrack) {
+ m_bOnlyCurTrack = FALSE;
+ }
+ for (long i = 0; i < lCount; i++) {
+ m_bTrackVisible[i] = m_pTrackListBox->GetCheck (i);
+ if (m_bTrackVisible[i] == FALSE) {
+ m_bShowAllTrack = FALSE;
+ }
+ }
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// トラックインデックスの選択項目が変化したとき
+void CEventListFrame::OnTrackListSelChange () {
+ // カレントトラックを変更する
+ long lCurTrackIndex = GetCurTrackIndex ();
+ SetCurTrackIndex (lCurTrackIndex);
+ // カレントチャンネルも更新する
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // ビューの作り直しと再描画
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// グラフの種類コンボボックスが選択され終わった時
+void CEventListFrame::OnEventKindComboSelEndOK () {
+ long lCurEventKind = m_wndEventKindCombo.GetCurSel ();
+ SetCurEventKind (lCurEventKind);
+ SetEventKindVisible (lCurEventKind);
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// グラフの種類リストのチェックボックスが変化したとき
+void CEventListFrame::OnEventKindListChkChange () {
+ // グラフの表示/非表示をチェックボックスの状態に合わせる
+ long lCount = m_pEventKindListBox->GetCount ();
+ long lCurSel = m_pEventKindListBox->GetCurSel ();
+ if (m_bOnlyCurEventKind) {
+ m_bOnlyCurEventKind = FALSE;
+ }
+ //else { // 20110122削除
+ for (long i = 0; i < lCount; i++) {
+ m_bEventKindVisible[i] = m_pEventKindListBox->GetCheck (i);
+ if (m_bEventKindVisible[i] == FALSE) {
+ m_bShowAllEventKind = FALSE;
+ }
+ }
+ //} // 20110122削除
+ MakeVisibleEventArray ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// グラフの種類リストの選択項目が変化したとき
+void CEventListFrame::OnEventKindListSelChange () {
+ // カレントグラフを変更する。
+ long lCurEventKind = GetCurEventKind ();
+ SetCurEventKind (lCurEventKind);
+}
+
+
+// 『ポップアップ』-『このトラックのみ表示ON』
+void CEventListFrame::OnPopupTrackVisibleOn () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ return;
+ }
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lCount = m_pTrackListBox->GetCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, i == lTrackIndex ? 1 : 0);
+ m_bTrackVisible[i] = (i == lTrackIndex ? TRUE : FALSE);
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // カレントトラックとカレントチャンネルを更新
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ // イベントリストの作り直し
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MakeVisibleEventArray ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ポップアップ』-『このトラックのみ表示ON』
+void CEventListFrame::OnUpdatePopupTrackVisibleOnUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『このトラックのみ表示OFF』
+void CEventListFrame::OnPopupTrackVisibleOff () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ return;
+ }
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lCount = m_pTrackListBox->GetCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, i == lTrackIndex ? 0 : 1);
+ m_bTrackVisible[i] = (i == lTrackIndex ? FALSE : TRUE);
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // カレントトラックとカレントチャンネルを更新
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ // イベントリストの作り直し
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MakeVisibleEventArray ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ポップアップ』-『このトラックのみ表示OFF』 // 20100429追加
+void CEventListFrame::OnUpdatePopupTrackVisibleOffUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『全トラック表示ON』
+void CEventListFrame::OnPopupTrackVisibleAll () {
+ long lCount = m_pTrackListBox->GetCount ();
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, 1);
+ m_bTrackVisible[i] = TRUE;
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // イベントリストの作り直し
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MakeVisibleEventArray ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ポップアップ』-『全トラック表示ON』
+void CEventListFrame::OnUpdatePopupTrackVisibleAllUI (CCmdUI* pCmdUI) {
+}
+
+
+// 『ポップアップ』-『このイベントの種類のみ表示ON』
+void CEventListFrame::OnPopupEventKindVisibleOn () {
+ long lListIndex = 0;
+ if (GetFocus () == m_pIndexPropertyView) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lEventKind = MIDIEvent_GetKind (pSekaijuDoc->m_pTempEvent);
+ lListIndex = EventKindtoListIndex (lEventKind);
+ }
+ else if (GetFocus () == m_pEventKindListBox) {
+ lListIndex = ((CEventKindListBox*)m_pEventKindListBox)->GetLastRButtonDownIndex ();
+ }
+ else {
+ return;
+ }
+ long lCount = m_pEventKindListBox->GetCount ();
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pEventKindListBox->SetCheck (i, (i == lListIndex ? 1 : 0));
+ m_bEventKindVisible[i] = (i == lListIndex ? TRUE : FALSE);
+ }
+ if (m_bEventKindVisible[lListIndex]) {
+ m_wndEventKindCombo.SetCurSel (lListIndex);
+ m_pEventKindListBox->SetCurSel (lListIndex);
+ }
+ m_bOnlyCurEventKind = FALSE;
+ m_bShowAllEventKind = FALSE;
+ // イベントリストの作り直し
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MakeVisibleEventArray ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ // 再描画
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ポップアップ』-『このイベントの種類のみ表示ON』
+void CEventListFrame::OnUpdatePopupEventKindVisibleOnUI (CCmdUI* pCmdUI) {
+ if (GetFocus () == m_pIndexPropertyView) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempEvent == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+ }
+}
+
+// 『ポップアップ』-『このイベントの種類のみ表示OFF』
+void CEventListFrame::OnPopupEventKindVisibleOff () {
+ long lListIndex = 0;
+ if (GetFocus () == m_pIndexPropertyView) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lEventKind = MIDIEvent_GetKind (pSekaijuDoc->m_pTempEvent);
+ lListIndex = EventKindtoListIndex (lEventKind);
+ }
+ else if (GetFocus () == m_pEventKindListBox) {
+ lListIndex = ((CEventKindListBox*)m_pEventKindListBox)->GetLastRButtonDownIndex ();
+ }
+ else {
+ return;
+ }
+ long lCount = m_pEventKindListBox->GetCount ();
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pEventKindListBox->SetCheck (i, (i == lListIndex ? 0 : 1));
+ m_bEventKindVisible[i] = (i == lListIndex ? FALSE : TRUE);
+ }
+ if (m_bEventKindVisible[lListIndex]) {
+ m_wndEventKindCombo.SetCurSel (lListIndex);
+ m_pEventKindListBox->SetCurSel (lListIndex);
+ }
+ m_bOnlyCurEventKind = FALSE;
+ m_bShowAllEventKind = FALSE;
+ // イベントリストの作り直し
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MakeVisibleEventArray ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ // 再描画
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ポップアップ』-『このイベントの種類のみ表示OFF』
+void CEventListFrame::OnUpdatePopupEventKindVisibleOffUI (CCmdUI* pCmdUI) {
+ if (GetFocus () == m_pIndexPropertyView) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempEvent == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+ }
+}
+
+// 『ポップアップ』-『全イベントの種類表示ON』
+void CEventListFrame::OnPopupEventKindVisibleAll () {
+ long lCount = m_pEventKindListBox->GetCount ();
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pEventKindListBox->SetCheck (i, 1);
+ m_bEventKindVisible[i] = TRUE;
+ }
+ // イベントリストの作り直し
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MakeVisibleEventArray ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ long lCurColumn = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurColumn;
+ long lCurRow = ((CEventListIndexPropertyView*)m_pIndexPropertyView)->m_lCurRow;
+ ((CEventListIndexPropertyView*)m_pIndexPropertyView)->AutoScrolltoShowCell (lCurRow, lCurColumn);
+ // 再描画
+ m_pIndexScaleView->Invalidate ();
+ m_pIndexPropertyView->Invalidate ();
+}
+
+// 『ポップアップ』-『全イベントの種類表示ON』 // 20100429追加
+void CEventListFrame::OnUpdatePopupEventKindVisibleAllUI (CCmdUI* pCmdUI) {
+}
+
diff --git a/src/EventListIndexPropertyView.cpp b/src/EventListIndexPropertyView.cpp
new file mode 100644
index 0000000..07f8790
--- /dev/null
+++ b/src/EventListIndexPropertyView.cpp
@@ -0,0 +1,4404 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストインデックスプロパティビュークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "common.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "EventListFrame.h"
+#include "EventListIndexPropertyView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+#define IDC_TEXTBOX 3939
+
+IMPLEMENT_DYNCREATE (CEventListIndexPropertyView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEventListIndexPropertyView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_KILLFOCUS ()
+ ON_WM_KEYDOWN ()
+ ON_WM_KEYUP ()
+ ON_WM_CHAR ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventListIndexPropertyView::CEventListIndexPropertyView () {
+ m_lCurRow = 0;
+ m_lCurColumn = 0;
+ m_lCurButtonState = 0x00;
+ m_lCurButtonInterval = 200;
+ m_bSettingCellString = 0;
+}
+
+// デストラクタ
+CEventListIndexPropertyView::~CEventListIndexPropertyView () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// (X,Y)座標からセル番号を取得
+BOOL CEventListIndexPropertyView::GetCellFromPoint
+(CPoint pt, long* pRow, long* pColumn) {
+ _ASSERT (pRow);
+ _ASSERT (pColumn);
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ *pRow = pEventListFrame->YtoRow (pt.y);
+ *pColumn = pEventListFrame->XtoColumn (pt.x);
+ return TRUE;
+}
+
+// 指定セルがビューからはみ出した場合のオートスクロール処理
+BOOL CEventListIndexPropertyView::AutoScrolltoShowCell (long lRow, long lColumn) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ long lNewPos = 0;
+ // 指定セルがビューの左にはみ出した場合の処理
+ if (pEventListFrame->GetColumnLeft (lColumn) < rcClient.left) {
+ lNewPos = pEventListFrame->GetColumnLeft (lColumn);
+ pEventListFrame->SetColumnScrollPos (lNewPos);
+ }
+ // 指定セルがビューの右にはみ出した場合の処理
+ else if (pEventListFrame->GetColumnLeft (lColumn) +
+ pEventListFrame->GetColumnWidth (lColumn) > rcClient.right) {
+ lNewPos = pEventListFrame->GetColumnLeft (lColumn) +
+ pEventListFrame->GetColumnWidth (lColumn) - rcClient.Width ();
+ pEventListFrame->SetColumnScrollPos (lNewPos);
+ }
+ // 指定セルがビューの上にはみ出した場合の処理
+ if (lRow * pEventListFrame->GetRowZoom () < rcClient.top) {
+ lNewPos = lRow * pEventListFrame->GetRowZoom ();
+ pEventListFrame->SetRowScrollPos (lNewPos);
+ }
+ // 指定セルがビューの下にはみ出した場合の処理
+ else if ((lRow + 1) * pEventListFrame->GetRowZoom () > rcClient.bottom) {
+ lNewPos = (lRow + 1) * pEventListFrame->GetRowZoom () - rcClient.Height ();
+ pEventListFrame->SetRowScrollPos (lNewPos);
+ }
+ return TRUE;
+}
+
+// 現在テキストボックスで編集中かどうか返す。
+BOOL CEventListIndexPropertyView::IsTextEditing () {
+ return (m_theTextBox.GetStyle () & WS_VISIBLE) ? TRUE : FALSE;
+}
+
+// 現在リストボックスで選択中かどうか返す。
+BOOL CEventListIndexPropertyView::IsListSelecting () {
+ return (m_theListBox.GetStyle () & WS_VISIBLE) ? TRUE : FALSE;
+}
+
+// テキストボックスでの編集を開始する。
+BOOL CEventListIndexPropertyView::BeginTextEditing () {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ MIDIEvent* pMIDIEvent = NULL;
+ ASSERT (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount);
+ //if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ VERIFY (pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow));
+ //}
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ pSekaijuApp->m_bInplaceEditing = 1;
+ m_theTextBox.SetWindowText (GetCellString (m_lCurRow, m_lCurColumn));
+ m_theTextBox.SetSel (0, -1, TRUE);
+ m_theTextBox.EmptyUndoBuffer ();
+ m_theTextBox.ShowWindow (SW_SHOW);
+ m_theTextBox.SetFocus ();
+ m_theTextBox.UpdateWindow ();
+ return TRUE;
+}
+
+// リストボックスでの編集を開始する。
+BOOL CEventListIndexPropertyView::BeginListSelecting () {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = pEventListFrame->GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pMIDIData->m_pFirstTrack;
+ MIDIEvent* pMIDIEvent = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ pSekaijuApp->m_bInplaceEditing = 1;
+ // トラックの場合
+ if (m_lCurColumn == 0) {
+ long i = 0;
+ TCHAR szText[1024];
+ CString strText;
+ m_theListBox.ResetContent ();
+ forEachTrack (pMIDIData, pMIDITrack) {
+ memset (szText, 0, sizeof (szText));
+ MIDITrack_GetName (pMIDITrack, szText, TSIZEOF (szText) - 1);
+ strText.Format (_T("%d-%s"), i + (bTrackZeroOrigin ? 0 : 1), szText);
+ m_theListBox.AddString (strText);
+ i++;
+ }
+ }
+ // イベントの種類の場合
+ else if (m_lCurColumn == 3) {
+ m_theListBox.ResetContent ();
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x00]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x01]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x02]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x03]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x04]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x05]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x06]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x07]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x08]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x09]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x20]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x21]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x2F]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x51]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x54]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x58]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x59]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x7F]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x80]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0x90]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0xA0]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0xB0]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0xC0]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0xD0]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0xE0]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0xF0]);
+ m_theListBox.AddString (pSekaijuApp->m_strEventKindName[0xF7]);
+ }
+ long i = 0;
+ long lCount = m_theListBox.GetCount ();
+ CString strCurCellString = GetCellString (m_lCurRow, m_lCurColumn);
+ CString strListBoxString;
+ for (i = 0; i < lCount; i++) {
+ m_theListBox.GetText (i, strListBoxString);
+ if (strListBoxString == strCurCellString) {
+ m_theListBox.SetCurSel (i);
+ }
+ }
+ m_theListBox.ShowWindow (SW_SHOW);
+ m_theListBox.SetFocus ();
+ m_theListBox.UpdateWindow ();
+ return TRUE;
+}
+
+
+
+
+// テキストボックスでの編集を終了し、新しい値を格納する。
+BOOL CEventListIndexPropertyView::EndTextEditingOK () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 現在のセルの編集テキストを取得
+ CString strBuf;
+ m_theTextBox.GetWindowText (strBuf);
+ // 値の反映
+ if (SetCellString (m_lCurRow, m_lCurColumn, strBuf)) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews
+ (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ // 編集終了
+ m_theTextBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+// リストボックスでの選択を終了し、新しい値を格納する。
+BOOL CEventListIndexPropertyView::EndListSelectingOK () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 現在のセルの選択テキストを取得
+ int nCurSel = m_theListBox.GetCurSel ();
+ if (nCurSel == LB_ERR) {
+ return FALSE;
+ }
+ CString strText;
+ m_theListBox.GetText (nCurSel, strText);
+ // 値の反映
+ if (SetCellString (m_lCurRow, m_lCurColumn, strText)) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews
+ (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ // 選択終了
+ m_theListBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+
+// テキストボックスでの編集を終了し、新しい値を格納しない。
+BOOL CEventListIndexPropertyView::EndTextEditingCancel () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_theTextBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+// リストボックスでの選択を終了し、新しい値を格納しない。
+BOOL CEventListIndexPropertyView::EndListSelectingCancel () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_theListBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+// 値の増減を開始する
+BOOL CEventListIndexPropertyView::BeginValueUpDown () {
+ _RPTF0 (_CRT_WARN, "BeginValueUpDown\n");
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (m_lCurButtonState == 0x0000);
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pTempTrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_pLastEvent = NULL;
+ m_pCloneEvent = NULL;
+ m_pCloneTrack = NULL;
+ CString strHistoryName;
+ // 現在のイベントとトラックを取得
+ VERIFY (pTempEvent = pEventListFrame->GetVisibleEvent (m_lCurRow));
+ VERIFY (pTempTrack = MIDIEvent_GetParent (pTempEvent));
+ // 項目別に
+ switch (m_lCurColumn) {
+ case 2: // 小節:拍:ティック
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_TIME));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (pLastEvent != pTempEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ VERIFY (pEventListFrame->ReplaceVisibleEvent (pLastEvent, m_pLastEvent));
+ }
+ }
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ VERIFY (pEventListFrame->ReplaceVisibleEvent (pTempEvent, pCloneEvent));
+ break;
+ case 4: // イベントのチャンネル
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_CHANNEL));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ VERIFY (pEventListFrame->ReplaceVisibleEvent (pTempEvent, pCloneEvent));
+ break;
+ case 5: // 値1
+ case 6: // 値2
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ VERIFY (pEventListFrame->ReplaceVisibleEvent (pTempEvent, pCloneEvent));
+ break;
+ case 7: // 値3
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ VERIFY (pEventListFrame->ReplaceVisibleEvent (pLastEvent, m_pLastEvent));
+ }
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ VERIFY (pEventListFrame->ReplaceVisibleEvent (pTempEvent, pCloneEvent));
+ break;
+ }
+ return TRUE;
+}
+
+
+// 値の増減を終了する
+BOOL CEventListIndexPropertyView::EndValueUpDown () {
+ _RPTF0 (_CRT_WARN, "EndValueUpDown\n");
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のイベントとトラックを取得
+ VERIFY (pTempEvent = pEventListFrame->GetVisibleEvent (m_lCurRow));
+ VERIFY (pTempTrack = MIDIEvent_GetParent (pTempEvent));
+ // 履歴記録
+ // 項目別に
+ switch (m_lCurColumn) {
+ case 2: // 小節:拍:ティック
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ if (m_pLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent));
+ }
+ break;
+ case 4: // イベントのチャンネル
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ break;
+ case 5: // 値1
+ case 6: // 値2
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ break;
+ case 7: // 値3
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ if (m_pLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent));
+ }
+ break;
+ }
+ return TRUE;
+}
+
+
+// セルの値を増減させる
+BOOL CEventListIndexPropertyView::AddValueOfCurCell (long lDeltaValue) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ // 現在のトラックへのポインタを取得
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pMIDITrack = NULL;
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ }
+ // 値の反映
+ long lValue = 0;
+ long lNumber = 0;
+ switch (m_lCurColumn) {
+ case 0:
+ return FALSE;
+ case 1:
+ return FALSE;
+ // 小節:拍:ティック
+ case 2:
+ lValue = MIDIEvent_GetTime (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 0x7FFFFFFF);
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ long lNewDuration = CLIP (1, lDuration - lDeltaValue, 65535);
+ MIDIEvent_SetTime (pMIDIEvent, lValue);
+ MIDIEvent_SetDuration (pMIDIEvent, lNewDuration);
+ }
+ else if (MIDIEvent_IsNoteOff (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ MIDIEvent* pNoteOnEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ long lDuration = MIDIEvent_GetDuration (pNoteOnEvent);
+ long lNewDuration = CLIP (1, lDuration + lDeltaValue, 65535);
+ MIDIEvent_SetDuration (pNoteOnEvent, lNewDuration);
+ MIDIEvent_SetTime (pMIDIEvent, lValue);
+ }
+ else {
+ MIDIEvent_SetTime (pMIDIEvent, lValue);
+ }
+ return TRUE;
+ // 種類
+ case 3:
+ return FALSE;
+ // チャンネル
+ case 4:
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ return FALSE;
+ }
+ lValue = MIDIEvent_GetChannel (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 15);
+ MIDIEvent_SetChannel (pMIDIEvent, lValue);
+ return TRUE;
+ // 値1
+ case 5:
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent) ||
+ MIDIEvent_IsKeyAftertouch (pMIDIEvent)) {
+ lValue = MIDIEvent_GetKey (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 127);
+ MIDIEvent_SetKey (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ lValue = MIDIEvent_GetNumber (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 127);
+ MIDIEvent_SetNumber (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ else if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ // パッチサーチONのとき
+ if (pSekaijuApp->m_theGeneralOption.m_bPatchSearch) {
+ long lRet;
+ MIDIEvent* pCC0Event = pSekaijuDoc->FindBankMSB (pMIDIEvent);
+ long lBankMSB = 0;
+ if (pCC0Event) {
+ lBankMSB = MIDIEvent_GetValue (pCC0Event);
+ }
+ MIDIEvent* pCC32Event = pSekaijuDoc->FindBankLSB (pMIDIEvent);
+ long lBankLSB = 0;
+ if (pCC32Event) {
+ lBankLSB = MIDIEvent_GetValue (pCC32Event);
+ }
+ MIDIEvent* pPCEvent = pMIDIEvent;
+ long lProgramChange = 0;
+ if (pPCEvent) {
+ lProgramChange = MIDIEvent_GetNumber (pPCEvent);
+ }
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ MIDIInstrumentDefinition* pMIDIInstDef = lTrackViewMode ?
+ pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort] :
+ pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ // インストゥルメント定義が設定されている場合
+ if (pMIDIInstDef) {
+ MIDIPatchNameTable* pMIDIPatchNameTable = NULL;
+ long lBank = 0;
+ TCHAR szBuf[256];
+ long lNewValue = lValue + (lDeltaValue > 0 ? 1 : -1);
+ long lTempNewValue = lValue; // 最後に音色が見つかった新しい値
+ while (0 <= lNewValue && lNewValue <= 127) {
+ lBank = (lBankMSB << 7) | lBankLSB;
+ // 音色があるか調べる
+ pMIDIPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pMIDIInstDef, lBank);
+ lRet = 0;
+ if (pMIDIPatchNameTable) {
+ lRet = MIDIPatchNameTable_GetName
+ (pMIDIPatchNameTable, lNewValue, szBuf, TSIZEOF (szBuf));
+ }
+ // 音色があった場合
+ if (lRet > 0) {
+ lTempNewValue = lNewValue;
+ if (lNewValue - lValue >= lDeltaValue && lDeltaValue > 0 ||
+ lNewValue - lValue <= lDeltaValue && lDeltaValue < 0) {
+ break;
+ }
+ }
+ lNewValue += (lDeltaValue > 0 ? 1 : -1);
+ }
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lTempNewValue, 127)));
+ }
+ // インストゥルメント定義が設定されていない場合(通常の場合と同じ処理)
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ }
+ // 通常の場合
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ return TRUE;
+ }
+ else if (MIDIEvent_IsChannelAftertouch (pMIDIEvent)) {
+ lValue = MIDIEvent_GetValue (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 127);
+ MIDIEvent_SetValue (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ lValue = MIDIEvent_GetValue (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 16384);
+ MIDIEvent_SetValue (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ return FALSE;
+ // 値2
+ case 6:
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ lValue = MIDIEvent_GetVelocity (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (1, lValue, 127);
+ MIDIEvent_SetVelocity (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ else if (MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ if ((lKind & 0xF0) == 0x80) {
+ lValue = MIDIEvent_GetVelocity (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 127);
+ MIDIEvent_SetVelocity (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ return FALSE;
+ }
+ else if (MIDIEvent_IsKeyAftertouch (pMIDIEvent)) {
+ lValue = MIDIEvent_GetValue (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (0, lValue, 127);
+ MIDIEvent_SetValue (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ // (Bank Select MSB (CC#0) 又は Bank Select LSB (CC#32)) の場合かつパッチサーチONのとき
+ if ((lNumber == 0 || lNumber == 32) && pSekaijuApp->m_theGeneralOption.m_bPatchSearch) {
+ long lRet;
+ MIDIEvent* pCC0Event = pSekaijuDoc->FindBankMSB (pMIDIEvent);
+ long lBankMSB = 0;
+ if (pCC0Event) {
+ lBankMSB = MIDIEvent_GetValue (pCC0Event);
+ }
+ MIDIEvent* pCC32Event = pSekaijuDoc->FindBankLSB (pMIDIEvent);
+ long lBankLSB = 0;
+ if (pCC32Event) {
+ lBankLSB = MIDIEvent_GetValue (pCC32Event);
+ }
+ MIDIEvent* pPCEvent = pSekaijuDoc->FindProgramChange (pMIDIEvent);
+ long lProgramChange = 0;
+ if (pPCEvent) {
+ lProgramChange = MIDIEvent_GetNumber (pPCEvent);
+ }
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ MIDIInstrumentDefinition* pMIDIInstDef = lTrackViewMode ?
+ pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort] :
+ pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ // インストゥルメント定義が設定されている場合
+ if (pMIDIInstDef) {
+ MIDIPatchNameTable* pMIDIPatchNameTable = NULL;
+ long lBank = 0;
+ TCHAR szBuf[256];
+ long lNewValue = lValue + (lDeltaValue > 0 ? 1 : -1);
+ long lTempNewValue = lValue; // 最後に音色が見つかった新しい値
+ while (0 <= lNewValue && lNewValue <= 127) {
+ if (lNumber == 0) {
+ lBank = (lNewValue << 7) | lBankLSB;
+ }
+ else if (lNumber == 32) {
+ lBank = (lBankMSB << 7) | lNewValue;
+ }
+ // 音色があるか調べる
+ pMIDIPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pMIDIInstDef, lBank);
+ lRet = 0;
+ if (pMIDIPatchNameTable) {
+ lRet = MIDIPatchNameTable_GetName
+ (pMIDIPatchNameTable, lProgramChange, szBuf, TSIZEOF (szBuf));
+ }
+ // 音色があった場合
+ if (lRet > 0) {
+ lTempNewValue = lNewValue;
+ if (lNewValue - lValue >= lDeltaValue && lDeltaValue > 0 ||
+ lNewValue - lValue <= lDeltaValue && lDeltaValue < 0) {
+ break;
+ }
+ }
+ lNewValue += (lDeltaValue > 0 ? 1 : -1);
+ }
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lTempNewValue, 127)));
+ }
+ // インストゥルメント定義が設定されていない場合(通常の場合と同じ処理)
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ }
+ // 通常の場合
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ return TRUE;
+ }
+ return FALSE;
+ // 値3
+ case 7:
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ lValue = MIDIEvent_GetDuration (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (1, lValue, 65535);
+ MIDIEvent_SetDuration (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ else if (MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ lValue = MIDIEvent_GetDuration (pMIDIEvent) + lDeltaValue;
+ lValue = CLIP (-65535, lValue, -1);
+ MIDIEvent_SetDuration (pMIDIEvent, lValue);
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+
+
+// セルの文字列を取得する
+CString CEventListIndexPropertyView::GetCellString (long lRow, long lColumn) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (lRow < 0 || lRow >= pEventListFrame->GetVisibleEventCount ()) {
+ return _T("");
+ }
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (lRow);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode = 0;
+ long lTimeResolution = 120;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ MIDIClock* pMIDIClock = pSekaijuDoc->m_pMIDIClock;
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent) && lColumn > 5) {
+ lColumn = 5;
+ }
+ CString strText;
+ TCHAR szBuf1[2048];
+ TCHAR szBuf2[2048];
+ switch (lColumn) {
+ // トラック
+ case 0:
+ memset (szBuf1, 0, sizeof (szBuf1));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ MIDITrack_GetName (pMIDITrack, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, TSIZEOF (szBuf2) - 1);
+ strText.Format (_T("%d-%s"),
+ pSekaijuDoc->GetTrackIndex (pMIDITrack) + (bTrackZeroOrigin ? 0 : 1), szBuf2);
+ break;
+ // 時:分:秒:ミリ秒
+ case 1:
+ VERIFY (pSekaijuDoc->LongTimeToStringMillisec (pSekaijuDoc->m_pMIDIData, lTime, &strText));
+ break;
+ // 小節:拍:ティック 又は フレーム番号:ティック
+ case 2:
+ VERIFY (pSekaijuDoc->LongTimeToStringTime (pSekaijuDoc->m_pMIDIData, lTime, &strText));
+ break;
+ // イベントの種類
+ case 3:
+ strText = pSekaijuApp->m_strEventKindName[lKind];
+ break;
+ // チャンネル(MIDIチャンネルイベントの場合のみ。その他はn/a)。
+ case 4:
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ strText.Format (_T("%3d"), MIDIEvent_GetChannel (pMIDIEvent) + 1);
+ }
+ else {
+ strText = _T("n/a");
+ }
+ break;
+ // 値1
+ case 5:
+ // シーケンス番号
+ if (MIDIEvent_IsSequenceNumber (pMIDIEvent)) {
+ strText.Format (_T("%d"), MIDIEvent_GetNumber (pMIDIEvent));
+ }
+ // テキスト系イベント
+ else if (0x01 <= lKind && lKind <= 0x1F) {
+ TCHAR szBuf1[2048];
+ TCHAR szBuf2[2048];
+ memset (szBuf1, 0, sizeof (szBuf1));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ MIDIEvent_GetText (pMIDIEvent, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, TSIZEOF (szBuf2) - 1);
+ strText = szBuf2;
+ }
+ // チャンネルプリフィックス,ポートプリフィックス
+ else if (MIDIEvent_IsChannelPrefix (pMIDIEvent) ||
+ MIDIEvent_IsPortPrefix (pMIDIEvent)) {
+ strText.Format (_T("%d"), MIDIEvent_GetNumber (pMIDIEvent) + 1);
+ }
+ // エンドオブトラック
+ else if (MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ strText = _T("");
+ }
+ // テンポイベント
+ else if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo;
+ double dBPM;
+ lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ dBPM = (double)60000000 / (double)lTempo;
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_1P2LF_BPM_EQ_D_MICROSEC_PER_QUARTER_NOTE));
+ strText.Format (strFormat, dBPM, lTempo);
+ }
+ // SMPTEオフセット
+ else if (MIDIEvent_IsSMPTEOffset (pMIDIEvent)) {
+ CString strMode[5];
+ VERIFY (strMode[0].LoadString (IDS_24));
+ VERIFY (strMode[1].LoadString (IDS_25));
+ VERIFY (strMode[2].LoadString (IDS_29P97));
+ VERIFY (strMode[3].LoadString (IDS_30));
+ VERIFY (strMode[4].LoadString (IDS_ERROR));
+ long lMode, lHour, lMinute, lSec, lFrame, lSubFrame;
+ MIDIEvent_GetSMPTEOffset (pMIDIEvent, &lMode, &lHour, &lMinute, &lSec, &lFrame, &lSubFrame);
+ if (lMode < 0 || lMode > 4) {
+ lMode = 4;
+ }
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_FPS_D_HOUR_D_MINUTE_D_SEC_D_FRAME_D_SUBFRAME));
+ strText.Format (strFormat,
+ strMode[lMode], lHour, lMinute, lSec, lFrame, lSubFrame);
+ }
+ // 拍子記号
+ else if (lKind == MIDIEVENT_TIMESIGNATURE) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_PER_D_D_CLOCK_PER_BEAT_D_32DIVNOTE_PER_BEAT));
+ strText.Format (strFormat, lnn, 1 << ldd, lcc, lbb);
+ }
+ // 調性記号
+ else if (lKind == MIDIEVENT_KEYSIGNATURE) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ CString strSF; // "#"又は"b"
+ CString strMi; // "major"又は"minor"
+ CString strKeySignatureName;
+ // 長調
+ if (lmi == 0) {
+ if (0 <= lsf && lsf < 8) {
+ VERIFY (strSF.LoadString (IDS_SHARP));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MA + lsf ));
+ }
+ else if (-8 <= lsf && lsf < 0) {
+ VERIFY (strSF.LoadString (IDS_FLAT));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MA + 16 + lsf));
+ }
+ VERIFY (strMi.LoadString (IDS_MAJOR));
+ }
+ // 短調
+ else {
+ if (0 <= lsf && lsf < 8) {
+ VERIFY (strSF.LoadString (IDS_SHARP));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MI + lsf ));
+ }
+ else if (-8 <= lsf && lsf < 0) {
+ VERIFY (strSF.LoadString (IDS_FLAT));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MI + 16 + lsf));
+ }
+ VERIFY (strMi.LoadString (IDS_MINOR));
+ }
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_S_S_EQ_S));
+ strText.Format (strFormat, abs (lsf), strSF, strMi, strKeySignatureName);
+ }
+ // ノートオフ・ノートオン・キーアフタータッチ
+ else if (0x80 <= lKind && lKind <= 0xAF) {
+ long lKey = MIDIEvent_GetKey (pMIDIEvent);
+ CString strKeyName;
+ strKeyName = pSekaijuDoc->GetKeyName (pMIDITrack, lTime, lKey);
+ strText.Format (_T("%d-%s"), lKey, strKeyName);
+ }
+ // コントロールチェンジ
+ else if (0xB0 <= lKind && lKind <= 0xBF) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ long lChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ if (0 <= lTrackOutputChannel && lTrackOutputChannel < 16) {
+ lChannel = lTrackOutputChannel;
+ }
+ MIDIInstrumentDefinition* pMIDIInstDef = NULL;
+ // このトラックの表示モードは「通常」の場合
+ if (lTrackViewMode == 0) {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ }
+ // このトラックの表示モードは「ドラム」の場合
+ else {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort];
+ }
+ // このトラックの指定するポートのインストゥルメント定義が見つかった
+ if (pMIDIInstDef) {
+ MIDIControllerNameTable* pControllerNameTable =
+ MIDIInstrumentDefinition_GetControllerNameTable (pMIDIInstDef);
+ // このインストゥルメント定義はControllerNameTableを持っている
+ if (pControllerNameTable) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIControllerNameTable_GetName (pControllerNameTable, lNumber, szBuf, 255);
+ strText.Format (_T("%d-%s"), lNumber, szBuf);
+ }
+ // このインストゥルメント定義はControllerNameTableを持っていない
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // こトラックの指定するポートのインストゥルメント定義がなかった
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // プログラムチェンジ
+ else if (0xC0 <= lKind && lKind <= 0xCF) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ long lChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ if (0 <= lTrackOutputChannel && lTrackOutputChannel < 16) {
+ lChannel = lTrackOutputChannel;
+ }
+ MIDIInstrumentDefinition* pMIDIInstDef = NULL;
+ // このトラックの表示モードは「通常」の場合
+ if (lTrackViewMode == 0) {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ }
+ // このトラックの表示モードは「ドラム」の場合
+ else {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort];
+ }
+ // このトラックの指定するポートのインストゥルメント定義が見つかった
+ if (pMIDIInstDef) {
+ long lBankMSB = MIDIEvent_GetBankMSB (pMIDIEvent);
+ long lBankLSB = MIDIEvent_GetBankLSB (pMIDIEvent);
+ long lBank = (lBankMSB << 7) | lBankLSB;
+ MIDIPatchNameTable* pPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pMIDIInstDef, lBank);
+ // このインストゥルメント定義は指定バンクのPatchNameTableを持っている
+ if (pPatchNameTable) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIPatchNameTable_GetName (pPatchNameTable, lNumber, szBuf, 255);
+ strText.Format (_T("%d-%s"), lNumber, szBuf);
+ }
+ // このインストゥルメント定義は指定バンクのPatchNameTableを持っていない
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // こトラックの指定するポートのインストゥルメント定義がなかった
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // チャンネルアフタータッチ
+ else if (0xD0 <= lKind && lKind <= 0xDF) {
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ strText.Format (_T("%d"), lValue);
+ }
+ // ピッチベンド
+ else if (0xE0 <= lKind && lKind <= 0xEF) {
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ strText.Format (_T("%d"), lValue - 8192);
+ }
+ // その他のイベント(16進ダンプ)
+ else {
+ BYTE byBin[1024];
+ TCHAR szText[1024];
+ memset (byBin, 0, sizeof (byBin));
+ memset (szText, 0, sizeof (szText));
+ MIDIEvent_GetData (pMIDIEvent, byBin, 1024);
+ bin2txt (byBin, MIDIEvent_GetLen (pMIDIEvent), szText, 1023);
+ strText = szText;
+ }
+ break;
+ // 値2
+ case 6:
+ // ノート
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ strText.Format (_T("%d"), MIDIEvent_GetVelocity (pMIDIEvent));
+ }
+ // キーアフタータッチ・コントロールチェンジ
+ else if (0xA0 <= lKind && lKind <= 0xBF) {
+ strText.Format (_T("%d"), MIDIEvent_GetValue (pMIDIEvent));
+ }
+ // その他
+ else {
+ strText.Format (_T("---"));
+ }
+ break;
+ // 値3
+ case 7:
+ // ノート
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ strText.Format (_T("%d"), MIDIEvent_GetDuration (pMIDIEvent));
+ }
+ // その他
+ else {
+ strText.Format (_T("---"));
+ }
+ break;
+ }
+ return strText;
+}
+
+// セルに文字列を設定(不正な文字列の場合はFALSEを返し設定しない)
+BOOL CEventListIndexPropertyView::SetCellString (long lRow, long lColumn, CString strText) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (lRow < 0 || lRow >= pEventListFrame->GetVisibleEventCount ()) {
+ return FALSE;
+ }
+ m_bSettingCellString = 1;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (lRow);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ MIDITrack* pNewMIDITrack = NULL;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ MIDIClock* pMIDIClock = pSekaijuDoc->m_pMIDIClock;
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent) && lColumn > 5) {
+ lColumn = 5;
+ }
+ //CString strMsg;
+ CString strToken;
+ CString strHistoryName;
+ long lNumTrack = MIDIData_CountTrack (pMIDIData);
+ long lValue = 0;
+ long lTemp = 0;
+ long i = 0;
+ MIDIEvent* pCloneEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ m_pLastEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ switch (lColumn) {
+ // トラック
+ case 0:
+ // トラック文字チェック
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_TRACK_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // トラック範囲チェック
+ lValue = _ttol (strText) - (bTrackZeroOrigin ? 0 : 1);
+ if (lValue < 0 || lValue >= lNumTrack) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_TRACK_VALUE_IS_OUT_OF_RANGE));
+ //strMsg.Format ("トラック番号は%d以上%d以下の半角整数を入力してください。",
+ // (bTrackZeroOrigin ? 0 : 1), lNumTrack + (bTrackZeroOrigin ? 0 : 1) - 1);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // フォーマット1の場合、
+ // テンポ・SMPTEオフセット・拍子記号・調性記号はトラックは2番目以降のトラックに置けない。
+ if (MIDIData_GetFormat (pMIDIData) == 1 && lValue != 0 &&
+ (MIDIEvent_IsTempo (pMIDIEvent) || MIDIEvent_IsSMPTEOffset (pMIDIEvent) ||
+ MIDIEvent_IsTimeSignature (pMIDIEvent) || MIDIEvent_IsKeySignature (pMIDIEvent))) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_THIS_EVENT_TO_THE_SECOND_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // フォーマット1の場合、
+ // MIDIチャンネルイベントはトラックは最初のトラックに置けない。
+ if (MIDIData_GetFormat (pMIDIData) == 1 && lValue == 0 &&
+ MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_THIS_EVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent) && MIDIEvent_GetNextEvent (pMIDIEvent) == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MOVE_THE_LAST_ENDOFTRACK_TO_THE_OTHER_TRACK));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ pNewMIDITrack = pSekaijuDoc->GetTrack (lValue);
+ if (pNewMIDITrack == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_MODIFY_EVENT_TRACK_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ if (pEventListFrame->IsTrackVisible (lValue) == FALSE) {
+ pEventListFrame->SetTrackVisible (lValue);
+ }
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_TRACK));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent));
+
+ pLastEvent = MIDITrack_GetLastEvent (pNewMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ VERIFY (MIDITrack_InsertEvent (pNewMIDITrack, pMIDIEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pMIDIEvent));
+ if (m_pLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent));
+ }
+ return TRUE;
+ // 時:分:秒:ミリ秒
+ case 1:
+ m_bSettingCellString = 0;
+ return FALSE;
+ // 小節:拍:ティック
+ case 2:
+ lValue = 0;
+ lTemp = pSekaijuDoc->StringTimeToLongTime (pSekaijuDoc->m_pMIDIData, strText, &lValue);
+ if (lTemp > 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lTemp));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_TIME));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (pLastEvent != pMIDIEvent) { // 20090712追加
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ if (m_pLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent));
+ }
+ return TRUE;
+ // イベントの種類
+ case 3:
+ // トラック最後のエンドオブトラックイベントが変更されるのを阻止
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent) &&
+ pMIDITrack->m_pLastEvent == pMIDIEvent) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MODIFY_THE_LAST_ENDOFTRADK));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 一致する名前のイベントの種類を探索
+ for (i = 0; i < 255; i++) {
+ if (strText == pSekaijuApp->m_strEventKindName[i]) {
+ break;
+ }
+ }
+ // イベントの種類iに一致した
+ if (0 <= i && i < 255) {
+ MIDITrack* pFirstTrack = MIDIData_GetFirstTrack (pMIDIData);
+ // MIDIチャンネルイベントの場合はチャンネル情報無視
+ if (0x80 <= i && i <= 0xEF) {
+ i &= 0xF0;
+ }
+ // ノートオフの場合は強制的にノートオン+ノートオフとする。
+ if (0x80 <= i && i <= 0x8F) {
+ i = MIDIEVENT_NOTEONNOTEOFF;
+ }
+ // ノートオンの場合は強制的にノートオン+ノートオン0とする。
+ else if (0x90 <= i && i <= 0x9F) {
+ i = MIDIEVENT_NOTEONNOTEON0;
+ }
+ // SMFフォーマット1でトラック0以外に
+ // テンポ、SMPTEオフセット、拍子、調性が入るのを防止
+ if (MIDIData_GetFormat (pMIDIData) == 1 && (pMIDITrack != pFirstTrack) &&
+ (i == 0x51 || i == 0x54 || i == 0x58 || i == 0x59)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_ARE_YOU_SURE_TO_MOVE_THIS_EVENT_TO_THE_FIRST_TRACK));
+ int nRet = AfxMessageBox (strMsg, MB_ICONINFORMATION | MB_YESNOCANCEL);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ // 自動的に最初のトラックに移動しない
+ if (nRet != IDYES) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_FAILED_TO_MODIFY_EVENT_KIND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 自動的に最初のトラックに移動する
+ else {
+ long lListIndex = pEventListFrame->EventKindtoListIndex (i);
+ if (pEventListFrame->IsEventKindVisible (lListIndex) == FALSE) {
+ pEventListFrame->SetEventKindVisible (lListIndex);
+ }
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_KIND));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ VERIFY (pEventListFrame->ReplaceVisibleEvent (pLastEvent, m_pLastEvent));
+ }
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pCloneEvent));
+ VERIFY (MIDIEvent_SetKind (pCloneEvent, i));
+ VERIFY (MIDITrack_InsertEvent (pFirstTrack, pCloneEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ if (m_pLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent));
+ }
+ }
+ }
+ // SMFフォーマット1でトラック0にMIDIチャンネルイベントが入るのを防止
+ else if (MIDIData_GetFormat (pMIDIData) == 1 && (pMIDITrack == pFirstTrack) &&
+ (0x80 <= i && i <= 0xEF || i == MIDIEVENT_NOTEONNOTEOFF ||
+ i == MIDIEVENT_NOTEONNOTEON0)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_THIS_EVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 異物イベントでない場合許可。
+ else {
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_KIND));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent_SetKind (pCloneEvent, i);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // 一致するイベントの種類はなかった
+ else {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNEXPECTED_EVENT_KIND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ break;
+ // チャンネル
+ case 4:
+ // MIDIチャンネルイベント以外の場合はチャンネルを設定できない
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SPECIFIY_EVENT_CHANNEL_OF_THIS_EVENT));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // チャンネル文字チェック
+ strText.TrimLeft ();
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CHANNEL_MUST_BE_HALF_WIDTH_NUMBER_FROM_1_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // チャンネル値チェック
+ lValue = _ttol (strText);
+ if (lValue <= 0 || lValue > 16) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CHANNEL_MUST_BE_HALF_WIDTH_NUMBER_FROM_1_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // チャンネル変更
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT_CHANNEL));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetChannel (pCloneEvent, lValue - 1));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ // 値1
+ case 5:
+ // シーケンス番号イベント
+ if (MIDIEvent_IsSequenceNumber (pMIDIEvent)) {
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_SEQUENCENUMBER_MUST_BE_HALF_WIDTH_NUMBER_FROM_0_TO_65535));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (0, lValue, 65535);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_SEQUENCENUMBER_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetNumber (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // テキスト系イベント
+ else if (0x01 <= lKind && lKind <= 0x1F) {
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_TEXTEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)strText, strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ VERIFY (MIDIEvent_SetText (pCloneEvent, szBuf2) >= 0);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // チャンネルプリフィックス
+ else if (MIDIEvent_IsChannelPrefix (pMIDIEvent)) {
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CHANNELPREFIX_MUST_BE_HALF_WIDTH_NUMBER_FROM_1_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (1, lValue, 16);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_CHANNELPREFIX_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetNumber (pCloneEvent, lValue - 1));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // ポートプリフィックス
+ else if (MIDIEvent_IsPortPrefix (pMIDIEvent)) {
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_PORTPREFIX_MUST_BE_HALF_WIDTH_NUMBER_FROM_0_TO_255));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (0, lValue, 255);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_PORTPREFIX_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetNumber (pCloneEvent, lValue - 1));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // エンドオブトラック
+ else if (MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_ENDOFTRACK_HAS_NO_VALUE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // テンポイベント
+ else if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lCurTime, lMillisec;
+ double dTemp;
+#ifdef UNICODE
+ dTemp = _wtol (strText); // TODO:VC++4.0で_ttofが使えないので仮
+#else
+ dTemp = atof (strText);
+#endif
+ dTemp = CLIP (1, dTemp, 60000);
+ lValue = (long)((60000000 / dTemp));
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_TEMPO_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetTempo (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ // TODO:MIDIClockがランニング中は一時停止
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ lCurTime = MIDIClock_GetTickCount (pMIDIClock);
+ lMillisec = MIDIData_TimeToMillisec (pMIDIData, lCurTime);
+ MIDIClock_SetMillisec (pMIDIClock, lMillisec);
+ MIDIData_FindTempo (pMIDIData, lTime, &lValue);
+ MIDIClock_SetTempo (pMIDIClock, lValue);
+ // TODO:MIDIClockのランニング状態を復帰
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // SMPTEオフセット
+ else if (MIDIEvent_IsSMPTEOffset (pMIDIEvent)) {
+ long lMaxFrame[4] = {23, 24, 29, 29};
+ long lMode, lHour, lMinute, lSec, lFrame, lSubFrame;
+ // FPSとフレームの間のセパレータ
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // FPS
+ strToken = strText.Left (lTemp);
+ if (strToken.Left (2) == _T("24")) {
+ lMode = 0;
+ }
+ else if (strToken.Left (2) == _T("25")) {
+ lMode = 1;
+ }
+ else if (strToken.Left (5) == _T("29.97")) {
+ lMode = 2;
+ }
+ else if (strToken.Left (2) == _T("30")) {
+ lMode = 3;
+ }
+ else {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_FPS_MUST_BE_24_OR_25_OR_29P97_OR_30));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // フレームと時の間のセパレータ
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 時
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_HOUR_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lHour = _ttol (strText);
+ lHour = CLIP (0, lHour, 23);
+ // 時と分の間のセパレータ
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 分
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_MINUTE_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lMinute = _ttol (strText);
+ lMinute = CLIP (0, lMinute, 59);
+ // 分と秒の間のセパレータ
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 秒
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_SECOND_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lSec = _ttol (strText);
+ lSec = CLIP (0, lSec, 59);
+ // 秒とフレームの間のセパレータ
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // フレーム
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_FRAME_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lFrame = _ttol (strText);
+ lFrame = CLIP (0, lFrame, lMaxFrame[lMode]);
+ // フレームとサブフレームの間のセパレータ
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // サブフレーム
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ lSubFrame = _ttol (strText);
+ lSubFrame = CLIP (0, lSubFrame, 99);
+ // SMPTEオフセットの設定
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_SMPTEOFFSET_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetSMPTEOffset
+ (pCloneEvent, lMode, lHour, lMinute, lSec, lFrame, lSubFrame));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // 拍子記号
+ else if (lKind == MIDIEVENT_TIMESIGNATURE) {
+ long lnn, ldd, lcc, lbb;
+ // 分子と分母の間のセパレータ
+ lTemp = strText.Find (_T("/"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_BETWEEN_NUMERATOR_AND_DENOMINATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 分子
+ strToken = strText.Left (lTemp);
+ if (IsNumeric (strToken) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_NUMERATOR_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lnn = _ttol (strToken);
+ lnn = CLIP (1, lnn, 127);
+ // 分母との間のセパレータ
+ strText = strText.Mid (lTemp + 1);
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 分母
+ strToken = strText.Left (lTemp);
+ if (IsNumeric (strToken) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_DENOMINATOR_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ ldd = _ttol (strToken);
+ //if (ldd != 1 && ldd != 2 && ldd != 4 && ldd != 8 && ldd != 16 && ldd != 32) {
+ // return FALSE;
+ //}
+ switch (ldd) {
+ case 1:
+ ldd = 0;
+ break;
+ case 2:
+ ldd = 1;
+ break;
+ case 4:
+ ldd = 2;
+ break;
+ case 8:
+ ldd = 3;
+ break;
+ case 16:
+ ldd = 4;
+ break;
+ case 32:
+ ldd = 5;
+ break;
+ default:
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_DENOMINATOR_MUST_BE_1_OR_2_OR_4_OR_8_OR_16_OR_32));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // [クロック/拍]と[32分音符/拍]の間のセパレータ
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_A_SEPARATOR_IS_NOT_FOUND));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 1拍あたりのクロック数[クロック/拍]
+ strToken = strText.Left (lTemp);
+ if (IsNumeric (strToken) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CLOCKSPERBEAT_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lcc = _ttol (strToken);
+ lcc = CLIP (1, lcc, 127);
+ // 1拍あたりの32分音符の数[32分音符/拍]
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ if (IsNumeric (strText) <= 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_32DIVNOTEPERBEAT_MUST_BE_HALF_WIDTH_NUMBER));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lbb = _ttol (strText);
+ lbb = CLIP (1, lbb, 127);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_TIMESIGNATURE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetTimeSignature (pCloneEvent, lnn, ldd, lcc, lbb));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // 調性記号
+ else if (lKind == MIDIEVENT_KEYSIGNATURE) {
+ long lsf, lmi;
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // #又はbの数
+ strToken = strText.Left (lTemp);
+ strToken.TrimLeft ();
+ strToken.TrimRight ();
+ TCHAR* szTemp[15] = {_T("7b"), _T("6b"), _T("5b"), _T("4b"), _T("3b"), _T("2b"), _T("1b"),
+ _T("0"), _T("1#"), _T("2#"), _T("3#"), _T("4#"), _T("5#"), _T("6#"), _T("7#")};
+ for (i = 0; i < 15; i++) {
+ if (_tcscmp ((LPCTSTR)strToken, szTemp[i]) == 0) {
+ break;
+ }
+ }
+ if (_tcscmp ((LPCTSTR)strToken, _T("0b")) == 0 ||
+ _tcscmp ((LPCTSTR)strToken, _T("0#")) == 0) {
+ i = 7;
+ }
+ if (i >= 15) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_KEYSIGNATURE_MUST_BE_7B_6B_5B_4B_3B_2B_1B_0_1S_2S_3S_4S_5S_6S_7S));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lsf = (long)(char)(i - 7);
+ // "major"又は"minor"
+ strText = strText.Mid (lTemp + 1);
+ strText.TrimLeft ();
+ CString strMajor;
+ CString strMinor;
+ VERIFY (strMajor.LoadString (IDS_MAJOR));
+ VERIFY (strMinor.LoadString (IDS_MINOR));
+ if (_tcsnccmp ((LPCTSTR)strText, (LPCTSTR)strMajor, strMajor.GetLength ()) == 0) {
+ lmi = 0;
+ }
+ else if (_tcsnccmp ((LPCTSTR)strText, (LPCTSTR)strMinor, strMinor.GetLength ()) == 0) {
+ lmi = 1;
+ }
+ else {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_KEYSCALE_MUST_BE_MAJOR_OR_MINOR));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_KEYSIGNATURE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetKeySignature (pCloneEvent, lsf, lmi));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ return TRUE;
+ }
+ // シーケンサ固有のイベント
+ else if (MIDIEvent_IsSequencerSpecific (pMIDIEvent)) {
+ BYTE byData[1024];
+ memset (byData, 0, sizeof (byData));
+ long lRet = txt2bin ((TCHAR*)(LPCTSTR)strText, 1023, byData, 1024);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_SEQUENCERSPECIFIC));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetData (pCloneEvent, byData, lRet) >= 0);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // ノート・キーアフタータッチ
+ else if (0x80 <= lKind && lKind <= 0xAF) {
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (0, lValue, 127);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetKey (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // コントロールチェンジ・プログラムチェンジ
+ else if (0xB0 <= lKind && lKind <= 0xCF) {
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (0, lValue, 127);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ (MIDIEvent_SetNumber (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // チャンネルアフタータッチ
+ else if (0xD0 <= lKind && lKind <= 0xDF) {
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (0, lValue, 127);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetValue (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // ピッチベンド
+ else if (0xE0 <= lKind && lKind <= 0xEF) {
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText) + 8192;
+ lValue = CLIP (0, lValue, 16383);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetValue (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // システムエクスクルーシブ(通常)
+ else if (lKind == 0xF0) {
+ BYTE byData[1024];
+ memset (byData, 0, sizeof (byData));
+ long lRet = txt2bin ((TCHAR*)(LPCTSTR)strText, 1023, byData, 1024);
+ if (byData[0] != 0xF0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_SYSEX_DATA_MUST_BEGIN_WITH_F0));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ for (long j = 1; j < lRet - 1; j++) { // 20080809訂正
+ if (byData[j] >= 0x80) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_SYSEX_DATA_BETWEE_F0_AND_F7_MUST_BE_FROM_00_TO_7F));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ }
+ if (byData[lRet - 1] != 0xF7) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_SYSEX_DATA_MUST_END_WITH_F7));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_SYSEX_NORMAL));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetData (pCloneEvent, byData, lRet) >= 0);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // システムエクスクルーシヴ(任意)
+ else if (lKind == 0xF7) {
+ BYTE byData[1024];
+ memset (byData, 0, sizeof (byData));
+ long lRet = txt2bin ((TCHAR*)(LPCTSTR)strText, 1023, byData, 1024);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_SYSEX_ARBITRARY));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetData (pCloneEvent, byData, lRet) >= 0);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // その他のイベント(16進ダンプ)
+ else {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MODIFY_UNDEFINED_EVENT));
+ AfxMessageBox (strMsg);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ break;
+ // 値2
+ case 6:
+ // ノートオフ・ノートオン
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (0, lValue, 127);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetVelocity (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // キーアフタータッチ・コントロールチェンジ
+ else if (0xA0 <= lKind && lKind <= 0xBF) {
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (0, lValue, 127);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetValue (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // その他
+ else {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ break;
+ // 値3
+ case 7:
+ // ノートオフ
+ if (0x80 <= lKind && lKind <= 0x8F) {
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ lValue = CLIP (-65535, lValue, 0);
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetDuration (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ if (m_pLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent));
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // ノートオン
+ else if (0x90 <= lKind && lKind <= 0x9F) {
+ long lVelocity = MIDIEvent_GetVelocity (pMIDIEvent);
+ if (IsNumeric (strText) <= 0) {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ // ノートオフ
+ if (lVelocity == 0) {
+ lValue = CLIP (-65535, lValue, 0);
+ }
+ // ノートオン
+ else {
+ lValue = CLIP (0, lValue, 65535);
+ }
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDIEVENT_VALUE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDIEvent_SetDuration (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ if (m_pLastEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent));
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+ }
+ // その他
+ else {
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ break;
+ }
+ m_bSettingCellString = 0;
+ return FALSE;
+}
+
+int CEventListIndexPropertyView::DrawCurFrame (CDC* pDC) {
+ CRect rcCurFrame = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcCurFrame.left -= 1;
+ rcCurFrame.right -= 1;
+ rcCurFrame.top -= 1;
+ rcCurFrame.bottom -= 1;
+ CPen thePen (PS_SOLID, 3, RGB (0, 0, 0));
+ CPen* pOldPen = pDC->SelectObject (&thePen);
+ int nOldDrawMode = pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (rcCurFrame.left, rcCurFrame.top);
+ pDC->LineTo (rcCurFrame.left, rcCurFrame.bottom);
+ pDC->LineTo (rcCurFrame.right, rcCurFrame.bottom);
+ pDC->LineTo (rcCurFrame.right, rcCurFrame.top);
+ pDC->LineTo (rcCurFrame.left, rcCurFrame.top);
+ pDC->SetROP2 (nOldDrawMode);
+ pDC->SelectObject (pOldPen);
+ return 1;
+}
+
+
+
+
+
+
+// セルの長方形を取得
+CRect CEventListIndexPropertyView::GetRectFromCell (long lRow, long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ BOOL bCombined = FALSE; // 列5〜7が結合している場合TRUE;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ // 列5〜7のセルの結合判定
+ if (0 <= lRow && lRow < lVisibleEventCount) {
+ if (lColumn >= 5) {
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (lRow);
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ bCombined = TRUE;
+ }
+ }
+ }
+ else {
+ bCombined = TRUE;
+ }
+ // セル矩形の計算
+ CRect rcCell (0, 0, 0 ,0);
+ if (bCombined && lColumn >= 5) {
+ rcCell.left = pEventListFrame->GetColumnLeft (5);
+ rcCell.right = rcCell.left + pEventListFrame->GetColumnWidth (5) +
+ pEventListFrame->GetColumnWidth (6) + pEventListFrame->GetColumnWidth (7);
+ }
+ else {
+ rcCell.left = pEventListFrame->GetColumnLeft (lColumn);
+ rcCell.right = rcCell.left + pEventListFrame->GetColumnWidth (lColumn);
+ }
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ rcCell.top = lRow * lRowZoom;
+ rcCell.bottom = (lRow + 1) * lRowZoom;
+ ASSERT (rcCell.left < rcCell.right);
+ ASSERT (rcCell.top < rcCell.bottom);
+ return rcCell;
+}
+
+// テキストボックスの移動(VISIBLE==FALSE時含む)
+BOOL CEventListIndexPropertyView::MoveTextBox (long lRow, long lColumn) {
+ ASSERT (0 <= lRow && lRow <= 0x7FFFFFFF);
+ ASSERT (0 <= lColumn && lColumn < 8);
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ long lButtonWidth = 12; //::GetSystemMetrics (SM_CXVSCROLL);
+ CRect rcNewCell = GetRectFromCell (lRow, lColumn);
+ rcNewCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ m_theTextBox.MoveWindow
+ (rcNewCell.left, rcNewCell.top + pEventListFrame->GetRowZoom () / 2 - 6,
+ rcNewCell.Width () - (lColumn >= 0 ? lButtonWidth : 1), 13);
+ return TRUE;
+}
+
+// リストボックスの移動(VISIBLE==FALSE時含む)
+BOOL CEventListIndexPropertyView::MoveListBox (long lRow, long lColumn) {
+ ASSERT (0 <= lRow && lRow <= 0x7FFFFFFF);
+ ASSERT (0 <= lColumn && lColumn < 8);
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ m_theListBox.MoveWindow
+ (rcNewCell.left, rcNewCell.bottom,
+ rcNewCell.Width (), rcNewCell.Height () + 64);
+ return TRUE;
+}
+
+// ツールバーのコントロール更新
+BOOL CEventListIndexPropertyView::UpdateParentToolbarControl () {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)GetDocument ();
+ CString strText;
+ long lIndex;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (m_lCurRow < 0 || m_lCurRow >= lVisibleEventCount) {
+ return FALSE;
+ }
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ if (pMIDIEvent == NULL) {
+ return FALSE;
+ }
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ long lEventKind = MIDIEvent_GetKind (pMIDIEvent);
+ //switch (m_lCurColumn) {
+ // トラックコンボ更新
+ //case 0:
+ lIndex = pSekaijuDoc->GetTrackIndex (pMIDITrack);
+ pEventListFrame->m_wndEventTrackCombo.SetCurSel (lIndex);
+ pEventListFrame->m_pTrackListBox->SetCurSel (lIndex);
+ // break;
+ // イベントの時刻エディット更新
+ //case 1:
+ //case 2:
+ strText = GetCellString (m_lCurRow, 2);
+ pEventListFrame->m_wndEventTimeEdit.SetWindowText (strText);
+ // break;
+ // イベントの種類コンボ更新
+ //case 3:
+ if (0 <= lEventKind && lEventKind < 256) {
+ lIndex = pEventListFrame->EventKindtoListIndex (lEventKind);
+ pEventListFrame->m_wndEventKindCombo.SetCurSel (lIndex);
+ pEventListFrame->m_pEventKindListBox->SetCurSel (lIndex);
+ }
+ // break;
+ // イベントのチャンネルコンボ更新
+ //case 4:
+ strText = GetCellString (m_lCurRow, 4);
+ if (strText == _T("n/a")) {
+ pEventListFrame->m_wndEventChannelCombo.SetCurSel (0);
+ }
+ else {
+ lIndex = _ttol (strText);
+ if (1 <= lIndex && lIndex <= 16) {
+ pEventListFrame->m_wndEventChannelCombo.SetCurSel (lIndex);
+ }
+ }
+ // break;
+ //}
+ return TRUE;
+}
+
+// ポップアップメニューの表示
+BOOL CEventListIndexPropertyView::ShowPopupMenu (CPoint ptMenu) {
+
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (m_lCurButtonState == 0x0000);
+
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ if (pMIDIEvent) {
+ pSekaijuDoc->m_lTempTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuDoc->m_pTempTrack = MIDIEvent_GetParent (pMIDIEvent);
+ pSekaijuDoc->m_pTempEvent = pMIDIEvent;
+ }
+ else {
+ pSekaijuDoc->m_lTempTime = pSekaijuDoc->m_lNewTime;
+ pSekaijuDoc->m_pTempTrack = NULL;
+ pSekaijuDoc->m_pTempEvent = NULL;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU21));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pEventListFrame);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lCurButtonState = 0x0000;
+
+ return TRUE;
+}
+
+
+
+
+
+
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CEventListIndexPropertyView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ pDC->SetWindowOrg (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+}
+
+// 描画
+void CEventListIndexPropertyView::OnDraw (CDC* pDC) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // クリティカルセクションロック
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (),pEventListFrame->GetRowScrollPos ());
+
+ int i, j;
+ long lButtonWidth = 12; //::GetSystemMetrics (SM_CXVSCROLL);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorGrayText = ::GetSysColor (COLOR_GRAYTEXT);
+
+ // 背景の塗りつぶし
+ long lVisibleTopRow = pEventListFrame->GetVisibleTopRow ();
+ long lVisibleBottomRow = pEventListFrame->GetVisibleBottomRow ();
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ long lBackColor = pSekaijuApp->m_theColorOption.m_lBackColor[i % 2];
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (i);
+ if (pMIDIEvent) {
+ if (!MIDIEvent_IsFloating (pMIDIEvent)) {
+ long lNormalColor = pSekaijuApp->m_theColorOption.m_lBackColor[i % 2];
+ long lSelectedColor =
+ (CLIP (0x00, ((lNormalColor >> 16) & 0xFF) - 0x00, 0xFF) << 16) |
+ (CLIP (0x00, ((lNormalColor >> 8) & 0xFF) - 0x20, 0xFF) << 8) |
+ (CLIP (0x00, ((lNormalColor >> 0) & 0xFF) - 0x20, 0xFF) << 0);
+ // 選択されているイベントの場合
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent)) {
+ lBackColor = lSelectedColor;
+ }
+ // 選択されていないイベントの場合
+ else {
+ lBackColor = lNormalColor;
+ }
+ }
+ }
+ long y = i * lRowZoom;
+ pDC->FillSolidRect (rcClient.left, y, rcClient.right, y + lRowZoom, lBackColor);
+ }
+
+ // 横線の描画(各行の下に線)
+ CPen penIndex (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen* pOldPen = pDC->SelectObject (&penIndex);
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ long y = (i + 1) * lRowZoom - 1;
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // 縦線の描画(各列の右に線)
+ CPen penColumn (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ pOldPen = pDC->SelectObject (&penColumn);
+ long x = 0;
+ long lColumnZoom = pEventListFrame->GetColumnZoom ();
+ for (j = 0; j < 8; j++) {
+ x += pEventListFrame->GetColumnBaseWidth (j) * lColumnZoom;
+ if (j == 5 || j == 6) {
+ continue;
+ }
+ pDC->MoveTo (x - 1, rcClient.top);
+ pDC->LineTo (x - 1, rcClient.bottom);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // 文字の描画
+ CRect rcCell;
+ CRect rcText;
+ CString strText;
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (pEventListFrame->GetParentFont ());
+ long lVisibleEventCount =pEventListFrame->GetVisibleEventCount ();
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ // テキストカラーの設定
+ long lForeColor = RGB (255, 255, 255);
+ if (0 <= i && i < lVisibleEventCount) {
+ VERIFY (pMIDIEvent = pEventListFrame->GetVisibleEvent (i));
+ }
+ if (pMIDIEvent) {
+ // TODO:MIDIイベントが差し替えられているがまだUpdateAllViewsされてない場合の回避措置
+ if (MIDIEvent_IsFloating (pMIDIEvent)) {
+ continue;
+ }
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ pDC->SetTextColor (lForeColor);
+ }
+ // トラック名
+ rcCell = GetRectFromCell (i, 0);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ _ASSERT (15 <= rcText.Height () && rcText.Height () <= 32);
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 0);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ // 時:分:秒:ミリ秒
+ rcCell = GetRectFromCell (i, 1);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 1);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ // 小節:拍:ティック
+ rcCell = GetRectFromCell (i, 2);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 2);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ // イベントの種類
+ rcCell = GetRectFromCell (i, 3);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 3);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ // チャンネル
+ rcCell = GetRectFromCell (i, 4);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 4);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ // 値1
+ rcCell = GetRectFromCell (i, 5);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 5);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ // 値2, 値3
+ if (pMIDIEvent) {
+ long lEventKind = MIDIEvent_GetKind (pMIDIEvent);
+ if (0x80 <= lEventKind && lEventKind <= 0xEF) {
+ rcCell = GetRectFromCell (i, 6);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ strText = GetCellString (i, 6);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+ rcCell = GetRectFromCell (i, 7);
+ rcText = rcCell;
+ rcText.right -= lButtonWidth;
+ strText = GetCellString (i, 7);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+ }
+ }
+ }
+ pDC->SelectObject (pOldFont);
+
+
+ // ボタン類の描画
+ CPen penColorBtnText (PS_SOLID, 1, lColorBtnText);
+ CPen penColorGrayText (PS_SOLID, 1, lColorGrayText);
+ CBrush brsColorBtnText;
+ CBrush brsColorGrayText;
+ brsColorBtnText.CreateSolidBrush (lColorBtnText);
+ brsColorGrayText.CreateSolidBrush (lColorGrayText);
+ CBrush* pOldBrush = NULL;
+ CRect rcButton;
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (i);
+ long jMax;
+ if (pMIDIEvent) {
+ jMax = MIDIEvent_IsMIDIEvent (pMIDIEvent) ? 8 : 6;
+ }
+ else {
+ jMax = 6;
+ }
+ for (j = 0; j < jMax; j++) {
+ // 上下ボタンかドロップダウンかの判定
+ BOOL bDropDown = FALSE;
+ if (j == 0 || j == 3) {
+ bDropDown = TRUE;
+ }
+ // ▲▼の色を決めるペンの選択
+ if (pMIDIEvent) {
+ if (j == 1 ||
+ j >= 4 && !MIDIEvent_IsMIDIEvent (pMIDIEvent) ||
+ j == 7 && MIDIEvent_IsKeyAftertouch (pMIDIEvent) ||
+ j == 7 && MIDIEvent_IsControlChange (pMIDIEvent) ||
+ j >= 6 && MIDIEvent_IsProgramChange (pMIDIEvent) ||
+ j >= 6 && MIDIEvent_IsChannelAftertouch (pMIDIEvent) ||
+ j >= 6 && MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ //continue;
+ pOldPen = pDC->SelectObject (&penColorGrayText);
+ pOldBrush = pDC->SelectObject (&brsColorGrayText);
+
+ }
+ else {
+ pOldPen = pDC->SelectObject (&penColorBtnText);
+ pOldBrush = pDC->SelectObject (&brsColorBtnText);
+ }
+ }
+ else {
+ //continue;
+ pOldPen = pDC->SelectObject (&penColorGrayText);
+ pOldBrush = pDC->SelectObject (&brsColorGrayText);
+ }
+ rcCell = GetRectFromCell (i, j);
+ rcButton = rcCell;
+ POINT pt[3];
+ // ドロップダウンボタンの場合
+ if (bDropDown) {
+ rcButton.left = rcCell.right - lButtonWidth;
+ pDC->FillSolidRect (&rcButton, ::GetSysColor (COLOR_3DFACE));
+ if (i == m_lCurRow && j == m_lCurColumn && (m_lCurButtonState & 0x0F)) {
+ pDC->Draw3dRect (&rcButton, lColorBtnShadow, lColorBtnHighlight);
+ }
+ else {
+ pDC->Draw3dRect (&rcButton, lColorBtnHighlight, lColorBtnShadow);
+ }
+ pt[0].x = rcCell.right - lButtonWidth / 2;
+ pt[0].y = rcCell.top + lRowZoom * 1 / 2 + 1;
+ pt[1].x = pt[0].x - 2;
+ pt[1].y = pt[0].y - 2;
+ pt[2].x = pt[0].x + 2;
+ pt[2].y = pt[0].y - 2;
+ pDC->Polygon (pt, 3);
+ }
+ // 上下ボタンの場合
+ else {
+ // 上ボタン
+ rcButton.left = rcCell.right - lButtonWidth;
+ rcButton.bottom = rcCell.top + lRowZoom / 2;
+ pDC->FillSolidRect (&rcButton, ::GetSysColor (COLOR_3DFACE));
+ if (i == m_lCurRow && j == m_lCurColumn && (m_lCurButtonState & 0x01) == 0x01) {
+ pDC->Draw3dRect (&rcButton, lColorBtnShadow, lColorBtnHighlight);
+ }
+ else {
+ pDC->Draw3dRect (&rcButton, lColorBtnHighlight, lColorBtnShadow);
+ }
+ pt[0].x = rcCell.right - lButtonWidth / 2;
+ pt[0].y = rcCell.top + lRowZoom * 1 / 4 - 1;
+ pt[1].x = pt[0].x - 2;
+ pt[1].y = pt[0].y + 2;
+ pt[2].x = pt[0].x + 2;
+ pt[2].y = pt[0].y + 2;
+ pDC->Polygon (pt, 3);
+ // 下ボタン
+ rcButton.top = rcCell.top + lRowZoom / 2;
+ rcButton.bottom = rcCell.bottom;
+ pDC->FillSolidRect (&rcButton, ::GetSysColor (COLOR_3DFACE));
+ if (i == m_lCurRow && j == m_lCurColumn && (m_lCurButtonState & 0x02) == 0x02) {
+ pDC->Draw3dRect (&rcButton, lColorBtnShadow, lColorBtnHighlight);
+ }
+ else {
+ pDC->Draw3dRect (&rcButton, lColorBtnHighlight, lColorBtnShadow);
+ }
+ pt[0].x = rcCell.right - lButtonWidth / 2;
+ pt[0].y = rcCell.top + lRowZoom * 3 / 4 + 1;
+ pt[1].x = pt[0].x - 2;
+ pt[1].y = pt[0].y - 2;
+ pt[2].x = pt[0].x + 2;
+ pt[2].y = pt[0].y - 2;
+ pDC->Polygon (pt, 3);
+ }
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+ }
+ }
+
+ // カレントセルの枠描画
+ DrawCurFrame (pDC);
+
+ // クリティカルセクションロック解除
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+
+}
+
+// ビューの更新
+void CEventListIndexPropertyView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ PostMessage (WM_TIMER, 0x11, NULL);
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+//#define CN_COMMAND 0 // void ()
+//#define CN_UPDATE_COMMAND_UI ((UINT)(-1)) // void (CCmdUI*)
+//#define CN_EVENT ((UINT)(-2)) // OLE event
+
+// コマンドルーティングのオーバーライド
+BOOL CEventListIndexPropertyView::OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {
+ // 注意:pHandlerInfo==NULLの時はコマンドを実行し、NULLでないときは
+ // コマンドは実行せずpHandlerInfoの中身を設定することを意味する。
+ if (nCode == CN_COMMAND && pHandlerInfo == NULL) {
+ // キーボードが操作中又はマウスが操作中の場合
+ if (m_lCurButtonState & 0x0FF0) {
+ }
+ }
+ return CView::OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CEventListIndexPropertyView::OnCreate (LPCREATESTRUCT lpcs) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ m_theTextBox.Create (WS_CHILD | ES_AUTOHSCROLL,
+ CRect (0, pEventListFrame->GetRowZoom () / 2 - 6, pEventListFrame->GetColumnWidth (0), 13),
+ this, IDC_TEXTBOX);
+ m_theTextBox.SetFont (pEventListFrame->GetParentFont ());
+ m_theListBox.Create (WS_CHILD | WS_VSCROLL | LBS_NOTIFY,
+ CRect (0, 0, 0, 0), this, IDC_TEXTBOX);
+ m_theListBox.SetFont (pEventListFrame->GetParentFont ());
+
+ SetTimer (0x11, 55, NULL);
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// ウィンドウ破壊時
+void CEventListIndexPropertyView::OnDestroy () {
+ KillTimer (0x11);
+}
+
+// フォーカスを失ったとき
+void CEventListIndexPropertyView::OnKillFocus (CWnd* pNewWnd) {
+ _RPTF1 (_CRT_WARN, "CEventListIndexPropertyView::OnKillFocus (pNewWnd=0x%08x)\n", (long)pNewWnd);
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ // インプレーステキストボックス又はインプレースリストボックスにフォーカスが移った場合を除き
+ if (pNewWnd != &m_theTextBox && pNewWnd != &m_theListBox && !m_bSettingCellString) {
+ // テキスト編集中の場合はその内容を確定
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews
+ (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ // リスト選択中の場合はその内容を確定
+ if (IsListSelecting ()) {
+ EndListSelectingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews
+ (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CView::OnKillFocus (pNewWnd);
+}
+
+// キー押し下げ時
+void CEventListIndexPropertyView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+
+ CString strText;
+ // 古いセルの描画(具体的にはセル枠の削除)(20100128:ちらつき防止のため条件式追加)
+ if (IsTextEditing () == FALSE && IsListSelecting () == FALSE
+ && nChar != VK_CONTROL && nChar != VK_SHIFT && nChar != VK_MENU) {
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+ }
+
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ long lVisibleRows = 0;
+
+ // 該当行のMIDIイベントを取得
+ MIDIEvent* pMIDIEvent = NULL;
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+ long lKind = 0;
+ if (pMIDIEvent) {
+ lKind = MIDIEvent_GetKind (pMIDIEvent);
+ }
+
+ switch (nChar) {
+ // 上キー
+ case VK_UP:
+ // テキストボックス編集中の場合は編集内容を確定し、このビューにフォーカスを移す。
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ m_lCurButtonState = 0x0000;
+ // カレントセルをひとつ上へ移動
+ m_lCurRow = CLIP (0, m_lCurRow - 1, 0x7FFFFFFF);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ // 停止中の場合、現在のセルのイベント時刻を再生時刻とする
+ if (pSekaijuApp->m_bPlaying == FALSE) {
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ if (pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ }
+ }
+ break;
+ // 下キー
+ case VK_DOWN:
+ // テキストボックス編集中の場合は編集内容を確定し、このビューにフォーカスを移す。
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ m_lCurButtonState = 0x0000;
+ // カレントセルをひとつ下へ移動
+ m_lCurRow = CLIP (0, m_lCurRow + 1, lVisibleEventCount);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ // 停止中の場合、現在のセルのイベント時刻を再生時刻とする
+ if (pSekaijuApp->m_bPlaying == FALSE) {
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ if (pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ }
+ }
+ break;
+ // PageUp
+ case VK_PRIOR:
+ // テキストボックス編集中の場合は編集内容を確定し、このビューにフォーカスを移す。
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ m_lCurButtonState = 0x0000;
+ // カレントセルを1ページ上へ移動
+ lVisibleRows = pEventListFrame->GetVisibleBottomRow () - pEventListFrame->GetVisibleTopRow ();
+ m_lCurRow = CLIP (0, m_lCurRow - __max (1, lVisibleRows), 0x7FFFFFFF);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ // 停止中の場合、現在のセルのイベント時刻を再生時刻とする
+ if (pSekaijuApp->m_bPlaying == FALSE) {
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ if (pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ }
+ }
+ break;
+ // PageDown
+ case VK_NEXT:
+ // テキストボックス編集中の場合は編集内容を確定し、このビューにフォーカスを移す。
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ m_lCurButtonState = 0x0000;
+ // カレントセルを1ページ下へ移動
+ lVisibleRows = pEventListFrame->GetVisibleBottomRow () - pEventListFrame->GetVisibleTopRow ();
+ m_lCurRow = CLIP (0, m_lCurRow + __max (1, lVisibleRows), lVisibleEventCount);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ // 停止中の場合、現在のセルのイベント時刻を再生時刻とする
+ if (pSekaijuApp->m_bPlaying == FALSE) {
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ if (pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ }
+ }
+ break;
+ // 左キー
+ case VK_LEFT:
+ // テキストボックス編集中の場合は編集内容を確定し、このビューにフォーカスを移す。
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ m_lCurButtonState = 0x0000;
+ // カレントセルを左へ移動
+ m_lCurColumn = CLIP (0, m_lCurColumn - 1, 7);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ UpdateParentToolbarControl ();
+ break;
+ // 右キー
+ case VK_RIGHT:
+ // テキストボックス編集中の場合は編集内容を確定し、このビューにフォーカスを移す。
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ m_lCurButtonState = 0x0000;
+ // カレントセルを右へ移動
+ m_lCurColumn = CLIP (0, m_lCurColumn + 1, 7);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ UpdateParentToolbarControl ();
+ break;
+ // 改行(Enter)キー
+ case VK_RETURN:
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ m_lCurButtonState = 0x0000;
+ // テキスト編集中でなく、かつリスト選択中でない場合、
+ // そのセルの編集又はリストからの選択を開始する。
+ if (IsTextEditing () == FALSE && IsListSelecting () == FALSE) {
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+
+ // リアルタイム入力中は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+
+ MIDIEvent* pMIDIEvent = NULL;
+ lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+ else {
+ break;
+ }
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ switch (m_lCurColumn) {
+ case 0: // トラック
+ BeginListSelecting ();
+ break;
+ case 2: // タイム
+ BeginTextEditing ();
+ break;
+ case 3: // イベントの種類
+ BeginListSelecting ();
+ break;
+ case 4: // チャンネル(MIDIチャンネルイベントの場合のみ)
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ BeginTextEditing ();
+ }
+ break;
+ case 5: // 値1
+ if (!MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ BeginTextEditing ();
+ }
+ break;
+ case 6: // 値2
+ if (!MIDIEvent_IsEndofTrack (pMIDIEvent) && !(0xC0 <= lKind && lKind <= 0xEF)) {
+ BeginTextEditing ();
+ }
+ break;
+ case 7: // 値3
+ if (!MIDIEvent_IsEndofTrack (pMIDIEvent) && 0x80 <= lKind && lKind <= 0x9F) {
+ BeginTextEditing ();
+ }
+ break;
+ }
+ }
+ // テキスト編集中の場合、テキスト編集を確定終了する(CInplaceEditクラスからPostMessageされる。)
+ else if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ }
+ // リスト選択中の場合、リスト選択を確定終了する(CInplaceListクラスからPostMessageされる。)
+ else if (IsListSelecting ()) {
+ EndListSelectingOK ();
+ }
+ break;
+ // エスケープ(Esc)キー(CInplaceEditクラスからPostMessageされる。)
+ case VK_ESCAPE:
+ // テキスト編集中の場合、テキスト編集をキャンセル終了する(CInplaceEditクラスからPostMessageされる。)
+ if (IsTextEditing ()) {
+ EndTextEditingCancel ();
+ }
+ // リスト選択中の場合、リスト選択をキャンセル終了する(CInplaceListクラスからPostMessageされる。)
+ else if (IsListSelecting ()) {
+ EndListSelectingCancel ();
+ }
+ break;
+ // +キー
+ case VK_ADD:
+ case 187:
+ // 既にマウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ // Ctrlが押されている場合はズームアップ
+ if (GetCapture () == NULL && GetKeyState (VK_CONTROL) < 0) {
+ pEventListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ }
+ // 通常の場合
+ else {
+ // リアルタイム入力中は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ switch (m_lCurColumn) {
+ case 2:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // 初回押し時のみキーボード操作開始
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ SetCapture ();
+ m_lCurButtonState |= 0x0101;
+ }
+ // 値の増減
+ if (::GetKeyState (VK_SHIFT) < 0) {
+ if (m_lCurColumn == 5 && 0x80 <= lKind && lKind <= 0xAF) {
+ AddValueOfCurCell (12);
+ }
+ else {
+ AddValueOfCurCell (10);
+ }
+ }
+ else {
+ AddValueOfCurCell (1);
+ }
+ break;
+ }
+ }
+ break;
+ // -キー
+ case VK_SUBTRACT:
+ case 189:
+ // 既にマウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ // Ctrlが押されている場合はズームダウン
+ if (GetCapture () == NULL && GetKeyState (VK_CONTROL) < 0) {
+ pEventListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ }
+ // 通常の場合
+ else {
+ // リアルタイム入力中は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ switch (m_lCurColumn) {
+ case 2:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ // 初回押し時のみキーボード操作開始
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ SetCapture ();
+ m_lCurButtonState |= 0x0202;
+ }
+ // 値の増減
+ if (::GetKeyState (VK_SHIFT) < 0) {
+ if (m_lCurColumn == 5 && 0x80 <= lKind && lKind <= 0xAF) {
+ AddValueOfCurCell (-12);
+ }
+ else {
+ AddValueOfCurCell (-10);
+ }
+ }
+ else {
+ AddValueOfCurCell (-1);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ // 新しいセルの描画(20100128:ちらつき防止のため条件式追加)
+ if (IsTextEditing () == FALSE && IsListSelecting () == FALSE
+ && nChar != VK_CONTROL && nChar != VK_SHIFT && nChar != VK_MENU) {
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// キー押し上げ時
+void CEventListIndexPropertyView::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ switch (nChar) {
+ // +キー
+ case VK_ADD:
+ case 187:
+ // キーボードで操作中の場合
+ if (m_lCurButtonState & 0x0F00) {
+ // +キー操作のみ停止
+ m_lCurButtonState &= ~0x0101;
+ // もはや何の操作も行われていないならば
+ if (m_lCurButtonState == 0x0000) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ // -キー
+ case VK_SUBTRACT:
+ case 189:
+ // キーボードで操作中の場合
+ if (m_lCurButtonState & 0x0F00) {
+ // -キー操作のみ停止
+ m_lCurButtonState &= ~0x0202;
+ // もはや何の操作も行われていないならば
+ if (m_lCurButtonState == 0x0000) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+
+// 文字直接入力時
+void CEventListIndexPropertyView::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ MIDIEvent* pMIDIEvent = NULL;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+ else {
+ return;
+ }
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+
+ switch (m_lCurColumn) {
+ case 0: // トラック
+ return;
+ case 2: // 小節:拍:ティック
+ if (48 <= nChar && nChar <= 57) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ return;
+ case 3: // イベントの種類
+ return;
+ case 4: // チャンネル(MIDIチャンネルイベントのときのみ)
+ if (0x80 <= lKind && lKind <= 0xEF && 48 <= nChar && nChar <= 57) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ return;
+ case 5: // 値1
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ }
+ else if (!MIDIEvent_IsMIDIEvent (pMIDIEvent) && 33 <= nChar && nChar <= 126) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ else if (48 <= nChar && nChar <=57) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ return;
+ case 6: // 値2
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ }
+ else if (!MIDIEvent_IsMIDIEvent (pMIDIEvent) && 33 <= nChar && nChar <= 126) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ else if (0x80 <= lKind && lKind <= 0xBF && 48 <= nChar && nChar <= 57) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ return;
+ case 7: // 値3
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ }
+ else if (!MIDIEvent_IsMIDIEvent (pMIDIEvent) && 33 <= nChar && nChar <= 126) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ else if (0x80 <= lKind && lKind <= 0x9F && 48 <= nChar && nChar <= 57) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ return;
+ }
+}
+
+
+// マウス左ボタン押された時
+void CEventListIndexPropertyView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ point += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+
+ BOOL bOldTextEditing = FALSE;
+ BOOL bOldListSelecting = FALSE;
+ long lButtonWidth = 12; //::GetSystemMetrics (SM_CXVSCROLL);
+ // テキスト編集の終了
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ bOldTextEditing = TRUE;
+ }
+
+ // リスト選択終了
+ if (IsListSelecting ()) {
+ EndListSelectingCancel ();
+ m_lCurButtonState = 0x0000;
+ bOldListSelecting = TRUE;
+ }
+
+ // 古いセルの描画
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+
+ // 新しいセルの設定(欄外をクリックした場合は何も起こらないで終了)
+ if (m_lCurButtonState == 0x0000) {
+ long i = 0;
+ long j = 0;
+ GetCellFromPoint (point, &i, &j);
+ if (0 <= i && i <= 0x7FFFFFFF && 0 <= j && j < 8) {
+ m_lCurRow = i;
+ m_lCurColumn = j;
+ }
+ else {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ return;
+ }
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ }
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ // 該当行のMIDIイベントを取得
+ MIDIEvent* pMIDIEvent = NULL;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+
+ // MIDIイベントのある行の場合のみ
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ if (pMIDIEvent) {
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ // 列とイベントによりリスト選択開始又は値の増減開始
+ switch (m_lCurColumn) {
+ case 0: // トラック
+ case 3: // イベントの種類
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ if (point.x > rcNewCell.right - lButtonWidth && bOldListSelecting == FALSE) {
+ m_lCurButtonState = 0x0003;
+ BeginListSelecting ();
+ }
+ break;
+ case 2: // 小節:拍:ティック
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0011;
+ AddValueOfCurCell (1);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0012;
+ AddValueOfCurCell (-1);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0010;
+ }
+ }
+ break;
+ case 4: // チャンネル(MIDIチャンネルイベントの場合のみ)
+ if (0x80 <= lKind && lKind <= 0xEF) {
+ if (point.x > rcNewCell.right - 10) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0011;
+ AddValueOfCurCell (1);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0012;
+ AddValueOfCurCell (-1);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0010;
+ }
+ }
+ }
+ break;
+ case 5: // 値1
+ if (0x80 <= lKind && lKind <= 0xEF) {
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0011;
+ AddValueOfCurCell (1);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0012;
+ AddValueOfCurCell (-1);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0010;
+ }
+ }
+ }
+ break;
+ case 6: // 値2
+ if (0x80 <= lKind && lKind <= 0xBF) {
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0011;
+ AddValueOfCurCell (1);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0012;
+ AddValueOfCurCell (-1);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0010;
+ }
+ }
+ }
+ break;
+ case 7: // 値3
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0011;
+ AddValueOfCurCell (1);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0012;
+ AddValueOfCurCell (-1);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0010;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ // 停止中の場合、現在のセルのイベント時刻を再生時刻とする
+ if (pSekaijuApp->m_bPlaying == FALSE) {
+ MIDIEvent* pMIDIEvent = NULL;
+ lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+ if (pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ }
+ }
+
+ // 新しいセルの描画
+ rcNewCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell, FALSE);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CEventListIndexPropertyView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CPoint ptMenu = point;
+ ClientToScreen (&ptMenu);
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ point += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+
+ BOOL bOldTextEditing = FALSE;
+ BOOL bOldListSelecting = FALSE;
+ long lButtonWidth = 12; //::GetSystemMetrics (SM_CXVSCROLL);
+ // テキスト編集の終了
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ m_lCurButtonState = 0x0000;
+ bOldTextEditing = TRUE;
+ }
+
+ // リスト選択終了
+ if (IsListSelecting ()) {
+ EndListSelectingCancel ();
+ m_lCurButtonState = 0x0000;
+ bOldListSelecting = TRUE;
+ }
+
+ // 古いセルの描画
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+
+ // 新しいセルの設定
+ if (m_lCurButtonState == 0x0000) {
+ long i = 0;
+ long j = 0;
+ GetCellFromPoint (point, &i, &j);
+ if (0 <= i && i <= 0x7FFFFFFF && 0 <= j && j < 8) {
+ m_lCurRow = i;
+ m_lCurColumn = j;
+ }
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ }
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ // 該当行のMIDIイベントを取得
+ MIDIEvent* pMIDIEvent = NULL;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+
+ // MIDIイベントのある行の場合のみ
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ if (pMIDIEvent) {
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ // 列とイベントによりリスト選択開始又は値の増減開始
+ switch (m_lCurColumn) {
+ case 0: // トラック
+ case 1: // 時:分:秒:ミリ秒
+ ShowPopupMenu (ptMenu);
+ break;
+ case 3: // イベントの種類
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ m_lCurButtonState = 0x03;
+ BeginListSelecting ();
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ break;
+ case 2: // 小節:拍:ティック
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0021;
+ AddValueOfCurCell (10);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0022;
+ AddValueOfCurCell (-10);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0020;
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ break;
+ case 4: // チャンネル(MIDIチャンネルイベントの場合のみ)
+ if (0x80 <= lKind && lKind <= 0xEF) {
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0021;
+ AddValueOfCurCell (10);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0022;
+ AddValueOfCurCell (-10);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0020;
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ break;
+ case 5: // 値1
+ if (0x80 <= lKind && lKind <= 0xEF) {
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0021;
+ if (0x80 <= lKind && lKind <= 0xA0) {
+ AddValueOfCurCell (12);
+ }
+ else {
+ AddValueOfCurCell (10);
+ }
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0022;
+ if (0x80 <= lKind && lKind <= 0xA0) {
+ AddValueOfCurCell (-12);
+ }
+ else {
+ AddValueOfCurCell (-10);
+ }
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0020;
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ break;
+ case 6: // 値2
+ if (0x80 <= lKind && lKind <= 0xBF) {
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0021;
+ AddValueOfCurCell (10);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0022;
+ AddValueOfCurCell (-10);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0020;
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ break;
+ case 7: // 値3
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ break;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ break;
+ }
+ // キーボード又はマウスによる操作を開始する場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pEventListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0021;
+ AddValueOfCurCell (10);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0022;
+ AddValueOfCurCell (-10);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0020;
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ }
+ else {
+ ShowPopupMenu (ptMenu);
+ }
+ break;
+ }
+ }
+
+ // 停止中の場合、現在のセルのイベント時刻を再生時刻とする
+ if (pSekaijuApp->m_bPlaying == FALSE) {
+ MIDIEvent* pMIDIEvent = NULL;
+ lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+ if (pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ }
+ }
+
+ // 新しいセルの描画
+ rcNewCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell, FALSE);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// マウス左ボタン離されたとき
+void CEventListIndexPropertyView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // 左マウスで操作中の場合のみ
+ if (m_lCurButtonState & 0x0010) {
+ // 左マウス操作の終了
+ m_lCurButtonState &= ~0x0010;
+ // もはやマウスで操作されていない場合
+ if ((m_lCurButtonState & 0x00F0) == 0x0000) {
+ EndValueUpDown ();
+ m_lCurButtonState = 0x0000;
+ KillTimer (1);
+ ReleaseCapture ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン離されたとき
+void CEventListIndexPropertyView::OnRButtonUp (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // 右マウスで操作中の場合のみ
+ if (m_lCurButtonState & 0x0020) {
+ // 右マウス操作の終了
+ m_lCurButtonState &= ~0x0020;
+ // もはやマウスで操作されていない場合
+ if ((m_lCurButtonState & 0x00F0) == 0x0000) {
+ EndValueUpDown ();
+ m_lCurButtonState = 0x0000;
+ KillTimer (1);
+ ReleaseCapture ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+
+}
+
+// マウスが動かされたとき
+void CEventListIndexPropertyView::OnMouseMove (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CEventListIndexPropertyView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+
+ long lButtonWidth = 12; //::GetSystemMetrics (SM_CXVSCROLL);
+
+ // 先にOnLButtonDownを実行させ、テキスト編集終了・リスト選択終了・カレントセルの移動を済ませておく。
+ SendMessage (WM_LBUTTONDOWN, nFlags, ((point.y & 0x0000FFFF) << 16) | (point.x & 0x0000FFFF));
+ if (IsTextEditing () || IsListSelecting ()) {
+ return;
+ }
+ if (m_lCurButtonState != 0x0000) {
+ return;
+ }
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ point += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+
+ // 新しいセルの取得
+ long i = 0;
+ long j = 0;
+ GetCellFromPoint (point, &i, &j);
+ if (0 <= i && i <= 0x7FFFFFFF && 0 <= j && j < 8) {
+ m_lCurRow = i;
+ m_lCurColumn = j;
+ }
+ CRect rcCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ // テキスト編集モード又は専用ダイアログモードに突入。
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (point.x < rcCell.right - lButtonWidth) {
+ MIDIEvent* pMIDIEvent = NULL;
+ if (m_lCurRow < lVisibleEventCount) {
+ VERIFY (pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow));
+ }
+ else {
+ return;
+ }
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ switch (m_lCurColumn) {
+ case 0: // トラック
+ BeginListSelecting ();
+ break;
+ case 2: // 小節:拍:ティック
+ BeginTextEditing ();
+ break;
+ case 3: // イベントの種類
+ BeginListSelecting ();
+ break;
+ case 4: // チャンネル(MIDIチャンネルイベントの場合のみ)
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ BeginTextEditing ();
+ }
+ break;
+ case 5: // 値1
+ if (!MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ BeginTextEditing ();
+ }
+ break;
+ case 6: // 値2
+ if (!MIDIEvent_IsEndofTrack (pMIDIEvent) && !(0xC0 <= lKind && lKind <= 0xEF)) {
+ BeginTextEditing ();
+ }
+ break;
+ case 7: // 値3
+ if (!MIDIEvent_IsEndofTrack (pMIDIEvent) && !(0xA0 <= lKind && lKind <= 0xEF)) {
+ BeginTextEditing ();
+ }
+ break;
+ }
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CEventListIndexPropertyView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// タイマー時
+void CEventListIndexPropertyView::OnTimer (UINT nIDEvent) {
+
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // 該当行のMIDIイベントを取得
+ MIDIEvent* pMIDIEvent = NULL;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+ long lKind = 0;
+ if (pMIDIEvent) {
+ lKind = MIDIEvent_GetKind (pMIDIEvent);
+ }
+
+ // 上下ボタン又は+-キーによる値の増減
+ if (nIDEvent == 1) {
+ // 加速処理
+ if (m_lCurButtonInterval > 50) {
+ KillTimer (1);
+ m_lCurButtonInterval = 50;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ }
+ // 上ボタンが左クリックで押されている
+ if ((m_lCurButtonState & 0x00FF) == 0x0011) {
+ AddValueOfCurCell (1);
+ }
+ // 下ボタンが左クリックで押されている
+ else if ((m_lCurButtonState & 0x00FF) == 0x0012) {
+ AddValueOfCurCell (-1);
+ }
+ // 上ボタンが右クリックで押されている
+ if ((m_lCurButtonState & 0x00FF) == 0x0021) {
+ if (m_lCurColumn == 5 && 0x80 <= lKind && lKind <= 0xAF) {
+ AddValueOfCurCell (12);
+ }
+ else {
+ AddValueOfCurCell (10);
+ }
+ }
+ // 下ボタンが右クリックで押されている
+ else if ((m_lCurButtonState & 0x00FF) == 0x0022) {
+ if (m_lCurColumn == 5 && 0x80 <= lKind && lKind <= 0xAF) {
+ AddValueOfCurCell (-12);
+ }
+ else {
+ AddValueOfCurCell (-10);
+ }
+ }
+ // 上ボタンが両クリックで押されている
+ if ((m_lCurButtonState & 0x00FF) == 0x0031) {
+ AddValueOfCurCell (10);
+ }
+ // 下ボタンが両クリックで押されている
+ else if ((m_lCurButtonState & 0x00FF) == 0x0032) {
+ AddValueOfCurCell (-10);
+ }
+
+ // セルの再描画
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell, FALSE);
+ }
+
+ // 再生時などのカレントセル自動移動用(ページ更新機能付き)
+ else if (nIDEvent == 0x11) {
+ if (pEventListFrame->m_bAutoPageUpdate == TRUE
+ && IsTextEditing () == FALSE && IsListSelecting () == FALSE) {
+ long lCurTime = pSekaijuDoc->m_lNewTime;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ long lEventTime = 0;
+ if (pMIDIEvent) {
+ lEventTime = MIDIEvent_GetTime (pMIDIEvent);
+ }
+ // カレントセルを更新する必要がある場合のみ
+ if (lCurTime != lEventTime) {
+ // セルを現在時刻のイベントに合わせる。
+ long i;
+ for (i = 0; i < lVisibleEventCount; i++) {
+ VERIFY (pMIDIEvent = pEventListFrame->GetVisibleEvent (i));
+ if (MIDIEvent_GetTime (pMIDIEvent) >= lCurTime) {
+ break;
+ }
+ }
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+
+ // 旧フレームの消去
+ DrawCurFrame (&dc);
+ // カレントセルの更新
+ m_lCurRow = i;
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ // 新フレームの描画
+ DrawCurFrame (&dc);
+
+ int n = 0;
+ // カレントセルがビューの上にはみ出した場合の処理
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ if (m_lCurRow * lRowZoom < rcClient.top) {
+ n = m_lCurRow * lRowZoom;
+ pEventListFrame->SetRowScrollPos (n);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ }
+ // カレントセルがビューの下にはみ出した場合の処理
+ else if ((m_lCurRow + 1) * lRowZoom > rcClient.bottom) {
+ n = m_lCurRow * lRowZoom;
+ pEventListFrame->SetRowScrollPos (n);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ }
+ }
+ }
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウスホイールが回された時
+void CEventListIndexPropertyView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+
+ // 演奏位置の移動
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+
+ // カレントセルの値の増減
+ else if (GetKeyState (VK_MENU) < 0) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ point += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+
+ // テキスト編集の終了
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ }
+ // リスト選択終了
+ if (IsListSelecting ()) {
+ EndListSelectingCancel ();
+ m_lCurButtonState = 0x0000;
+ }
+
+ // 古いセルの描画
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+
+ // 新しいセルの設定
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ MoveListBox (m_lCurRow, m_lCurColumn);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ UpdateParentToolbarControl ();
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ // 該当行のMIDIイベントを取得
+ MIDIEvent* pMIDIEvent = NULL;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+
+ // MIDIイベントのある行の場合のみ
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ if (pMIDIEvent) {
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ long lDeltaValue = GetKeyState (VK_SHIFT) < 0 ? 10 : 1;
+ // 列とイベントによりリスト選択開始又は値の増減開始
+ switch (m_lCurColumn) {
+ case 2: // 小節:拍:ティック
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上回しの場合
+ if (lDelta > 0) {
+ AddValueOfCurCell (lDeltaValue);
+ }
+ // 下回しの場合
+ else {
+ AddValueOfCurCell (-lDeltaValue);
+ }
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ break;
+ case 4: // チャンネル(MIDIチャンネルイベントの場合のみ)
+ if (0x80 <= lKind && lKind <= 0xEF) {
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上回しの場合
+ if (lDelta > 0) {
+ AddValueOfCurCell (lDeltaValue);
+ }
+ // 下回しの場合
+ else {
+ AddValueOfCurCell (-lDeltaValue);
+ }
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ case 5: // 値1
+ if (0x80 <= lKind && lKind <= 0xEF) {
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上回しの場合
+ if (lDelta > 0) {
+ AddValueOfCurCell (lDeltaValue);
+ }
+ // 下回しの場合
+ else {
+ AddValueOfCurCell (-lDeltaValue);
+ }
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ case 6: // 値2
+ if (0x80 <= lKind && lKind <= 0xBF) {
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上回しの場合
+ if (lDelta > 0) {
+ AddValueOfCurCell (lDeltaValue);
+ }
+ // 下回しの場合
+ else {
+ AddValueOfCurCell (-lDeltaValue);
+ }
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ case 7: // 値3
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上回しの場合
+ if (lDelta > 0) {
+ AddValueOfCurCell (lDeltaValue);
+ }
+ // 下回しの場合
+ else {
+ AddValueOfCurCell (-lDeltaValue);
+ }
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ }
+ }
+
+ // 停止中の場合、現在のセルのイベント時刻を再生時刻とする
+ if (pSekaijuApp->m_bPlaying == FALSE) {
+ MIDIEvent* pMIDIEvent = NULL;
+ lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ if (0 <= m_lCurRow && m_lCurRow < lVisibleEventCount) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (m_lCurRow);
+ }
+ if (pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ }
+ }
+
+ // 新しいセルの描画
+ rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+ // 画面スクロール
+ else {
+ long lRowScrollPos = pEventListFrame->GetRowScrollPos ();
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pEventListFrame->SetRowScrollPos (lRowScrollPos);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ }
+}
diff --git a/src/EventListIndexPropertyView.h b/src/EventListIndexPropertyView.h
new file mode 100644
index 0000000..6018e23
--- /dev/null
+++ b/src/EventListIndexPropertyView.h
@@ -0,0 +1,120 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストインデックスプロパティビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTLISTINDEXPROPERTYVIEW_H_
+#define _EVENTLISTINDEXPROPERTYVIEW_H_
+
+#include "InplaceEdit.h"
+#include "InplaceListBox.h"
+
+class CEventListIndexPropertyView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CEventListIndexPropertyView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEventListIndexPropertyView(); // コンストラクタ
+ virtual ~CEventListIndexPropertyView(); // デストラクタ
+
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lCurRow; // 現在の行番号(0〜)
+ long m_lCurColumn; // 現在の列番号(0〜)
+ long m_lCurButtonState; // 現在のボタン状態
+ long m_lCurButtonInterval; // 現在のボタンの増減間隔
+ CInplaceEdit m_theTextBox; // インプレーステキストボックス
+ CInplaceListBox m_theListBox; // インプレースリストボックス
+
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ MIDITrack* m_pCloneTrack; // 一時的な複製されたトラックへのポインタ
+ MIDIEvent* m_pCloneEvent; // 一時的な複製されたイベントへのポインタ
+ MIDIEvent* m_pLastEvent; // 一時的な最後のイベントへのポインタ
+ BOOL m_bSettingCellString; // セルの文字列を設定中か
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL GetCellFromPoint (CPoint pt, long* pRow, long* pColumn);
+ virtual CRect GetRectFromCell (long lRow, long lColumn);
+
+public:
+ virtual BOOL AutoScrolltoShowCell (long lRow, long lColumn);
+ virtual BOOL IsTextEditing ();
+ virtual BOOL IsListSelecting ();
+ virtual BOOL BeginTextEditing ();
+ virtual BOOL BeginListSelecting ();
+ virtual BOOL EndTextEditingOK ();
+ virtual BOOL EndListSelectingOK ();
+ virtual BOOL EndTextEditingCancel ();
+ virtual BOOL EndListSelectingCancel ();
+ virtual BOOL BeginValueUpDown ();
+ virtual BOOL EndValueUpDown ();
+ virtual BOOL AddValueOfCurCell (long lDeltaValue);
+ virtual BOOL MoveTextBox (long lRow, long lColumn);
+ virtual BOOL MoveListBox (long lRow, long lColumn);
+ virtual BOOL UpdateParentToolbarControl ();
+ virtual CString GetCellString (long lRow, long lColumn);
+ virtual BOOL SetCellString (long lRow, long lColumn, CString strText);
+ virtual BOOL ShowPopupMenu (CPoint point);
+ virtual int DrawCurFrame (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo = NULL);
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+ virtual BOOL OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
+
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnDestroy ();
+ afx_msg void OnKillFocus (CWnd* pNewWnd);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+
+ DECLARE_MESSAGE_MAP ();
+};
+
+#endif
+
diff --git a/src/EventListIndexScaleView.cpp b/src/EventListIndexScaleView.cpp
new file mode 100644
index 0000000..20593e2
--- /dev/null
+++ b/src/EventListIndexScaleView.cpp
@@ -0,0 +1,454 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストインデックススケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "EventListFrame.h"
+#include "EventListIndexScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CEventListIndexScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEventListIndexScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventListIndexScaleView::CEventListIndexScaleView () {
+}
+
+// デストラクタ
+CEventListIndexScaleView::~CEventListIndexScaleView () {
+}
+
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// セルの長方形を取得
+CRect CEventListIndexScaleView::GetRectFromRow (long lRow) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CRect rcCell (0, 0, 0 ,0);
+ rcCell.left = 0;
+ rcCell.right = rcCell.left + rcClient.Width ();
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ rcCell.top = lRow * lRowZoom;
+ rcCell.bottom = (lRow + 1) * lRowZoom;
+ ASSERT (rcCell.left < rcCell.right);
+ ASSERT (rcCell.top < rcCell.bottom);
+ return rcCell;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CEventListIndexScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ pDC->SetWindowOrg (0, pEventListFrame->GetRowScrollPos ());
+}
+
+// 描画
+void CEventListIndexScaleView::OnDraw (CDC* pDC) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ BOOL bEventZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bEventZeroOrigin;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (pEventListFrame->GetParentFont ());
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+
+ long lTopIndex = pEventListFrame->GetVisibleTopRow ();
+ long lBottomIndex = pEventListFrame->GetVisibleBottomRow ();
+ long y = 0;
+ long yold = 0;
+ TCHAR szBuf[256];
+
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ for (long i = lTopIndex; i <= lBottomIndex; i++) {
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (i);
+ long bEventSelected = FALSE;
+ if (pMIDIEvent) {
+ bEventSelected = pSekaijuDoc->IsEventSelected (pMIDIEvent);
+ }
+ y = i * lRowZoom;
+ CRect theRect (0, y, rcClient.Width (), y + lRowZoom);
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i + (bEventZeroOrigin ? 0 : 1));
+ if (bEventSelected) {
+ pDC->FillSolidRect (&theRect, lColorBlack);
+ pDC->Draw3dRect (&theRect, lColorBlack, lColorBtnShadow);
+ pDC->SetTextColor (lColorWhite);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ else {
+ pDC->FillSolidRect (&theRect, lColorBtnFace);
+ pDC->Draw3dRect (&theRect, lColorBtnHighlight, lColorBtnShadow);
+ pDC->SetTextColor (lColorBtnText);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ yold = y;
+ }
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+// ビューの更新
+void CEventListIndexScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CEventListIndexScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キー押し下げ時
+void CEventListIndexScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ pEventListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+}
+
+// マウス左ボタン押された時
+void CEventListIndexScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+ point += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ());
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pSekaijuDoc->AddHistoryUnit (_T("選択/選択解除")));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ pEventListFrame->MakeVisibleEventArray (); // TODO 他のフレームウィンドウが不正になる
+ }
+
+ // イベントの選択
+ long lOldRow = pEventListFrame->YtoRow (m_ptMouseDown.y);
+ long lCurRow = pEventListFrame->YtoRow (point.y);
+ // シフトが押されている場合
+ if (nFlags & MK_SHIFT) {
+ long lMinRow = __min (lOldRow, lCurRow);
+ long lMaxRow = __max (lOldRow, lCurRow);
+ long i;
+ for (i = lMinRow; i <= lMaxRow; i++) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (i);
+ if (pMIDIEvent) {
+ MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent);
+ }
+ }
+ }
+ }
+ // シフトが押されていない場合
+ else {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (lCurRow);
+ if (pMIDIEvent) {
+ MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent);
+ }
+ }
+ }
+
+ SetCapture ();
+ SetTimer (0x21, 55, NULL);
+ Invalidate ();
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CEventListIndexScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+}
+
+// マウス左ボタン離されたとき
+void CEventListIndexScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ ReleaseCapture ();
+ KillTimer (0x21);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CEventListIndexScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CEventListIndexScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pEventListFrame->GetRowScrollPos ());
+ point += CSize (0, pEventListFrame->GetRowScrollPos ());
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // イベントの選択又は選択解除
+ long lCurRow = pEventListFrame->YtoRow (point.y);
+ long lDownRow = pEventListFrame->YtoRow (m_ptMouseDown.y);
+ long lOldRow = pEventListFrame->YtoRow (m_ptMouseMove.y);
+ if (lOldRow != lCurRow) {
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ long lMinRow = __min (lOldRow, lCurRow);
+ long lMaxRow = __max (lOldRow, lCurRow);
+ long i;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ if (lDownRow <= lOldRow && lOldRow <= lCurRow ||
+ lDownRow >= lOldRow && lOldRow >= lCurRow) {
+ for (i = lMinRow; i <= lMaxRow; i++) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (i);
+ if (pMIDIEvent) {
+ MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent);
+ }
+ }
+ }
+ }
+ else if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ for (i = lMinRow; i <= lMaxRow; i++) {
+ if (i != lCurRow) {
+ pMIDIEvent = pEventListFrame->GetVisibleEvent (i);
+ if (pMIDIEvent) {
+ MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 0, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent);
+ }
+ }
+ }
+ }
+ }
+ Invalidate (FALSE);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CEventListIndexScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CEventListIndexScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CEventListIndexScaleView::OnTimer (UINT nIDEvent) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理
+ if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pEventListFrame->GetRowScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ long lOldRowScrollPos = pEventListFrame->GetRowScrollPos ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (m_ptMouseMove.y < rcClient.top) {
+ pEventListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pEventListFrame->m_wndRowScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y > rcClient.bottom) {
+ pEventListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pEventListFrame->m_wndRowScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldRowScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+
+ ::Sleep (0);
+}
+
+// マウスホイールが回された時
+void CEventListIndexScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pEventListFrame->GetRowScrollPos ();
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pEventListFrame->SetRowScrollPos (lRowScrollPos);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ }
+}
+
diff --git a/src/EventListIndexScaleView.h b/src/EventListIndexScaleView.h
new file mode 100644
index 0000000..36ad5b4
--- /dev/null
+++ b/src/EventListIndexScaleView.h
@@ -0,0 +1,77 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストインデックススケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTLISTINDEXSCALEVIEW_H_
+#define _EVENTLISTINDEXSCALEVIEW_H_
+
+class CEventListIndexScaleView : public CSekaijuView {
+
+public:
+ DECLARE_DYNCREATE (CEventListIndexScaleView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEventListIndexScaleView(); // コンストラクタ
+ virtual ~CEventListIndexScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+protected:
+ virtual CRect GetRectFromRow (long lRow);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo = NULL);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EventListOptionPage.cpp b/src/EventListOptionPage.cpp
new file mode 100644
index 0000000..554baec
--- /dev/null
+++ b/src/EventListOptionPage.cpp
@@ -0,0 +1,126 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストオプションページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "EventListOptionPage.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventListOptionPage::CEventListOptionPage () : CPropertyPage (CEventListOptionPage::IDD) {
+ m_lDefRowZoom = 0;
+ m_lDefColumnZoom = 0;
+ m_lDefTrackWidth = 0;
+ m_lDefMillisecWidth = 0;
+ m_lDefTimeWidth = 0;
+ m_lDefKindWidth = 0;
+ m_lDefChWidth = 0;
+ m_lDefVal1Width = 0;
+ m_lDefVal2Width = 0;
+ m_lDefVal3Width = 0;
+ m_bInsertEventAfter = FALSE;
+ m_bDuplicateEventAfter = FALSE;
+ m_bDeleteEventAfter = FALSE;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CEventListOptionPage::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFROWZOOM, m_lDefRowZoom);
+ DDV_MinMaxInt (pDX, m_lDefRowZoom, 16, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFCOLUMNZOOM, m_lDefColumnZoom);
+ DDV_MinMaxInt (pDX, m_lDefColumnZoom, 2, 16);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFTRACKWIDTH, m_lDefTrackWidth);
+ DDV_MinMaxInt (pDX, m_lDefTrackWidth, 1, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFMILLISECWIDTH, m_lDefMillisecWidth);
+ DDV_MinMaxInt (pDX, m_lDefMillisecWidth, 1, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFTIMEWIDTH, m_lDefTimeWidth);
+ DDV_MinMaxInt (pDX, m_lDefTimeWidth, 1, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFKINDWIDTH, m_lDefKindWidth);
+ DDV_MinMaxInt (pDX, m_lDefKindWidth, 1, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFCHWIDTH, m_lDefChWidth);
+ DDV_MinMaxInt (pDX, m_lDefChWidth, 1, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFVAL1WIDTH, m_lDefVal1Width);
+ DDV_MinMaxInt (pDX, m_lDefVal1Width, 1, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFVAL2WIDTH, m_lDefVal2Width);
+ DDV_MinMaxInt (pDX, m_lDefVal2Width, 1, 32);
+ DDX_Text (pDX, IDC_EVENTLISTOPTION_DEFVAL3WIDTH, m_lDefVal3Width);
+ DDV_MinMaxInt (pDX, m_lDefVal3Width, 1, 32);
+ DDX_Radio (pDX, IDC_EVENTLISTOPTION_INSERTEVENTBEFORE, m_bInsertEventAfter);
+ DDX_Radio (pDX, IDC_EVENTLISTOPTION_DUPLICATEEVENTBEFORE, m_bDuplicateEventAfter);
+ DDX_Radio (pDX, IDC_EVENTLISTOPTION_DELETEEVENTBEFORE, m_bDeleteEventAfter);
+ DDX_Check (pDX, IDC_EVENTLISTOPTION_ENABLEROWZOOMKEY, m_bEnableRowZoomKey);
+ DDX_Check (pDX, IDC_EVENTLISTOPTION_ENABLECOLUMNZOOMKEY, m_bEnableColumnZoomKey);
+
+}
+
+
+
+// ダイアログの初期化
+BOOL CEventListOptionPage::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFROWZOOMSP))->SetRange (16, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFCOLUMNZOOMSP))->SetRange (2, 16);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFTRACKWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFMILLISECWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFTIMEWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFKINDWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFCHWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFVAL1WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFVAL2WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_EVENTLISTOPTION_DEFVAL3WIDTHSP))->SetRange (1, 32);
+
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CEventListOptionPage, CPropertyPage)
+END_MESSAGE_MAP ()
+
diff --git a/src/EventListOptionPage.h b/src/EventListOptionPage.h
new file mode 100644
index 0000000..b1adfbd
--- /dev/null
+++ b/src/EventListOptionPage.h
@@ -0,0 +1,72 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストオプションページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTLISTOPTION_H_
+#define _EVENTLISTOPTION_H_
+
+class CEventListOptionPage : public CPropertyPage {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lDefRowZoom; // デフォルトの行方向拡大率[倍]
+ long m_lDefColumnZoom; // デフォルトの列方向拡大率[倍]
+ long m_lDefTrackWidth; // デフォルトのトラック幅[pixel]
+ long m_lDefMillisecWidth; // デフォルトの時:分:秒:ミリ秒幅[pixel]
+ long m_lDefTimeWidth; // デフォルトのタイム幅[pixel]
+ long m_lDefKindWidth; // デフォルトのイベントの種類幅[pixel]
+ long m_lDefChWidth; // デフォルトのチャンネル幅[pixel]
+ long m_lDefVal1Width; // デフォルトの値1幅[pixel]
+ long m_lDefVal2Width; // デフォルトの値2幅[pixel]
+ long m_lDefVal3Width; // デフォルトの値3幅[pixel]
+ BOOL m_bInsertEventAfter; // 同時刻のイベントの直後に挿入する
+ BOOL m_bDuplicateEventAfter; // 現在のイベントの直後に挿入する
+ BOOL m_bDeleteEventAfter; // 削除したイベントの次のイベントにフォーカスを合わせる
+ BOOL m_bEnableRowZoomKey; // 行方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bEnableColumnZoomKey; // 列方向ズームのショートカットキーCtrl+'+''-'を有効にする
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ // コンストラクタ
+ CEventListOptionPage ();
+ enum {IDD = IDD_EVENTLISTOPTION};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ //afx_msg void OnChangeEnableAutoSave ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EventListPrintView.cpp b/src/EventListPrintView.cpp
new file mode 100644
index 0000000..38f0b49
--- /dev/null
+++ b/src/EventListPrintView.cpp
@@ -0,0 +1,865 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリスト印刷ビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include <afxpriv.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "common.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "EventListFrame.h"
+#include "EventListPrintView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define EVENTLISTPRINTVIEW_SCALEHEIGHT 40
+#define EVENTLISTPRINTVIEW_SCALEWIDTH 100
+#define EVENTLISTPRINTVIEW_LEFTMARGIN 200
+#define EVENTLISTPRINTVIEW_RIGHTMARGIN 200
+#define EVENTLISTPRINTVIEW_TOPMARGIN 200
+#define EVENTLISTPRINTVIEW_BOTTOMMARGIN 200
+
+IMPLEMENT_DYNCREATE (CEventListPrintView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEventListPrintView, CSekaijuView)
+ ON_COMMAND (ID_FILE_PRINT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventListPrintView::CEventListPrintView () {
+ // 印刷用文字フォントの作成(2.5ミリ)
+ CString strDefaultFontName;
+ VERIFY (strDefaultFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (25, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strDefaultFontName);
+
+}
+
+// デストラクタ
+CEventListPrintView::~CEventListPrintView () {
+ m_theFont.DeleteObject ();
+}
+
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// セルの長方形を取得
+CRect CEventListPrintView::GetRectFromCell (long lRow, long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < 8);
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ BOOL bCombined = FALSE; // 列5〜7が結合している場合TRUE;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ // 列5〜7のセルの結合判定
+ if (0 <= lRow && lRow < lVisibleEventCount) {
+ if (lColumn >= 5) {
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (lRow);
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ bCombined = TRUE;
+ }
+ }
+ }
+ else {
+ bCombined = TRUE;
+ }
+ // 縦境界の定義
+ long lLeftMargin = EVENTLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = EVENTLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = EVENTLISTPRINTVIEW_SCALEWIDTH;
+ long lWidthDiv[] = {0, 2, 4, 6, 8, 9, 11, 13, 15};
+ // セル矩形の計算
+ CRect rcCell (0, 0, 0 ,0);
+ if (bCombined && lColumn >= 5) {
+ rcCell.left = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[5] / 15;
+ rcCell.right = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[8] / 15;
+ }
+ else {
+ rcCell.left = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[lColumn] / 15;
+ rcCell.right = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[lColumn + 1] / 15;
+ }
+ long lRowZoom = 40;
+ rcCell.top = lRowZoom * m_lNumEventPerPage * m_lMaxPage - lRowZoom * (lRow + 1);
+ rcCell.bottom = lRowZoom * m_lNumEventPerPage * m_lMaxPage - lRowZoom * (lRow + 0);
+ ASSERT (rcCell.left < rcCell.right);
+ ASSERT (rcCell.top < rcCell.bottom);
+ return rcCell;
+}
+
+// セルの文字列を取得する
+CString CEventListPrintView::GetCellString (long lRow, long lColumn) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (lRow < 0 || lRow >= pEventListFrame->GetVisibleEventCount ()) {
+ return _T("");
+ }
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (lRow);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode = 0;
+ long lTimeResolution = 120;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ MIDIClock* pMIDIClock = pSekaijuDoc->m_pMIDIClock;
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ if (!MIDIEvent_IsMIDIEvent (pMIDIEvent) && lColumn > 5) {
+ lColumn = 5;
+ }
+ CString strText;
+ TCHAR szBuf1[2048];
+ TCHAR szBuf2[2048];
+ switch (lColumn) {
+ // トラック(20120107修正)
+ case 0:
+ memset (szBuf1, 0, sizeof (szBuf1));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ MIDITrack_GetName (pMIDITrack, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, sizeof (szBuf2));
+ strText.Format (_T("%d-%s"),
+ pSekaijuDoc->GetTrackIndex (pMIDITrack) + (bTrackZeroOrigin ? 0 : 1), szBuf2);
+ break;
+ // 時:分:秒:ミリ秒
+ case 1:
+ VERIFY (pSekaijuDoc->LongTimeToStringMillisec (pSekaijuDoc->m_pMIDIData, lTime, &strText));
+ break;
+ // 小節:拍:ティック 又は フレーム番号:ティック
+ case 2:
+ VERIFY (pSekaijuDoc->LongTimeToStringTime (pSekaijuDoc->m_pMIDIData, lTime, &strText));
+ break;
+ // イベントの種類
+ case 3:
+ strText = pSekaijuApp->m_strEventKindName[lKind];
+ break;
+ // チャンネル(MIDIチャンネルイベントの場合のみ。その他はn/a)。
+ case 4:
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ strText.Format (_T("%3d"), MIDIEvent_GetChannel (pMIDIEvent) + 1);
+ }
+ else {
+ strText = _T("n/a");
+ }
+ break;
+ // 値1
+ case 5:
+ // シーケンス番号
+ if (MIDIEvent_IsSequenceNumber (pMIDIEvent)) {
+ strText.Format (_T("%d"), MIDIEvent_GetNumber (pMIDIEvent));
+ }
+ // テキスト系イベント
+ else if (0x01 <= lKind && lKind <= 0x1F) {
+ TCHAR szBuf[1024];
+ memset (szBuf, 0, 1024);
+ MIDIEvent_GetText (pMIDIEvent, szBuf, 1024);
+ strText = szBuf;
+ }
+ // チャンネルプリフィックス,ポートプリフィックス
+ else if (MIDIEvent_IsChannelPrefix (pMIDIEvent) ||
+ MIDIEvent_IsPortPrefix (pMIDIEvent)) {
+ strText.Format (_T("%d"), MIDIEvent_GetNumber (pMIDIEvent) + 1);
+ }
+ // エンドオブトラック
+ else if (MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ strText = _T("");
+ }
+ // テンポイベント
+ else if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo;
+ double dBPM;
+ lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ dBPM = (double)60000000 / (double)lTempo;
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_1P2LF_BPM_EQ_D_MICROSEC_PER_QUARTER_NOTE));
+ strText.Format (strFormat, dBPM, lTempo);
+ }
+ // SMPTEオフセット
+ else if (MIDIEvent_IsSMPTEOffset (pMIDIEvent)) {
+ CString strMode[5];
+ VERIFY (strMode[0].LoadString (IDS_24));
+ VERIFY (strMode[1].LoadString (IDS_25));
+ VERIFY (strMode[2].LoadString (IDS_29P97));
+ VERIFY (strMode[3].LoadString (IDS_30));
+ VERIFY (strMode[4].LoadString (IDS_ERROR));
+ long lMode, lHour, lMinute, lSec, lFrame, lSubFrame;
+ MIDIEvent_GetSMPTEOffset (pMIDIEvent, &lMode, &lHour, &lMinute, &lSec, &lFrame, &lSubFrame);
+ if (lMode < 0 || lMode > 4) {
+ lMode = 4;
+ }
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_FPS_D_HOUR_D_MINUTE_D_SEC_D_FRAME_D_SUBFRAME));
+ strText.Format (strFormat,
+ strMode[lMode], lHour, lMinute, lSec, lFrame, lSubFrame);
+ }
+ // 拍子記号
+ else if (lKind == MIDIEVENT_TIMESIGNATURE) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_PER_D_D_CLOCK_PER_BEAT_D_32DIVNOTE_PER_BEAT));
+ strText.Format (strFormat, lnn, 1 << ldd, lcc, lbb);
+ }
+ // 調性記号
+ else if (lKind == MIDIEVENT_KEYSIGNATURE) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ CString strSF; // "#"又は"b"
+ CString strMi; // "major"又は"minor"
+ CString strKeySignatureName;
+ // 長調
+ if (lmi == 0) {
+ if (0 <= lsf && lsf < 8) {
+ VERIFY (strSF.LoadString (IDS_SHARP));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MA + lsf ));
+ }
+ else if (-8 <= lsf && lsf < 0) {
+ VERIFY (strSF.LoadString (IDS_FLAT));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MA + 16 + lsf));
+ }
+ VERIFY (strMi.LoadString (IDS_MAJOR));
+ }
+ // 短調
+ else {
+ if (0 <= lsf && lsf < 8) {
+ VERIFY (strSF.LoadString (IDS_SHARP));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MI + lsf ));
+ }
+ else if (-8 <= lsf && lsf < 0) {
+ VERIFY (strSF.LoadString (IDS_FLAT));
+ VERIFY (strKeySignatureName.LoadString (IDS_KEYSIGNATURE_0MI + 16 + lsf));
+ }
+ VERIFY (strMi.LoadString (IDS_MINOR));
+ }
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_S_S_EQ_S));
+ strText.Format (strFormat, abs (lsf), strSF, strMi, strKeySignatureName);
+ }
+ // ノートオフ・ノートオン・キーアフタータッチ
+ else if (0x80 <= lKind && lKind <= 0xAF) {
+ long lKey = MIDIEvent_GetKey (pMIDIEvent);
+ CString strKeyName;
+ strKeyName = pSekaijuDoc->GetKeyName (pMIDITrack, lTime, lKey);
+ strText.Format (_T("%d-%s"), lKey, strKeyName);
+ }
+ // コントロールチェンジ
+ else if (0xB0 <= lKind && lKind <= 0xBF) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ long lChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ if (0 <= lTrackOutputChannel && lTrackOutputChannel < 16) {
+ lChannel = lTrackOutputChannel;
+ }
+ MIDIInstrumentDefinition* pMIDIInstDef = NULL;
+ // このトラックの表示モードは「通常」の場合
+ if (lTrackViewMode == 0) {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ }
+ // このトラックの表示モードは「ドラム」の場合
+ else {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort];
+ }
+ // このトラックの指定するポートのインストゥルメント定義が見つかった
+ if (pMIDIInstDef) {
+ MIDIControllerNameTable* pControllerNameTable =
+ MIDIInstrumentDefinition_GetControllerNameTable (pMIDIInstDef);
+ // このインストゥルメント定義はControllerNameTableを持っている
+ if (pControllerNameTable) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIControllerNameTable_GetName (pControllerNameTable, lNumber, szBuf, 255);
+ strText.Format (_T("%d-%s"), lNumber, szBuf);
+ }
+ // このインストゥルメント定義はControllerNameTableを持っていない
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // こトラックの指定するポートのインストゥルメント定義がなかった
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // プログラムチェンジ
+ else if (0xC0 <= lKind && lKind <= 0xCF) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ long lChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ if (0 <= lTrackOutputChannel && lTrackOutputChannel < 16) {
+ lChannel = lTrackOutputChannel;
+ }
+ MIDIInstrumentDefinition* pMIDIInstDef = NULL;
+ // このトラックの表示モードは「通常」の場合
+ if (lTrackViewMode == 0) {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ }
+ // このトラックの表示モードは「ドラム」の場合
+ else {
+ pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort];
+ }
+ // このトラックの指定するポートのインストゥルメント定義が見つかった
+ if (pMIDIInstDef) {
+ long lBankMSB = MIDIEvent_GetBankMSB (pMIDIEvent);
+ long lBankLSB = MIDIEvent_GetBankLSB (pMIDIEvent);
+ long lBank = (lBankMSB << 7) | lBankLSB;
+ MIDIPatchNameTable* pPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pMIDIInstDef, lBank);
+ // このインストゥルメント定義は指定バンクのPatchNameTableを持っている
+ if (pPatchNameTable) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIPatchNameTable_GetName (pPatchNameTable, lNumber, szBuf, 255);
+ strText.Format (_T("%d-%s"), lNumber, szBuf);
+ }
+ // このインストゥルメント定義は指定バンクのPatchNameTableを持っていない
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // こトラックの指定するポートのインストゥルメント定義がなかった
+ else {
+ strText.Format (_T("%d"), lNumber);
+ }
+ }
+ // チャンネルアフタータッチ
+ else if (0xD0 <= lKind && lKind <= 0xDF) {
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ strText.Format (_T("%d"), lValue);
+ }
+ // ピッチベンド
+ else if (0xE0 <= lKind && lKind <= 0xEF) {
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ strText.Format (_T("%d"), lValue - 8192);
+ }
+ // その他のイベント(16進ダンプ)
+ else {
+ BYTE byBin[1024];
+ TCHAR szText[1024];
+ memset (byBin, 0, sizeof (byBin));
+ memset (szText, 0, sizeof (szText));
+ MIDIEvent_GetData (pMIDIEvent, byBin, 1024);
+ bin2txt (byBin, MIDIEvent_GetLen (pMIDIEvent), szText, 1023);
+ strText = szText;
+ }
+ break;
+ // 値2
+ case 6:
+ // ノート
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ strText.Format (_T("%d"), MIDIEvent_GetVelocity (pMIDIEvent));
+ }
+ // キーアフタータッチ・コントロールチェンジ
+ else if (0xA0 <= lKind && lKind <= 0xBF) {
+ strText.Format (_T("%d"), MIDIEvent_GetValue (pMIDIEvent));
+ }
+ // その他
+ else {
+ strText.Format (_T("---"));
+ }
+ break;
+ // 値3
+ case 7:
+ // ノート
+ if (0x80 <= lKind && lKind <= 0x9F) {
+ strText.Format (_T("%d"), MIDIEvent_GetDuration (pMIDIEvent));
+ }
+ // その他
+ else {
+ strText.Format (_T("---"));
+ }
+ break;
+ }
+ return strText;
+}
+
+
+// 左ラベル部描画
+void CEventListPrintView::DrawIndexScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+
+ long lRowZoom = 40;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ long lRowCount = m_lNumEventPerPage * pInfo->GetMaxPage ();
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long i;
+ long iMin = m_lNumEventPerPage * lCurPage;
+ long iMax = m_lNumEventPerPage * (lCurPage + 1);
+ for (i = iMin; i < iMax; i++) {
+ long x1 = 0;
+ long x2 = EVENTLISTPRINTVIEW_SCALEWIDTH;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lColorBtnFace);
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ CString strText;
+ strText.Format (_T("%d"), pSekaijuApp->m_theGeneralOption.m_bEventZeroOrigin ? i : i + 1);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 左上描画
+void CEventListPrintView::DrawScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ // 左上余白部描画
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (0, 0, EVENTLISTPRINTVIEW_SCALEWIDTH, EVENTLISTPRINTVIEW_SCALEHEIGHT, lColorBtnFace);
+}
+
+// リスト部描画
+void CEventListPrintView::DrawIndexPropertyView (CDC* pDC, CPrintInfo* pInfo) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+
+ CPen penIndex (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen penColumn (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen* pOldPen;
+
+ long lRowZoom = 40;
+ long lLeftMargin = EVENTLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = EVENTLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = EVENTLISTPRINTVIEW_SCALEWIDTH;
+ long lVisibleEventCount = pEventListFrame->GetVisibleEventCount ();
+ long lRowCount = m_lNumEventPerPage * pInfo->GetMaxPage ();
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long i;
+ long iMin = m_lNumEventPerPage * lCurPage;
+ long iMax = m_lNumEventPerPage * (lCurPage + 1);
+ for (i = iMin; i < iMax; i++) {
+ long x1 = 0;
+ long x2 = m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ long lBackColor = pSekaijuApp->m_theColorOption.m_lBackColor[i % 2];
+ // 背景の塗りつぶし
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lBackColor);
+ // 下線の描画
+ pOldPen = pDC->SelectObject (&penIndex);
+ pDC->MoveTo (x1, y1 + 1);
+ pDC->LineTo (x2, y1 + 1);
+ pDC->SelectObject (pOldPen);
+
+ // テキストカラーの設定
+ long lForeColor = RGB (0, 0, 0);
+ pDC->SetBkMode (TRANSPARENT);
+ CRect rcText;
+ CString strText;
+ MIDIEvent* pMIDIEvent = NULL;
+ if (0 <= i && i < lVisibleEventCount) {
+ VERIFY (pMIDIEvent = pEventListFrame->GetVisibleEvent (i));
+ }
+ if (pMIDIEvent) {
+ // TODO:MIDIイベントが差し替えられているがまだUpdateAllViewsされてない場合の回避措置
+ if (MIDIEvent_IsFloating (pMIDIEvent)) {
+ continue;
+ }
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ pDC->SetTextColor (lForeColor);
+ }
+ pOldPen = pDC->SelectObject (&penColumn);
+ // トラック名
+ rcText = GetRectFromCell (i, 0);
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 0);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->MoveTo (rcText.right - 1, rcText.top);
+ pDC->LineTo (rcText.right - 1, rcText.bottom);
+ // 時:分:秒:ミリ秒
+ rcText = GetRectFromCell (i, 1);
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 1);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->MoveTo (rcText.right - 1, rcText.top);
+ pDC->LineTo (rcText.right - 1, rcText.bottom);
+ // 小節:拍:ティック
+ rcText = GetRectFromCell (i, 2);
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 2);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->MoveTo (rcText.right - 1, rcText.top);
+ pDC->LineTo (rcText.right - 1, rcText.bottom);
+ // イベントの種類
+ rcText = GetRectFromCell (i, 3);
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 3);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->MoveTo (rcText.right - 1, rcText.top);
+ pDC->LineTo (rcText.right - 1, rcText.bottom);
+ // チャンネル
+ rcText = GetRectFromCell (i, 4);
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 4);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->MoveTo (rcText.right - 1, rcText.top);
+ pDC->LineTo (rcText.right - 1, rcText.bottom);
+ // 値1
+ rcText = GetRectFromCell (i, 5);
+ if (pMIDIEvent) {
+ strText = GetCellString (i, 5);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ // 値2, 値3
+ if (pMIDIEvent) {
+ long lEventKind = MIDIEvent_GetKind (pMIDIEvent);
+ if (0x80 <= lEventKind && lEventKind <= 0xEF) {
+ pDC->MoveTo (rcText.right - 1, rcText.top);
+ pDC->LineTo (rcText.right - 1, rcText.bottom);
+ rcText = GetRectFromCell (i, 6);
+ strText = GetCellString (i, 6);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+ pDC->MoveTo (rcText.right - 1, rcText.top);
+ pDC->LineTo (rcText.right - 1, rcText.bottom);
+ rcText = GetRectFromCell (i, 7);
+ strText = GetCellString (i, 7);
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+ }
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 上部ラベル部描画
+void CEventListPrintView::DrawPropertyScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ long lLeftMargin = EVENTLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = EVENTLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = EVENTLISTPRINTVIEW_SCALEWIDTH;
+ long lWidthDiv[] = {0, 2, 4, 6, 8, 9, 11, 13, 15};
+ pDC->SetBkMode (TRANSPARENT);
+ pDC->SetTextColor (RGB (0, 0, 0));
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ for (long j = 0; j < 8; j++) {
+ long x1 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j] / 15;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j + 1] / 15;
+ long y1 = 0;
+ long y2 = EVENTLISTPRINTVIEW_SCALEHEIGHT;
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lColorBtnFace);
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ CString strText (pEventListFrame->GetColumnTitle (j));
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 印刷時
+void CEventListPrintView::OnPrint (CDC* pDC, CPrintInfo* pInfo) {
+
+ pDC->SetMapMode (MM_LOMETRIC);
+ CPoint ptWindowOrg (0, 0);
+
+ long lLeftMargin = EVENTLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = EVENTLISTPRINTVIEW_RIGHTMARGIN;
+ long lTopMargin = EVENTLISTPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = EVENTLISTPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = EVENTLISTPRINTVIEW_SCALEHEIGHT;
+ long lScaleWidth = EVENTLISTPRINTVIEW_SCALEWIDTH;
+ long lListHeight = (m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin) / 40 * 40;
+ long lListWidth = (m_sizLogPaper.cx - lScaleWidth- lLeftMargin - lRightMargin);
+
+ CRgn theRgn;
+ CRect rcClip;
+
+ // イベント番号部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lListHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin + lListHeight * (pInfo->GetMaxPage () - pInfo->m_nCurPage);
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawIndexScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+
+ // 左上余白部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin + lListHeight;
+ rcClip.bottom = lBottomMargin + lListHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lListHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // イベントリスト部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lListWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lListHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin + lListHeight * (pInfo->GetMaxPage () - pInfo->m_nCurPage);
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawIndexPropertyView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+
+ // 上部項目名部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lListWidth;
+ rcClip.top = lBottomMargin + lListHeight;
+ rcClip.bottom = lBottomMargin + lListHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lListHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawPropertyScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // ヘッダー(タイトル)
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ pDC->SetTextColor (RGB (0, 0 ,0));
+ CRect rcText;
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = m_sizLogPaper.cy - lTopMargin;
+ rcText.bottom = m_sizLogPaper.cy - lTopMargin / 2;
+ TCHAR szText[256];
+ memset (szText, 0, sizeof (szText));
+ MIDIData_GetTitle (GetDocument()->m_pMIDIData, szText, TSIZEOF (szText));
+ CString strText;
+ if (TCSLEN (szText) == 0) {
+ strText = GetDocument()->GetTitle ();
+ }
+ else {
+ strText.Format (_T("%s"), szText);
+ }
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+ // フッター(ページ数/全ページ数)
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = lTopMargin / 2;
+ rcText.bottom = lTopMargin;
+ strText.Format (_T("%d/%d"), pInfo->m_nCurPage, pInfo->GetMaxPage ());
+ pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+}
+
+// 印刷準備時
+BOOL CEventListPrintView::OnPreparePrinting (CPrintInfo* pInfo) {
+ // デフォルトの印刷準備
+ return DoPreparePrinting (pInfo);
+}
+
+// 印刷開始時
+void CEventListPrintView::OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+
+ // 紙サイズの取得
+ m_sizDevPaper.cx = pDC->GetDeviceCaps (HORZRES); // [pixel]
+ m_sizDevPaper.cy = pDC->GetDeviceCaps (VERTRES); // [pixel]
+ m_sizLogPaper.cx = pDC->GetDeviceCaps (HORZSIZE) * 10; // [*0.1mm]
+ m_sizLogPaper.cy = pDC->GetDeviceCaps (VERTSIZE) * 10; // [*0.1mm]
+ m_sizLogPrinterDPI.cx = pDC->GetDeviceCaps (LOGPIXELSX); // [dpi]
+ m_sizLogPrinterDPI.cy = pDC->GetDeviceCaps (LOGPIXELSY); // [dpi]
+
+ // リスト全体の高さを計算
+ long lRowZoom = 40;
+ long lScaleHeight = EVENTLISTPRINTVIEW_SCALEHEIGHT;
+ long lTopMargin = EVENTLISTPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = EVENTLISTPRINTVIEW_BOTTOMMARGIN;
+ long lNumVisibleEvent = pEventListFrame->GetVisibleEventCount ();
+ m_lNumEventPerPage = MAX ((m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin) / lRowZoom, 1);
+ m_lMaxPage = lNumVisibleEvent / m_lNumEventPerPage + 1;
+
+ // 印刷ページ数の設定
+ pInfo->SetMaxPage (m_lMaxPage);
+}
+
+// 印刷終了時
+void CEventListPrintView::OnEndPrinting (CDC* pDC, CPrintInfo* pInfo) {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
diff --git a/src/EventListPrintView.h b/src/EventListPrintView.h
new file mode 100644
index 0000000..2053391
--- /dev/null
+++ b/src/EventListPrintView.h
@@ -0,0 +1,75 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリスト印刷ビュークラス
+// (C)2002-2011 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTLISTPRINTVIEW_H_
+#define _EVENTLISTPRINTVIEW_H_
+
+class CEventListPrintView : public CSekaijuView {
+
+public:
+ DECLARE_DYNCREATE (CEventListPrintView)
+
+ // CEventListFrameからCEventListPrintView::OnCmdMsgの呼び出しを許可する。
+ friend class CEventListFrame;
+
+ // 印刷関係
+ CSize m_sizDevPaper; // 物理紙サイズ[ドット]
+ CSize m_sizLogPaper; // 論理紙サイズ[*1/10mm]
+ CSize m_sizLogPrinterDPI; // プリンタのDPI
+ CFont m_theFont; // 印刷用フォント
+ long m_lNumEventPerPage; // 1ページあたりのイベント数
+ long m_lMaxPage; // 最大ページ数
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEventListPrintView(); // コンストラクタ
+ virtual ~CEventListPrintView (); // デストラクタ
+
+ //------------------------------------------------------------------------------
+ // オペレーション
+ //------------------------------------------------------------------------------
+
+protected:
+ CRect GetRectFromCell (long lRow, long lColumn);
+ CString GetCellString (long lRow, long lColumn);
+ void DrawIndexScaleView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawScaleView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawIndexPropertyView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawPropertyScaleView (CDC* pDC, CPrintInfo* pInfo);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrint (CDC* pDC, CPrintInfo* pInfo);
+ virtual BOOL OnPreparePrinting (CPrintInfo* pInfo);
+ virtual void OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting (CDC* pDC, CPrintInfo* pInfo);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/EventListPropertyScaleView.cpp b/src/EventListPropertyScaleView.cpp
new file mode 100644
index 0000000..b8c9e9b
--- /dev/null
+++ b/src/EventListPropertyScaleView.cpp
@@ -0,0 +1,251 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストプロパティスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "EventListFrame.h"
+#include "EventListPropertyScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE (CEventListPropertyScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEventListPropertyScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventListPropertyScaleView::CEventListPropertyScaleView () {
+}
+
+// デストラクタ
+CEventListPropertyScaleView::~CEventListPropertyScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動
+void CEventListPropertyScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ pDC->SetWindowOrg (pEventListFrame->GetColumnScrollPos (), 0);
+}
+
+// 描画
+void CEventListPropertyScaleView::OnDraw (CDC* pDC) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+ // 背景の塗りつぶし
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (pEventListFrame->GetParentFont ());
+ CRect theRect (0, 0, 0, 0);
+ long lColumnZoom = pEventListFrame->GetColumnZoom ();
+ for (long j = 0; j < 8; j++) {
+ theRect.top = rcClient.top;
+ theRect.bottom = rcClient.bottom;
+ theRect.left = theRect.right;
+ theRect.right = theRect.right + pEventListFrame->GetColumnBaseWidth (j) * lColumnZoom;
+ pDC->Draw3dRect (&theRect, lColorBtnHighlight, lColorBtnShadow);
+ pDC->DrawText (pEventListFrame->GetColumnTitle (j), &theRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CEventListPropertyScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キー押し下げ時
+void CEventListPropertyScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ pEventListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+}
+
+// マウス左ボタン押された時
+void CEventListPropertyScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ point += CSize (pEventListFrame->GetColumnScrollPos (), 0);
+ // カーソルが境界上にあるか調べる
+ long j = 0;
+ long lBorderX = 0;
+ for (j = 0; j < 8; j++) {
+ lBorderX += pEventListFrame->GetColumnBaseWidth (j) * pEventListFrame->GetColumnZoom ();
+ if (lBorderX - 2 <= point.x && point.x <= lBorderX + 2) {
+ break;
+ }
+ }
+ // カーソルが境界上にあった場合
+ if (0 <= j && j < 8) {
+ SetCapture ();
+ m_lTempColumnIndex = j;
+ m_lTempColumnBaseWidth = pEventListFrame->GetColumnBaseWidth (j);
+ m_ptMouseDown = m_ptMouseMoveOld = point;
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+}
+
+// マウス右ボタン押された時
+void CEventListPropertyScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+
+}
+
+// マウス左ボタン離されたとき
+void CEventListPropertyScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (GetCapture () == this) {
+ ReleaseCapture ();
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ pEventListFrame->RecalcColumnScrollInfo ();
+ pEventListFrame->m_pPropertyScaleView->Invalidate ();
+ pEventListFrame->m_pIndexPropertyView->Invalidate ();
+ }
+}
+
+// マウス右ボタン離されたとき
+void CEventListPropertyScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+
+}
+
+// マウスが動かされたとき
+void CEventListPropertyScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ point += CSize (pEventListFrame->GetColumnScrollPos (), 0);
+ // キャプター中
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CSize szMouseDelta = point.x - m_ptMouseDown.x;
+ long lNewColumnBaseWidth =
+ (m_lTempColumnBaseWidth * pEventListFrame->GetColumnZoom () + szMouseDelta.cx) /
+ pEventListFrame->GetColumnZoom ();
+ lNewColumnBaseWidth = CLIP (1, lNewColumnBaseWidth, 1024);
+ if (lNewColumnBaseWidth != pEventListFrame->GetColumnBaseWidth (m_lTempColumnIndex)) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ pEventListFrame->SetColumnBaseWidth (m_lTempColumnIndex, lNewColumnBaseWidth);
+ pEventListFrame->m_pPropertyScaleView->Invalidate ();
+ pEventListFrame->m_pIndexPropertyView->Invalidate ();
+ }
+ m_ptMouseMoveOld = point;
+ }
+ // 非キャプター中
+ else {
+ // カーソルが境界上にあるか調べる
+ long j = 0;
+ long lBorderX = 0;
+ for (j = 0; j < 8; j++) {
+ lBorderX += pEventListFrame->GetColumnBaseWidth (j) * pEventListFrame->GetColumnZoom ();
+ if (lBorderX - 2 <= point.x && point.x <= lBorderX + 2) {
+ break;
+ }
+ }
+ // カーソルが境界上にあった場合
+ if (0 <= j && j < 8) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+ // カーソルが境界上にない場合
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ }
+ }
+
+}
+
+// マウスホイールが回された時
+void CEventListPropertyScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pEventListFrame->GetRowScrollPos ();
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pEventListFrame->SetRowScrollPos (lRowScrollPos);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ }
+}
diff --git a/src/EventListPropertyScaleView.h b/src/EventListPropertyScaleView.h
new file mode 100644
index 0000000..35f5b09
--- /dev/null
+++ b/src/EventListPropertyScaleView.h
@@ -0,0 +1,73 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストプロパティスケールビュークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTLISTPROPERTYSCALEVIEW_H_
+#define _EVENTLISTPROPERTYSCALEVIEW_H_
+
+class CEventListPropertyScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CEventListPropertyScaleView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMoveOld; // マウスが動かされたときの前回の座標
+ long m_lTempColumnIndex; // マウスが押されたときのフラグ
+ long m_lTempColumnBaseWidth; // マウスが動かされたときの前回のフラグ
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEventListPropertyScaleView (); // コンストラクタ
+ virtual ~CEventListPropertyScaleView(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/EventListScaleView.cpp b/src/EventListScaleView.cpp
new file mode 100644
index 0000000..ae7ba13
--- /dev/null
+++ b/src/EventListScaleView.cpp
@@ -0,0 +1,168 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "EventListFrame.h"
+#include "EventListScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CEventListScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CEventListScaleView, CSekaijuView)
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CEventListScaleView::CEventListScaleView () {
+}
+
+// デストラクタ
+CEventListScaleView::~CEventListScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 描画
+void CEventListScaleView::OnDraw (CDC* pDC) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+}
+
+// ビューの更新
+void CEventListScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // 演奏開始した場合、リアルタイム入力開始した場合、位置移動した場合
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) { // 20091224追加
+ pEventListFrame->m_bAutoPageUpdate = TRUE;
+ }
+ }
+ // MIDIデータが変更された場合
+ if (lHint & SEKAIJUDOC_MIDIDATACHANGED) {
+ // タイトル文字列を更新(20091201:CEventListPropertyScaleView::OnDrawから引越し)
+ long lTimeMode = 0;
+ long lTimeResolution = 120;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ CString strTitle;
+ VERIFY (strTitle.LoadString (IDS_MEASURE_BEAT_TICK));
+ pEventListFrame->SetColumnTitle (2, strTitle);
+ }
+ else if (lTimeMode == MIDIDATA_SMPTE24BASE ||
+ lTimeMode == MIDIDATA_SMPTE25BASE ||
+ lTimeMode == MIDIDATA_SMPTE29BASE ||
+ lTimeMode == MIDIDATA_SMPTE30BASE) {
+ CString strTitle;
+ VERIFY (strTitle.LoadString (IDS_FRAME_SUBFRAME));
+ pEventListFrame->SetColumnTitle (2, strTitle);
+ }
+ }
+ // MIDIトラックが変更された場合
+ if (lHint & SEKAIJUDOC_MIDITRACKCHANGED) {
+ pEventListFrame->UpdateTrackList ();
+ pEventListFrame->UpdateTrackCombo ();
+ }
+ // MIDIデータ又はMIDIトラック又はMIDIイベントが変更された場合
+ if ((lHint & SEKAIJUDOC_MIDIDATACHANGED) ||
+ (lHint & SEKAIJUDOC_MIDITRACKCHANGED) ||
+ (lHint & SEKAIJUDOC_MIDIEVENTCHANGED)) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ pMainFrame->SetPositionScrollRange (0, lEndTime, TRUE);
+ pEventListFrame->MakeVisibleEventArray ();
+ pEventListFrame->RecalcRowScrollInfo ();
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+// キー押し下げ時
+void CEventListScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ pEventListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+}
+
+// マウスホイールが回された時
+void CEventListScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pEventListFrame->GetRowScrollPos ();
+ long lRowZoom = pEventListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pEventListFrame->SetRowScrollPos (lRowScrollPos);
+ pEventListFrame->m_bAutoPageUpdate = FALSE;
+ }
+}
+
diff --git a/src/EventListScaleView.h b/src/EventListScaleView.h
new file mode 100644
index 0000000..ac3fe77
--- /dev/null
+++ b/src/EventListScaleView.h
@@ -0,0 +1,52 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストスケールビュークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTLISTSCALEVIEW_H_
+#define _EVENTLISTSCALEVIEW_H_
+
+class CEventListScaleView : public CSekaijuView {
+ DECLARE_DYNCREATE (CEventListScaleView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEventListScaleView (); // コンストラクタ
+ virtual ~CEventListScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
+
+
diff --git a/src/FilePropertyDlg.cpp b/src/FilePropertyDlg.cpp
new file mode 100644
index 0000000..47ef79e
--- /dev/null
+++ b/src/FilePropertyDlg.cpp
@@ -0,0 +1,148 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ファイルプロパティダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include "resource.h"
+#include "FilePropertyDlg.h"
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CFilePropertyDlg::CFilePropertyDlg () : CDialog (CFilePropertyDlg::IDD) {
+ m_strTitle = _T("");
+ m_strSubTitle = _T("");
+ m_strCopyright = _T("");
+ m_strComment1 = _T("");
+ m_strComment2 = _T("");
+ m_strComment3 = _T("");
+ m_nSMFFormat = -1;
+ m_nTimeMode = -1;
+ m_nResolution = 120;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+void CFilePropertyDlg::FillResolutionComboAndStatic () {
+ CComboBox* pResolutionCombo = (CComboBox*)GetDlgItem (IDC_FILEPROPERTY_RESOLUTION);
+ CStatic* pResolutionStatic = (CStatic*)GetDlgItem (IDC_FILEPROPERTY_RESOLUTIONU);
+ CString strOldComboText;
+ pResolutionCombo->GetWindowText (strOldComboText);
+ pResolutionCombo->ResetContent ();
+ long i;
+ for (i = 0; i < 5; i++) {
+ CButton* pButton = (CButton*)GetDlgItem (IDC_FILEPROPERTY_TPQNBASE + i);
+ if (pButton->GetCheck () == TRUE) {
+ break;
+ }
+ }
+
+ // TPQNベース
+ if (i == 0) {
+ CString strUnit;
+ VERIFY (strUnit.LoadString (IDS_TICKS_PER_QUARTER_NOTE));
+ pResolutionCombo->AddString (_T("48"));
+ pResolutionCombo->AddString (_T("60"));
+ pResolutionCombo->AddString (_T("96"));
+ pResolutionCombo->AddString (_T("120"));
+ pResolutionCombo->AddString (_T("192"));
+ pResolutionCombo->AddString (_T("240"));
+ pResolutionCombo->AddString (_T("384"));
+ pResolutionCombo->AddString (_T("480"));
+ pResolutionCombo->AddString (_T("960"));
+ pResolutionCombo->SetWindowText (strOldComboText);
+ pResolutionStatic->SetWindowText (strUnit);
+ }
+ // SMPTEベース
+ else if (1 <= i && i <= 5) {
+ CString strUnit;
+ VERIFY (strUnit.LoadString (IDS_SUBFRAMES_PER_FRAME));
+ pResolutionCombo->AddString (_T("10"));
+ pResolutionCombo->AddString (_T("20"));
+ pResolutionCombo->AddString (_T("30"));
+ pResolutionCombo->AddString (_T("40"));
+ pResolutionCombo->AddString (_T("50"));
+ pResolutionCombo->AddString (_T("60"));
+ pResolutionCombo->AddString (_T("70"));
+ pResolutionCombo->AddString (_T("80"));
+ pResolutionCombo->AddString (_T("90"));
+ pResolutionCombo->AddString (_T("100"));
+ pResolutionCombo->SetWindowText (strOldComboText);
+ pResolutionStatic->SetWindowText (strUnit);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CFilePropertyDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_FILEPROPERTY_TITLE, m_strTitle);
+ DDX_Text (pDX, IDC_FILEPROPERTY_SUBTITLE, m_strSubTitle);
+ DDX_Text (pDX, IDC_FILEPROPERTY_COPYRIGHT, m_strCopyright);
+ DDX_Text (pDX, IDC_FILEPROPERTY_COMMENT1, m_strComment1);
+ DDX_Text (pDX, IDC_FILEPROPERTY_COMMENT2, m_strComment2);
+ DDX_Text (pDX, IDC_FILEPROPERTY_COMMENT3, m_strComment3);
+ DDX_Text (pDX, IDC_FILEPROPERTY_NUMTRACK, m_strNumTrack);
+ DDX_Text (pDX, IDC_FILEPROPERTY_NUMEVENT, m_strNumEvent);
+ DDX_Text (pDX, IDC_FILEPROPERTY_ENDMILLISEC, m_strEndMillisec);
+ DDX_Text (pDX, IDC_FILEPROPERTY_ENDTIME, m_strEndTime);
+
+ DDX_Radio (pDX, IDC_FILEPROPERTY_SMFFORMAT0, m_nSMFFormat);
+ DDX_Radio (pDX, IDC_FILEPROPERTY_TPQNBASE, m_nTimeMode);
+ DDX_Text (pDX, IDC_FILEPROPERTY_RESOLUTION, m_nResolution);
+ CButton* pTimeModeButton = (CButton*)GetDlgItem (IDC_FILEPROPERTY_TPQNBASE);
+ if (pTimeModeButton->GetCheck ()) {
+ DDV_MinMaxInt (pDX, m_nResolution, 1, 960);
+ }
+ else {
+ DDV_MinMaxInt (pDX, m_nResolution, 1, 255);
+ }
+}
+
+// ダイアログ初期化
+BOOL CFilePropertyDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ GetDlgItem (IDC_FILEPROPERTY_COMMENT2)->EnableWindow (FALSE);
+ GetDlgItem (IDC_FILEPROPERTY_COMMENT3)->EnableWindow (FALSE);
+ FillResolutionComboAndStatic ();
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CFilePropertyDlg, CDialog)
+ ON_CONTROL_RANGE (BN_CLICKED, IDC_FILEPROPERTY_TPQNBASE, IDC_FILEPROPERTY_SMPTE30BASE, OnChangeTimeMode)
+END_MESSAGE_MAP ()
+
+// タイムモードが変更された
+void CFilePropertyDlg::OnChangeTimeMode (UINT nID) {
+ FillResolutionComboAndStatic ();
+}
+
+
diff --git a/src/FilePropertyDlg.h b/src/FilePropertyDlg.h
new file mode 100644
index 0000000..59d31ef
--- /dev/null
+++ b/src/FilePropertyDlg.h
@@ -0,0 +1,70 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ファイルプロパティダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _FILEPROPERTYDLG_H_
+#define _FILEPROPERTYDLG_H_
+
+class CFilePropertyDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strTitle; // タイトル(=最初のトラックの最初のトラック名)
+ CString m_strSubTitle; // サブタイトル(=最初のトラックの2番目のトラック名)
+ CString m_strCopyright; // 著作権(=最初のトラックの最初の著作権)
+ CString m_strComment1; // コメント1(=最初のトラックの最初のテキスト)
+ CString m_strComment2; // コメント2(=最初のトラックの2番目のテキスト)
+ CString m_strComment3; // コメント3(=最初のトラックの3番目のテキスト)
+ CString m_strNumTrack; // トラック数
+ CString m_strNumEvent; // イベント数
+ CString m_strEndMillisec; // 終了ミリ秒
+ CString m_strEndTime; // 終了タイム
+ int m_nSMFFormat; // SMFフォーマット0/1/2
+ int m_nTimeMode; // タイムモード(0=TPQNベース,...)
+ int m_nResolution; // 分解能[tick/4分音符]又は[サブフレーム/1フレーム]
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CFilePropertyDlg (); // コンストラクタ
+ enum {IDD = IDD_FILEPROPERTY};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ void FillResolutionComboAndStatic ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeTimeMode (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/GeneralOptionPage.cpp b/src/GeneralOptionPage.cpp
new file mode 100644
index 0000000..74e0ac8
--- /dev/null
+++ b/src/GeneralOptionPage.cpp
@@ -0,0 +1,124 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// オプション(全般)プロパティページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "GeneralOptionPage.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CGeneralOptionPage::CGeneralOptionPage () : CPropertyPage (CGeneralOptionPage::IDD) {
+ m_bEnableMultiExec = FALSE;
+ m_bEnableMultiOpen = TRUE;
+ m_bRestoreWindowPlacement = TRUE;
+ m_bExecOpen = FALSE;
+ m_bOpenPlay = FALSE;
+ m_bPlayUpdate = TRUE;
+ m_bSearchUpdate = TRUE;
+ m_bEnableCC111Loop = TRUE;
+ m_bPatchSearch = TRUE;
+ m_bInvertCtrlMouseWheel = FALSE;
+ m_bTrackZeroOrigin = FALSE;
+ m_bEventZeroOrigin = FALSE;
+ m_lSpeedSlow = 50;
+ m_lSpeedNormal = 100;
+ m_lSpeedFast = 200;
+ m_lPlayRecordInterval = 5;
+ m_lOctaveSignature = 5;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CGeneralOptionPage::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Check (pDX, IDC_GENERALOPTION_ENABLEMULTIEXEC, m_bEnableMultiExec);
+ DDX_Check (pDX, IDC_GENERALOPTION_ENABLEMULTIOPEN, m_bEnableMultiOpen);
+ DDX_Check (pDX, IDC_GENERALOPTION_RESTOREWINDOWPLACEMENT, m_bRestoreWindowPlacement);
+ DDX_Check (pDX, IDC_GENERALOPTION_EXECOPEN, m_bExecOpen);
+ DDX_Check (pDX, IDC_GENERALOPTION_OPENPLAY, m_bOpenPlay);
+ DDX_Check (pDX, IDC_GENERALOPTION_PLAYUPDATE, m_bPlayUpdate);
+ DDX_Check (pDX, IDC_GENERALOPTION_SEARCHUPDATE, m_bSearchUpdate);
+ DDX_Check (pDX, IDC_GENERALOPTION_ENABLECC111LOOP, m_bEnableCC111Loop);
+ DDX_Check (pDX, IDC_GENERALOPTION_PATCHSEARCH, m_bPatchSearch);
+ DDX_Check (pDX, IDC_GENERALOPTION_INVERTCTRLMOUSEWHEEL, m_bInvertCtrlMouseWheel);
+ DDX_Check (pDX, IDC_GENERALOPTION_TRACKZEROORIGIN, m_bTrackZeroOrigin);
+ DDX_Check (pDX, IDC_GENERALOPTION_EVENTZEROORIGIN, m_bEventZeroOrigin);
+ DDX_Check (pDX, IDC_GENERALOPTION_ENABLEAUTOPAGEUPDATE, m_bEnableAutoPageUpdate);
+ DDX_Check (pDX, IDC_GENERALOPTION_SENDNOTEOFFHOLDOFFATEND, m_bSendNoteOffHoldOffAtEnd);
+ // DDV_MinMaxXXXは各々のDDX_TEXTの直後に配置すること(20090501訂正)
+ DDX_Text (pDX, IDC_GENERALOPTION_SPEEDSLOW, m_lSpeedSlow);
+ DDV_MinMaxInt (pDX, m_lSpeedSlow, 1, 1000);
+ DDX_Text (pDX, IDC_GENERALOPTION_SPEEDNORMAL, m_lSpeedNormal);
+ DDV_MinMaxInt (pDX, m_lSpeedNormal, 1, 1000);
+ DDX_Text (pDX, IDC_GENERALOPTION_SPEEDFAST, m_lSpeedFast);
+ DDV_MinMaxInt (pDX, m_lSpeedFast, 1, 1000);
+ DDX_Text (pDX, IDC_GENERALOPTION_PLAYRECORDINTERVAL, m_lPlayRecordInterval);
+ DDV_MinMaxInt (pDX, m_lPlayRecordInterval, 1, 1000);
+ DDX_Text (pDX, IDC_GENERALOPTION_OCTAVESIGNATURE, m_lOctaveSignature);
+ DDV_MinMaxInt (pDX, m_lOctaveSignature, 3, 5);
+}
+
+// ダイアログの初期化
+BOOL CGeneralOptionPage::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_GENERALOPTION_SPEEDSLOWSP))->SetRange (1, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_GENERALOPTION_SPEEDNORMALSP))->SetRange (1, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_GENERALOPTION_SPEEDFASTSP))->SetRange (1, 1000);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_GENERALOPTION_PLAYRECORDINTERVALSP))->SetRange (1, 1000); //20200205修正
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_GENERALOPTION_OCTAVESIGNATURESP))->SetRange (3, 5);
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CGeneralOptionPage, CPropertyPage)
+END_MESSAGE_MAP ()
+
+
+
+
diff --git a/src/GeneralOptionPage.h b/src/GeneralOptionPage.h
new file mode 100644
index 0000000..11f63ab
--- /dev/null
+++ b/src/GeneralOptionPage.h
@@ -0,0 +1,78 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// オプション(全般)プロパティページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _GENERALOPTIONPAGE_H_
+#define _GENERALOPTIONPAGE_H_
+
+class CGeneralOptionPage : public CPropertyPage {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ BOOL m_bEnableMultiExec; // 複数の世界樹を起動すること許可する
+ BOOL m_bEnableMultiOpen; // 複数のMIDIデータを開くことを許可する
+ BOOL m_bRestoreWindowPlacement; // 起動時に前回のウィンドウ位置を復元する
+ BOOL m_bExecOpen; // 起動時に最後に開いたMIDIデータを自動的に開く
+ BOOL m_bOpenPlay; // MIDIデータを開くと自動的に演奏を開始する
+ BOOL m_bPlayUpdate; // 演奏位置移動時にパッチ・コントローラ・ピッチベンド・RPN・NRPNを最新値に更新する
+ BOOL m_bSearchUpdate; // 演奏開始時にパッチ・コントローラ・ピッチベンド・RPN・NRPNを最新値に更新する
+ BOOL m_bEnableCC111Loop; // オートリピート時にCC#111の位置からループ開始する
+ BOOL m_bPatchSearch; // CC#0・CC#32・プログラムチェンジ操作時に有効な音色だけを検索する
+ BOOL m_bInvertCtrlMouseWheel; // Ctrl+マウスホイールの演奏位置移動方向を反転
+ BOOL m_bTrackZeroOrigin; // トラック番号を0から数える
+ BOOL m_bEventZeroOrigin; // イベント番号を0から数える
+ BOOL m_bEnableAutoPageUpdate; // 演奏開始時・位置移動時に自動的ページ更新をオンにする。
+ BOOL m_bSendNoteOffHoldOffAtEnd; // 曲の終端に達したときノートオフやホールドオフを送信する
+ long m_lUpDownDelta1; // ▲▼の左クリック又は[+][-]キーで増減する量(1〜127)
+ long m_lUpDownDelta2; // ▲▼の右クリック又は[Shift]+[+][-]キーで増減する量(1〜127)
+ long m_lKeyVelocity1; // 鍵盤の左クリック又は[Z]-[\]キーで発音するベロシティ(1〜127)
+ long m_lKeyVelocity2; // 鍵盤の右クリック又は[Shift]+[Z]-[\]キーで発音するベロシティ(1〜127)
+ long m_lSpeedSlow; // スピード=低速で演奏時のテンポ倍率(1〜<50>〜1000)[%]
+ long m_lSpeedNormal; // スピード=標準で演奏時のテンポ倍率(1〜<100>〜1000)[%]
+ long m_lSpeedFast; // スピード=高速で演奏時のテンポ倍率(1〜<200>〜1000)[%]
+ long m_lPlayRecordInterval; // MIDIデータ録音演奏時のwhileループ呼び出し間隔(1〜1000)[ミリ秒]
+ long m_lOctaveSignature; // 中央のド(キー60)のオクターブ番号表記(3〜5)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CGeneralOptionPage (); // コンストラクタ
+ enum {IDD = IDD_GENERALOPTION};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/GraphKindListBox.cpp b/src/GraphKindListBox.cpp
new file mode 100644
index 0000000..1d849a2
--- /dev/null
+++ b/src/GraphKindListBox.cpp
@@ -0,0 +1,135 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// グラフの種類リストボックスクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "resource.h"
+#include "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuDoc.h"
+#include "GraphKindListBox.h"
+
+// TSIZEOFマクロ //20120211追加
+#ifndef TSIZEOF
+#define TSIZEOF(STR) (sizeof(STR)/sizeof(TCHAR))
+#endif
+#ifndef TCSLEN
+#ifdef UNICODE
+#define TCSLEN(STRING) wcslen(STRING)
+#else
+#define TCSLEN(STRING) strlen(STRING)
+#endif
+#endif
+#ifndef TCSNCPY
+#ifdef UNICODE
+#define TCSNCPY(STRING1,STRING2,N) wcsncpy(STRING1,STRING2,N)
+#else
+#define TCSNCPY(STRING1,STRING2,N) strncpy(STRING1,STRING2,N)
+#endif
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CGraphKindListBox, CCheckListBox)
+
+BEGIN_MESSAGE_MAP (CGraphKindListBox, CCheckListBox)
+ ON_WM_RBUTTONDOWN ()
+END_MESSAGE_MAP ()
+
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CGraphKindListBox::CGraphKindListBox () {
+ m_pDocument = NULL;
+ m_lMenuID = 0;
+ m_lLastRButtonDownIndex = 0;
+ CCheckListBox::CCheckListBox ();
+}
+
+// コンストラクタ
+CGraphKindListBox::CGraphKindListBox (CDocument* pDocument, long lMenuID) {
+ m_pDocument = pDocument;
+ m_lMenuID = lMenuID;
+ m_lLastRButtonDownIndex = 0;
+ CCheckListBox::CCheckListBox ();
+}
+
+// デストラクタ
+CGraphKindListBox::~CGraphKindListBox () {
+ CCheckListBox::~CCheckListBox ();
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+CSekaijuDoc* CGraphKindListBox::GetDocument () {
+ return (CSekaijuDoc*)m_pDocument;
+}
+
+long CGraphKindListBox::GetLastRButtonDownIndex () {
+ return m_lLastRButtonDownIndex;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// マウス右ボタン押された時
+void CGraphKindListBox::OnRButtonDown (UINT nFlags, CPoint point) {
+ this->SetFocus ();
+ if (m_lMenuID == 0) {
+ return;
+ }
+ BOOL bOutside;
+ long lIndex = this->ItemFromPoint (point, bOutside);
+ if (bOutside) {
+ return;
+ }
+ if (lIndex < 0 || lIndex >= GetCount ()) {
+ return;
+ }
+ m_lLastRButtonDownIndex = lIndex;
+ // ポップアップメニューの表示
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (m_lMenuID));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, GetParentFrame ());
+}
+
+
diff --git a/src/GraphKindListBox.h b/src/GraphKindListBox.h
new file mode 100644
index 0000000..c940d87
--- /dev/null
+++ b/src/GraphKindListBox.h
@@ -0,0 +1,64 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// グラフの種類リストボックスクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _GRAPHKINDLISTBOX_H_
+#define _GRAPHKINDLISTBOX_H_
+
+class CGraphKindListBox : public CCheckListBox {
+ DECLARE_DYNCREATE (CGraphKindListBox)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CDocument* m_pDocument; // ドキュメントへのポインタ
+ long m_lMenuID; // 右クリックしたときに現れるメニューのID
+ long m_lLastRButtonDownIndex; // 最後に右クリックした項目番号(0〜)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CGraphKindListBox (); // コンストラクタ
+ CGraphKindListBox (CDocument* pDocument, long lMenuID); // コンストラクタ
+ virtual ~CGraphKindListBox (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ void CGraphKindListBox::SetDocument (CDocument* pDocument);
+ CSekaijuDoc* GetDocument ();
+ long GetLastRButtonDownIndex ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/HistoryRecord.cpp b/src/HistoryRecord.cpp
new file mode 100644
index 0000000..b9456b2
--- /dev/null
+++ b/src/HistoryRecord.cpp
@@ -0,0 +1,45 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 履歴記録クラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include "../../MIDIData/MIDIData.h"
+#include "HistoryRecord.h"
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CHistoryRecord::CHistoryRecord () {
+ m_lType = 0;
+ m_pObject = NULL;
+ m_pPrevObject = NULL;
+ m_pNextObject = NULL;
+ m_pFirstChild = NULL;
+ m_pLastChild = NULL;
+ m_pParent = NULL;
+
+}
+
+// デストラクタ
+CHistoryRecord::~CHistoryRecord () {
+}
+
diff --git a/src/HistoryRecord.h b/src/HistoryRecord.h
new file mode 100644
index 0000000..7a17ee5
--- /dev/null
+++ b/src/HistoryRecord.h
@@ -0,0 +1,56 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 履歴記録クラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _HISTORYRECORD_H_
+#define _HISTORYRECORD_H_
+
+#define HISTORYRECORD_INSERTEVENT 0x0001 // MIDIイベント挿入
+#define HISTORYRECORD_REMOVEEVENT 0x0002 // MIDIイベント削除
+#define HISTORYRECORD_INSERTEVENTALL 0x0003 // MIDIイベント全挿入
+#define HISTORYRECORD_REMOVEEVENTALL 0x0004 // MIDIイベント全削除
+#define HISTORYRECORD_INSERTTRACK 0x0011 // MIDIトラック挿入
+#define HISTORYRECORD_REMOVETRACK 0x0012 // MIDIトラック削除
+#define HISTORYRECORD_INSERTDATA 0x0021 // MIDIデータ挿入(未使用)
+#define HISTORYRECORD_REMOVEDATA 0x0022 // MIDIデータ削除(未使用)
+
+class CHistoryRecord {
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lType; // 記録タイプ
+ void* m_pObject; // オブジェクトへのポインタ
+ void* m_pPrevObject; // オブジェクトが双方向リンクリスト要素の場合の前のオブジェクトへのポインタ
+ void* m_pNextObject; // オブジェクトが双方向リンクリスト要素の場合の次のオブジェクトへのポインタ
+ void* m_pFirstChild; // オブジェクトが子を持つ場合の最初の子オブジェクトへのポインタ
+ void* m_pLastChild; // オブジェクトが子を持つ場合の最後の子オブジェクトへのポインタ
+ void* m_pParent; // オブジェクトが親を持つ場合の親オブジェクトへのポインタ
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CHistoryRecord (); // コンストラクタ
+ virtual ~CHistoryRecord (); // デストラクタ
+};
+
+#endif
+
diff --git a/src/HistoryUnit.cpp b/src/HistoryUnit.cpp
new file mode 100644
index 0000000..b138478
--- /dev/null
+++ b/src/HistoryUnit.cpp
@@ -0,0 +1,351 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 履歴ユニットクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxmt.h>
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuDoc.h"
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CHistoryUnit::CHistoryUnit () {
+ m_strName = _T("");
+}
+
+// デストラクタ
+CHistoryUnit::~CHistoryUnit () {
+ long i;
+ long lHistoryRecordCount = m_theHistoryRecordArray.GetSize ();
+ for (i = lHistoryRecordCount - 1; i >= 0; i--) {
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack * pMIDITrack = NULL;
+ MIDIData* pMIDIData = NULL;
+ CHistoryRecord* pHistoryRecord = (CHistoryRecord*)(m_theHistoryRecordArray.GetAt(i));
+ switch (pHistoryRecord->m_lType) {
+ case HISTORYRECORD_INSERTEVENT:
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ // ドキュメントで使われていないイベントは実体を削除
+ if ((pMIDIEvent->m_lUserFlag & MIDIEVENT_ALIVE) == 0) {
+ MIDIEvent_DeleteSingle (pMIDIEvent);
+ pMIDIEvent = NULL;
+ }
+ break; // 20080714break忘れ修正
+ case HISTORYRECORD_REMOVEEVENT:
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ // ドキュメントで使われていないイベントは実体を削除
+ if ((pMIDIEvent->m_lUserFlag & MIDIEVENT_ALIVE) == 0 &&
+ (pMIDIEvent->m_lUserFlag & MIDIEVENT_RESISTEREDASINSERTED) == 0) {
+ MIDIEvent_DeleteSingle (pMIDIEvent);
+ pMIDIEvent = NULL;
+ }
+ break;
+ case HISTORYRECORD_INSERTTRACK:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pObject);
+ // ドキュメントで使われていないトラックは実体を削除
+ if ((pMIDITrack->m_lUserFlag & MIDITRACK_ALIVE) == 0) {
+ MIDITrack_Delete (pMIDITrack);
+ pMIDITrack = NULL;
+ }
+ break; // 20080714break忘れ修正
+ case HISTORYRECORD_REMOVETRACK:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pObject);
+ // ドキュメントで使われていないトラックは実体を削除
+ if ((pMIDITrack->m_lUserFlag & MIDITRACK_ALIVE) == 0 &&
+ (pMIDITrack->m_lUserFlag & MIDITRACK_RESISTEREDASINSERTED) == 0) {
+ MIDITrack_Delete (pMIDITrack);
+ pMIDITrack = NULL;
+ }
+ break;
+ case HISTORYRECORD_INSERTDATA:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pObject);
+ // ドキュメントで使われていないMIDIDataオブジェクトは実体を削除
+ if ((pMIDIData->m_lUserFlag & MIDIDATA_ALIVE) == 0) {
+ MIDIData_Delete (pMIDIData);
+ pMIDIData = NULL;
+ }
+ break;
+ case HISTORYRECORD_REMOVEDATA:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pObject);
+ // ドキュメントで使われていないMIDIDataオブジェクトは実体を削除
+ if ((pMIDIData->m_lUserFlag & MIDIDATA_ALIVE) == 0 &&
+ (pMIDIData->m_lUserFlag & MIDIDATA_RESISTEREDASINSERTED) == 0) {
+ MIDIData_Delete (pMIDIData);
+ pMIDIData = NULL;
+ }
+ break;
+ }
+ delete pHistoryRecord;
+ }
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// この履歴ユニットに履歴記録をひとつ追加
+long CHistoryUnit::AddHistoryRecord (long lType, void* pObject) {
+ long lCount = 0;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pNextEvent = NULL;
+ MIDIEvent* pPrevEvent = NULL;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pTempTrack = NULL;
+ MIDIData* pMIDIData = NULL;
+ CHistoryRecord* pHistoryRecord = NULL;
+ switch (lType) {
+ // MIDIEventオブジェクト挿入の記録
+ case HISTORYRECORD_INSERTEVENT:
+ pMIDIEvent = (MIDIEvent*)pObject;
+ pMIDIEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ ASSERT (pMIDIEvent);
+ while (pMIDIEvent) {
+ ASSERT (pMIDIEvent->m_pParent);
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDIEvent;
+ pHistoryRecord->m_pFirstChild = NULL;
+ pHistoryRecord->m_pLastChild = NULL;
+ pNextEvent = pMIDIEvent->m_pNextEvent;
+ while (pNextEvent) {
+ if (pNextEvent->m_lUserFlag & MIDIEVENT_ALIVE) {
+ break;
+ }
+ pNextEvent = pNextEvent->m_pNextEvent;
+ }
+ pHistoryRecord->m_pNextObject = pNextEvent;
+ pPrevEvent = pMIDIEvent->m_pPrevEvent;
+ while (pPrevEvent) {
+ if (pPrevEvent->m_lUserFlag & MIDIEVENT_ALIVE) {
+ break;
+ }
+ pPrevEvent = pPrevEvent->m_pPrevEvent;
+ }
+ pHistoryRecord->m_pPrevObject = pPrevEvent;
+ pHistoryRecord->m_pParent = pMIDIEvent->m_pParent;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_RESISTEREDASINSERTED;
+ //_RPTF4 (_CRT_WARN, "HISTORYRECORD_INSERTEVENT (%08x(%08x), prev=%08x, next=%08x)\n",
+ // (long)pMIDIEvent, pMIDIEvent->m_lData, (long)pPrevEvent, (long)pNextEvent);
+ //FILE* pFile = fopen ("history.txt", "at");
+ //fprintf (pFile, "HISTORYRECORD_INSERTEVENT (%08x(%08x), prev=%08x, next=%08x)\n",
+ // (long)pMIDIEvent, pMIDIEvent->m_lData, (long)pPrevEvent, (long)pNextEvent);
+ //fclose (pFile);
+
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ pMIDIEvent = pMIDIEvent->m_pNextCombinedEvent;
+ lCount++;
+ }
+ break;
+ // MIDIEventオブジェクト除去の記録
+ case HISTORYRECORD_REMOVEEVENT:
+ pMIDIEvent = (MIDIEvent*)pObject;
+ pMIDIEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ ASSERT (pMIDIEvent);
+ while (pMIDIEvent) {
+ ASSERT (pMIDIEvent->m_pParent);
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDIEvent;
+ pHistoryRecord->m_pFirstChild = NULL;
+ pHistoryRecord->m_pLastChild = NULL;
+ pNextEvent = pMIDIEvent->m_pNextEvent;
+ while (pNextEvent) {
+ //TODO 次の判定式両方必要か不明。
+ if (pNextEvent->m_lUserFlag & MIDIEVENT_ALIVE) {
+ //if (!(pNextEvent->m_lUserFlag & MIDIEVENT_DEAD)) {
+ break;
+ }
+ pNextEvent = pNextEvent->m_pNextEvent;
+ }
+ pHistoryRecord->m_pNextObject = pNextEvent;
+ pPrevEvent = pMIDIEvent->m_pPrevEvent;
+ while (pPrevEvent) {
+ //TODO 次の判定式両方必要か不明。
+ if (pPrevEvent->m_lUserFlag & MIDIEVENT_ALIVE) {
+ //if (!(pPrevEvent->m_lUserFlag & MIDIEVENT_DEAD)) {
+ break;
+ }
+ pPrevEvent = pPrevEvent->m_pPrevEvent;
+ }
+ pHistoryRecord->m_pPrevObject = pPrevEvent;
+ pHistoryRecord->m_pParent = pMIDIEvent->m_pParent;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_RESISTEREDASREMOVED;
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ //_RPTF4 (_CRT_WARN, "HISTORYRECORD_REMOVEEVENT (%08x(%08x), prev=%08x, next=%08x)\n",
+ // (long)pMIDIEvent, pMIDIEvent->m_lData, (long)pPrevEvent, (long)pNextEvent);
+ //FILE* pFile = fopen ("history.txt", "at");
+ //fprintf (pFile, "HISTORYRECORD_REMOVEEVENT (%08x(%08x), prev=%08x, next=%08x)\n",
+ // (long)pMIDIEvent, pMIDIEvent->m_lData, (long)pPrevEvent, (long)pNextEvent);
+ //fclose (pFile);
+ pMIDIEvent = pMIDIEvent->m_pNextCombinedEvent;
+ lCount++;
+ }
+ break;
+ // MIDIEventオブジェクト全挿入の記録(20090116追加)
+ case HISTORYRECORD_INSERTEVENTALL:
+ pMIDIEvent = (MIDIEvent*)pObject;
+ ASSERT (pMIDIEvent);
+ while (pMIDIEvent) {
+ ASSERT (pMIDIEvent->m_pParent);
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDIEvent;
+ pHistoryRecord->m_pFirstChild = NULL;
+ pHistoryRecord->m_pLastChild = NULL;
+ pHistoryRecord->m_pNextObject = pMIDIEvent->m_pNextEvent;
+ pHistoryRecord->m_pPrevObject = pMIDIEvent->m_pPrevEvent;
+ pHistoryRecord->m_pParent = pMIDIEvent->m_pParent;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_RESISTEREDASINSERTED;
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ pMIDIEvent = pMIDIEvent->m_pNextEvent;
+ lCount++;
+ }
+ break;
+ // MIDIEventオブジェクト全除去の記録(20090116追加)
+ case HISTORYRECORD_REMOVEEVENTALL:
+ pMIDIEvent = (MIDIEvent*)pObject;
+ ASSERT (pMIDIEvent);
+ while (pMIDIEvent) {
+ ASSERT (pMIDIEvent->m_pParent);
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDIEvent;
+ pHistoryRecord->m_pFirstChild = NULL;
+ pHistoryRecord->m_pLastChild = NULL;
+ pHistoryRecord->m_pNextObject = pMIDIEvent->m_pNextEvent;
+ pHistoryRecord->m_pPrevObject =pMIDIEvent->m_pPrevEvent;
+ pHistoryRecord->m_pParent = pMIDIEvent->m_pParent;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_RESISTEREDASREMOVED;
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ pMIDIEvent = pMIDIEvent->m_pNextEvent;
+ lCount++;
+ }
+ break;
+ // MIDITrackオブジェクト挿入の記録
+ case HISTORYRECORD_INSERTTRACK:
+ pMIDITrack = (MIDITrack*)pObject;
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDITrack;
+ pHistoryRecord->m_pFirstChild = pMIDITrack->m_pFirstEvent;
+ pHistoryRecord->m_pLastChild = pMIDITrack->m_pLastEvent;
+ pHistoryRecord->m_pPrevObject = pMIDITrack->m_pPrevTrack;
+ pHistoryRecord->m_pNextObject = pMIDITrack->m_pNextTrack;
+ pHistoryRecord->m_pParent = pMIDITrack->m_pParent;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag |= MIDITRACK_RESISTEREDASINSERTED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ }
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ lCount = 1;
+ break;
+ // MIDITrackオブジェクト除去の記録
+ case HISTORYRECORD_REMOVETRACK:
+ pMIDITrack = (MIDITrack*)pObject;
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDITrack;
+ pHistoryRecord->m_pFirstChild = pMIDITrack->m_pFirstEvent;
+ pHistoryRecord->m_pLastChild = pMIDITrack->m_pLastEvent;
+ pHistoryRecord->m_pPrevObject = pMIDITrack->m_pPrevTrack;
+ pHistoryRecord->m_pNextObject = pMIDITrack->m_pNextTrack;
+ pHistoryRecord->m_pParent = pMIDITrack->m_pParent;
+ pMIDITrack->m_lUserFlag |= MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag |= MIDITRACK_RESISTEREDASREMOVED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ }
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ lCount = 1;
+ break;
+
+ // MIDIDataオブジェクト挿入の記録
+ case HISTORYRECORD_INSERTDATA:
+ pMIDIData = (MIDIData*)pObject;
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDIData;
+ pHistoryRecord->m_pFirstChild = pMIDIData->m_pFirstTrack;
+ pHistoryRecord->m_pLastChild = pMIDIData->m_pLastTrack;
+ pHistoryRecord->m_pPrevObject = NULL;
+ pHistoryRecord->m_pNextObject = NULL;
+ pHistoryRecord->m_pParent = NULL;
+ pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ pMIDIData->m_lUserFlag |= MIDIDATA_RESISTEREDASINSERTED;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ }
+ }
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ lCount = 1;
+ break;
+ // MIDIDataオブジェクト除去の記録
+ case HISTORYRECORD_REMOVEDATA:
+ pMIDIData = (MIDIData*)pObject;
+ pHistoryRecord = new CHistoryRecord ();
+ pHistoryRecord->m_lType = lType;
+ pHistoryRecord->m_pObject = pMIDIData;
+ pHistoryRecord->m_pFirstChild = pMIDIData->m_pFirstTrack;
+ pHistoryRecord->m_pLastChild = pMIDIData->m_pLastTrack;
+ pHistoryRecord->m_pPrevObject = NULL;
+ pHistoryRecord->m_pNextObject = NULL;
+ pHistoryRecord->m_pParent = NULL;
+ pMIDIData->m_lUserFlag |= MIDIDATA_DEAD;
+ pMIDIData->m_lUserFlag &= ~MIDIDATA_ALIVE;
+ pMIDIData->m_lUserFlag |= MIDIDATA_RESISTEREDASREMOVED;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_ALIVE;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ }
+ }
+ m_theHistoryRecordArray.Add (pHistoryRecord);
+ lCount = 1;
+ break;
+ }
+ return lCount;
+}
diff --git a/src/HistoryUnit.h b/src/HistoryUnit.h
new file mode 100644
index 0000000..342fd9d
--- /dev/null
+++ b/src/HistoryUnit.h
@@ -0,0 +1,48 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 履歴ユニットクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _HISTORYUNIT_H_
+#define _HISTORYUNIT_H_
+
+class CHistoryUnit {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strName; // この履歴ユニットの名前
+ CTime m_theTime; // この履歴ユニットが記録された時刻
+ CPtrArray m_theHistoryRecordArray; // この履歴ユニットが持つ履歴記録(複数)へのポインタ配列
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CHistoryUnit (); // コンストラクタ
+ virtual ~CHistoryUnit (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual long AddHistoryRecord (long lType, void* pObject);
+
+};
+
+#endif
diff --git a/src/InplaceEdit.cpp b/src/InplaceEdit.cpp
new file mode 100644
index 0000000..631e068
--- /dev/null
+++ b/src/InplaceEdit.cpp
@@ -0,0 +1,98 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// インプレースエディットクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+
+#include "InplaceEdit.h"
+
+
+// アロケーションの監視
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CInplaceEdit, CEdit)
+
+BEGIN_MESSAGE_MAP (CInplaceEdit, CEdit)
+ ON_WM_KILLFOCUS ()
+ ON_WM_KEYDOWN ()
+ ON_WM_CHAR ()
+END_MESSAGE_MAP()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CInplaceEdit::CInplaceEdit () {
+}
+
+// デストラクタ
+CInplaceEdit::~CInplaceEdit () {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// フォーカスが失われたとき
+void CInplaceEdit::OnKillFocus (CWnd* pNewWnd) {
+ _RPTF1 (_CRT_WARN, "CInplaceEditBox::OnKillFocus (pNewWnd=0x%08x)\n", pNewWnd);
+ CWnd* pParentWnd = GetParent ();
+ if (pParentWnd != pNewWnd) {
+ pParentWnd->SendMessage (WM_KILLFOCUS, (WPARAM)pNewWnd, (LPARAM)0L);
+ }
+ else {
+ //pParentWnd->SetFocus ();
+ }
+ CEdit::OnKillFocus (pNewWnd); //20080809追加(カレットの消失防止)
+}
+
+// キー押し下げ時
+void CInplaceEdit::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CWnd* pParentWnd = GetParent ();
+ switch (nChar) {
+ case VK_RETURN:
+ //GetParent ()->SendMessage (WM_KEYDOWN, VK_RETURN, (nRepCnt << 16) | nFlags);
+ pParentWnd->SetFocus ();
+ pParentWnd->PostMessage (WM_KEYDOWN, VK_RETURN, (nRepCnt << 16) | nFlags);
+ break;
+ case VK_ESCAPE:
+ //GetParent ()->SendMessage (WM_KEYDOWN, VK_ESCAPE, (nRepCnt << 16) | nFlags);
+ pParentWnd->SetFocus ();
+ pParentWnd->PostMessage (WM_KEYDOWN, VK_ESCAPE, (nRepCnt << 16) | nFlags);
+ break;
+ }
+ CEdit::OnKeyDown (nChar, nRepCnt, nFlags);
+}
+
+// 文字入力時
+void CInplaceEdit::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ // Enterを押したときにプープー音が鳴るのを防ぐ
+ switch (nChar) {
+ case VK_RETURN:
+ return;
+ }
+ CEdit::OnChar (nChar, nRepCnt, nFlags);
+}
diff --git a/src/InplaceEdit.h b/src/InplaceEdit.h
new file mode 100644
index 0000000..5ec9166
--- /dev/null
+++ b/src/InplaceEdit.h
@@ -0,0 +1,46 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// インプレースエディットクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _INPLACEEDIT_H_
+#define _INPLACEEDIT_H_
+
+class CInplaceEdit : public CEdit {
+
+ DECLARE_DYNCREATE (CInplaceEdit);
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CInplaceEdit (); // コンストラクタ
+ virtual ~CInplaceEdit (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnKillFocus (CWnd* pNewWnd);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags);
+ DECLARE_MESSAGE_MAP()
+
+};
+
+#endif
diff --git a/src/InplaceListBox.cpp b/src/InplaceListBox.cpp
new file mode 100644
index 0000000..25ac80b
--- /dev/null
+++ b/src/InplaceListBox.cpp
@@ -0,0 +1,103 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// インプレースリストボックスクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+
+#include "InplaceListBox.h"
+
+
+// アロケーションの監視
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CInplaceListBox, CListBox)
+
+BEGIN_MESSAGE_MAP (CInplaceListBox, CListBox)
+ ON_WM_KILLFOCUS ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDBLCLK ()
+END_MESSAGE_MAP()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CInplaceListBox::CInplaceListBox () {
+
+}
+
+// デストラクタ
+CInplaceListBox::~CInplaceListBox () {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// フォーカスが失われたとき
+void CInplaceListBox::OnKillFocus (CWnd* pNewWnd) {
+ _RPTF1 (_CRT_WARN, "CInplaceListBox::OnKillFocus (pNewWnd=0x%08x)\n", pNewWnd);
+ CWnd* pParentWnd = GetParent ();
+ if (pParentWnd != pNewWnd) {
+ pParentWnd->SendMessage (WM_KILLFOCUS, (WPARAM)pNewWnd, (LPARAM)0L);
+ }
+ else {
+ //pParentWnd->SetFocus ();
+ }
+}
+
+// キー押し下げ時
+void CInplaceListBox::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CWnd* pParentWnd = GetParent ();
+ switch (nChar) {
+ case VK_UP:
+ case VK_LEFT:
+ case VK_RIGHT:
+ case VK_DOWN:
+ //TODO:上下左右キーは編集終了か選択できるようにしておく
+ //GetParent ()->SendMessage (WM_KEYDOWN, VK_RETURN, (nRepCnt << 16) | nFlags);
+ //GetParent ()->PostMessage (WM_KEYDOWN, nChar, (nRepCnt << 16) | nFlags);
+ break;
+ return;
+ case VK_RETURN:
+ //GetParent ()->SendMessage (WM_KEYDOWN, VK_RETURN, (nRepCnt << 16) | nFlags);
+ pParentWnd->SetFocus ();
+ pParentWnd->PostMessage (WM_KEYDOWN, VK_RETURN, (nRepCnt << 16) | nFlags);
+ break;
+ case VK_ESCAPE:
+ //GetParent ()->SendMessage (WM_KEYDOWN, VK_ESCAPE, (nRepCnt << 16) | nFlags);
+ pParentWnd->SetFocus ();
+ pParentWnd->PostMessage (WM_KEYDOWN, VK_ESCAPE, (nRepCnt << 16) | nFlags);
+ break;
+ }
+ CListBox::OnKeyDown (nChar, nRepCnt, nFlags);
+}
+
+// マウス左ボタンダブルクリック時
+void CInplaceListBox::OnLButtonDblClk (UINT nFlags, CPoint point) {
+ // 選択項目の確定信号(VK_RETURN)を親ウィンドウに送る
+ GetParent ()->SendMessage (WM_KEYDOWN, VK_RETURN, (1 << 16) | 0);
+ CListBox::OnLButtonDblClk (nFlags, point);
+}
diff --git a/src/InplaceListBox.h b/src/InplaceListBox.h
new file mode 100644
index 0000000..14571e1
--- /dev/null
+++ b/src/InplaceListBox.h
@@ -0,0 +1,48 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// インプレースリストボックスクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _INPLACELISTBOX_H_
+#define _INPLACELISTBOX_H_
+
+class CInplaceListBox : public CListBox {
+
+ DECLARE_DYNCREATE (CInplaceListBox);
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CInplaceListBox (); // コンストラクタ
+ virtual ~CInplaceListBox (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnKillFocus (CWnd* pNewWnd);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP()
+
+};
+
+
+#endif
+
diff --git a/src/LanguageDlg.cpp b/src/LanguageDlg.cpp
new file mode 100644
index 0000000..bf26f6d
--- /dev/null
+++ b/src/LanguageDlg.cpp
@@ -0,0 +1,101 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 言語ダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "LanguageDlg.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CLanguageDlg::CLanguageDlg () : CDialog (CLanguageDlg::IDD) {
+ m_strLanguage = _T("");
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 言語コンボボックスの充満
+BOOL CLanguageDlg::FillLanguageCombo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_LANGUAGE_COMBO);
+ if (pComboBox == NULL) {
+ return FALSE;
+ }
+ pComboBox->ResetContent ();
+ TCHAR* pszLanguage[] = {_T("Japanese"), _T("English")};
+ long i = 0;
+ for (i = 0; i < sizeof (pszLanguage) / sizeof (pszLanguage[0]); i++) {
+ pComboBox->AddString (pszLanguage[i]);
+ if (pSekaijuApp->m_strLanguage.Compare (pszLanguage[i]) == 0) {
+ pComboBox->SetCurSel (i);
+ }
+ }
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CLanguageDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+
+ DDX_CBString (pDX, IDC_LANGUAGE_COMBO, m_strLanguage);
+}
+
+// ダイアログの初期化
+BOOL CLanguageDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ FillLanguageCombo ();
+ return bRet;
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CLanguageDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
+
+
diff --git a/src/LanguageDlg.h b/src/LanguageDlg.h
new file mode 100644
index 0000000..7bf7dc5
--- /dev/null
+++ b/src/LanguageDlg.h
@@ -0,0 +1,57 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 言語ダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _LANGUAGEDLG_H_
+#define _LANGUAGEDLG_H_
+
+class CLanguageDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // メンバ変数
+ //--------------------------------------------------------------------------
+public:
+ CString m_strLanguage; // 言語名
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CLanguageDlg(); // コンストラクタ
+ enum {IDD = IDD_LANGUAGE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ BOOL FillLanguageCombo ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/MIDIDeviceSheet.cpp b/src/MIDIDeviceSheet.cpp
new file mode 100644
index 0000000..f8ee5bb
--- /dev/null
+++ b/src/MIDIDeviceSheet.cpp
@@ -0,0 +1,93 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDIデバイスプロパティシートクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInDevicePage.h"
+#include "MIDIOutDevicePage.h"
+#include "MIDIInstDefNormPage.h"
+#include "MIDIInstDefDrumPage.h"
+#include "MIDIDeviceSheet.h"
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDIDeviceSheet::CMIDIDeviceSheet (CWnd* pParentWnd)
+ :CPropertySheet (IDS_MIDIDEVICE_AND_INSTRUMENT, pParentWnd) {
+ AddPage (&m_theMIDIInDevicePage);
+ AddPage (&m_theMIDIOutDevicePage);
+ AddPage (&m_theMIDIInstDefNormPage);
+ AddPage (&m_theMIDIInstDefDrumPage);
+}
+
+// デストラクタ
+CMIDIDeviceSheet::~CMIDIDeviceSheet () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 初期化時
+BOOL CMIDIDeviceSheet::OnInitDialog() {
+ BOOL bResult = CPropertySheet::OnInitDialog();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ SetActivePage (pSekaijuApp->m_theCurrentPage.m_lMIDIDevice);
+ return bResult;
+}
+
+// コマンド時
+BOOL CMIDIDeviceSheet::OnCommand (WPARAM wParam, LPARAM lParam) {
+ // 『OK』又は『キャンセル』ボタンが押された
+ if (LOWORD (wParam) == IDOK || LOWORD (wParam) == IDCANCEL) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ pSekaijuApp->m_theCurrentPage.m_lMIDIDevice = GetActiveIndex ();
+ }
+ return CPropertySheet::OnCommand(wParam, lParam);
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CMIDIDeviceSheet, CPropertySheet)
+ ON_BN_CLICKED (ID_APPLY_NOW, OnApplyNow)
+END_MESSAGE_MAP ()
+
+// 『適用』ボタンが押された
+void CMIDIDeviceSheet::OnApplyNow () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ GetActivePage ()->UpdateData (TRUE);
+ pSekaijuApp->ApplyMIDIDeviceSheet (this);
+ m_theMIDIInDevicePage.SetModified (FALSE);
+ m_theMIDIOutDevicePage.SetModified (FALSE);
+ m_theMIDIInstDefNormPage.SetModified (FALSE);
+ m_theMIDIInstDefDrumPage.SetModified (FALSE);
+}
+
diff --git a/src/MIDIDeviceSheet.h b/src/MIDIDeviceSheet.h
new file mode 100644
index 0000000..4476561
--- /dev/null
+++ b/src/MIDIDeviceSheet.h
@@ -0,0 +1,59 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDIデバイスプロパティシートクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MIDIDEVICESHEET_H_
+#define _MIDIDEVICESHEET_H_
+
+#include "MIDIInDevicePage.h"
+#include "MIDIOutDevicePage.h"
+#include "MIDIInstDefNormPage.h"
+#include "MIDIInstDefDrumPage.h"
+
+class CMIDIDeviceSheet : public CPropertySheet {
+ //--------------------------------------------------------------------------
+ // 各プロパティページ
+ //--------------------------------------------------------------------------
+public:
+ CMIDIInDevicePage m_theMIDIInDevicePage; // MIDI入力デバイスページ
+ CMIDIOutDevicePage m_theMIDIOutDevicePage; // MIDI出力デバイスページ
+ CMIDIInstDefNormPage m_theMIDIInstDefNormPage; // MIDIインストゥルメント(通常)ページ
+ CMIDIInstDefDrumPage m_theMIDIInstDefDrumPage; // MIDIインストゥルメント(ドラム)ページ
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMIDIDeviceSheet (CWnd* pParentWnd); // コンストラクタ
+ virtual ~CMIDIDeviceSheet (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+ virtual BOOL OnInitDialog ();
+ virtual BOOL OnCommand (WPARAM wParam, LPARAM lParam);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnApplyNow ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/MIDIInDevicePage.cpp b/src/MIDIInDevicePage.cpp
new file mode 100644
index 0000000..a8814e8
--- /dev/null
+++ b/src/MIDIInDevicePage.cpp
@@ -0,0 +1,122 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI入力デバイスページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInDevicePage.h"
+#include "MIDIOutDevicePage.h"
+#include "MIDIInstDefNormPage.h"
+#include "MIDIInstDefDrumPage.h"
+#include "MIDIDeviceSheet.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE (CMIDIInDevicePage, CPropertyPage)
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDIInDevicePage::CMIDIInDevicePage () :
+CPropertyPage (IDD_MIDIINDEVICE) {
+}
+
+// デストラクタ
+CMIDIInDevicePage::~CMIDIInDevicePage () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+void CMIDIInDevicePage::DoDataExchange (CDataExchange* pDX) {
+ long i;
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ // 20100126:空文字列対応
+ // コントロール→メンバ変数
+ if (pDX->m_bSaveAndValidate) {
+ if (((CComboBox*)GetDlgItem (IDC_MIDIINDEVICE_01 + i))->GetCurSel () == 0) {
+ m_strMIDIInName[i] = _T("");
+ }
+ else {
+ DDX_CBString (pDX, IDC_MIDIINDEVICE_01 + i, m_strMIDIInName[i]);
+ }
+ }
+ // メンバ変数→コントロール
+ else {
+ if (m_strMIDIInName[i] == _T("")) {
+ ((CComboBox*)GetDlgItem (IDC_MIDIINDEVICE_01 + i))->SetCurSel (0);
+ }
+ else {
+ DDX_CBString (pDX, IDC_MIDIINDEVICE_01 + i, m_strMIDIInName[i]);
+ }
+ }
+ }
+}
+
+// ダイアログの初期化
+BOOL CMIDIInDevicePage::OnInitDialog () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CString strNone;
+ VERIFY (strNone.LoadString (IDS_NONE));
+ long lNum = MIDIIn_GetDeviceNum ();
+ /* 20081219 MIDIIn_GetDeviceNameが大変遅いのでループ順序変更 */
+ long lPort, j;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIINDEVICE_01 + lPort);
+ pComboBox->AddString (strNone);
+ }
+ for (j = 0; j < lNum; j++) {
+ TCHAR szName[256];
+ memset (szName, 0, sizeof (szName));
+ MIDIIn_GetDeviceName (j, szName, 255);
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIINDEVICE_01 + lPort);
+ pComboBox->AddString (szName);
+ }
+ }
+ CDialog::OnInitDialog(); // AddStringは基本関数の呼び出しより前(20090625)
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CMIDIInDevicePage, CPropertyPage)
+ ON_CONTROL_RANGE (CBN_SELCHANGE, IDC_MIDIINDEVICE_01, IDC_MIDIINDEVICE_16, OnSelChange)
+END_MESSAGE_MAP ()
+
+
+void CMIDIInDevicePage::OnSelChange (UINT nID) {
+ SetModified (TRUE);
+}
diff --git a/src/MIDIInDevicePage.h b/src/MIDIInDevicePage.h
new file mode 100644
index 0000000..fdc817d
--- /dev/null
+++ b/src/MIDIInDevicePage.h
@@ -0,0 +1,55 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI入力デバイスページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MIDIINDEVICEPAGE_H_
+#define _MIDIINDEVICEPAGE_H_
+
+class CMIDIInDevicePage : public CPropertyPage {
+ DECLARE_DYNCREATE (CMIDIInDevicePage)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+ CString m_strMIDIInName[MAXMIDIINDEVICENUM]; // MIDIInデバイス名[0〜15]
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMIDIInDevicePage (); // コンストラクタ
+ virtual ~CMIDIInDevicePage (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnSelChange (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/MIDIInSyncModePage.cpp b/src/MIDIInSyncModePage.cpp
new file mode 100644
index 0000000..11d6e5a
--- /dev/null
+++ b/src/MIDIInSyncModePage.cpp
@@ -0,0 +1,104 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI入力同期モードページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInSyncModePage.h"
+#include "MIDIOutSyncModePage.h"
+#include "MIDISyncModeSheet.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+
+
+IMPLEMENT_DYNCREATE (CMIDIInSyncModePage, CPropertyPage)
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDIInSyncModePage::CMIDIInSyncModePage () :
+CPropertyPage (IDD_MIDIINSYNCMODE) {
+}
+
+// デストラクタ
+CMIDIInSyncModePage::~CMIDIInSyncModePage () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+void CMIDIInSyncModePage::DoDataExchange (CDataExchange* pDX) {
+ long i;
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ DDX_CBIndex (pDX, IDC_MIDIINSYNCMODE_01 + i, m_nMIDIInSyncMode[i]);
+ }
+}
+
+// ダイアログの初期化
+BOOL CMIDIInSyncModePage::OnInitDialog () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lPort;
+ CString strItem[3];
+ VERIFY (strItem[0].LoadString (IDS_NONE));
+ VERIFY (strItem[1].LoadString (IDS_RECEIVE_MIDI_TIMING_CLOCK));
+ VERIFY (strItem[2].LoadString (IDS_RECEIVE_SMPTE_MTC));
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIINSYNCMODE_01 + lPort);
+ pComboBox->AddString (strItem[0]);
+ pComboBox->AddString (strItem[1]);
+ pComboBox->AddString (strItem[2]);
+ }
+ CDialog::OnInitDialog(); // AddStringは基本関数の呼び出しより前(20090625)
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CMIDIInSyncModePage, CPropertyPage)
+ ON_CONTROL_RANGE (CBN_SELCHANGE, IDC_MIDIINSYNCMODE_01, IDC_MIDIINSYNCMODE_16, OnSelChange)
+END_MESSAGE_MAP ()
+
+void CMIDIInSyncModePage::OnSelChange (UINT nID) {
+ long lPort;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ if ((long)nID != IDC_MIDIINSYNCMODE_01 + lPort) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIINSYNCMODE_01 + lPort);
+ pComboBox->SetCurSel (0);
+ }
+ }
+ SetModified (TRUE);
+}
diff --git a/src/MIDIInSyncModePage.h b/src/MIDIInSyncModePage.h
new file mode 100644
index 0000000..1fbb32d
--- /dev/null
+++ b/src/MIDIInSyncModePage.h
@@ -0,0 +1,57 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI入力同期モードページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MIDIINSYNCMODEPAGE_H_
+#define _MIDIINSYNCMODEPAGE_H_
+
+
+class CMIDIInSyncModePage : public CPropertyPage {
+ DECLARE_DYNCREATE (CMIDIInSyncModePage)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ int m_nMIDIInSyncMode[MAXMIDIINDEVICENUM]; // MIDI入力同期モード[0〜15]
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMIDIInSyncModePage (); // コンストラクタ
+ virtual ~CMIDIInSyncModePage (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnSelChange (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/MIDIInstDefDrumPage.cpp b/src/MIDIInstDefDrumPage.cpp
new file mode 100644
index 0000000..b78dd95
--- /dev/null
+++ b/src/MIDIInstDefDrumPage.cpp
@@ -0,0 +1,112 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDIインストゥルメント定義(ドラム)ページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInDevicePage.h"
+#include "MIDIOutDevicePage.h"
+#include "MIDIInstDefNormPage.h"
+#include "MIDIInstDefDrumPage.h"
+#include "MIDIDeviceSheet.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+
+
+IMPLEMENT_DYNCREATE (CMIDIInstDefDrumPage, CPropertyPage)
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDIInstDefDrumPage::CMIDIInstDefDrumPage () :
+CPropertyPage (IDD_MIDIINSTDEFDRUM) {
+}
+
+// デストラクタ
+CMIDIInstDefDrumPage::~CMIDIInstDefDrumPage () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CMIDIInstDefDrumPage::DoDataExchange (CDataExchange* pDX) {
+ long i;
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ DDX_CBString (pDX, IDC_MIDIINSTDEFDRUM_01 + i, m_strMIDIInstDefDrumName[i]);
+ }
+}
+
+// ダイアログの初期化
+BOOL CMIDIInstDefDrumPage::OnInitDialog () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lNum = MIDIIn_GetDeviceNum ();
+ for (long lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ MIDIInstrumentDefinition* pMIDIInstDef;
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIINSTDEFDRUM_01 + lPort);
+ int nIndex = 0;
+ long i = 0;
+ for (i = 0; i < MAXMIDIINSTRUMENTNUM; i++) {
+ if (pSekaijuApp->m_pMIDIInstrument[i] != NULL) {
+ forEachInstrumentDefinition (pSekaijuApp->m_pMIDIInstrument[i], pMIDIInstDef) {
+ TCHAR szName[256];
+ memset (szName, 0, sizeof (szName));
+ MIDIInstrumentDefinition_GetTitle (pMIDIInstDef, szName, 255);
+ pComboBox->AddString (szName);
+ if (_tcscmp (szName, pSekaijuApp->m_strMIDIInstDefDrumName[lPort]) == 0) {
+ pComboBox->SetCurSel (nIndex);
+ }
+ nIndex++;
+ }
+ }
+ }
+ }
+ CDialog::OnInitDialog(); // AddStringは基本関数の呼び出しより前(20090625)
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CMIDIInstDefDrumPage, CPropertyPage)
+ ON_CONTROL_RANGE (CBN_SELCHANGE, IDC_MIDIINSTDEFNORM_01, IDC_MIDIINSTDEFNORM_16, OnSelChange)
+END_MESSAGE_MAP ()
+
+void CMIDIInstDefDrumPage::OnSelChange (UINT nID) {
+ SetModified (TRUE);
+}
diff --git a/src/MIDIInstDefDrumPage.h b/src/MIDIInstDefDrumPage.h
new file mode 100644
index 0000000..b110c3b
--- /dev/null
+++ b/src/MIDIInstDefDrumPage.h
@@ -0,0 +1,58 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDIインストゥルメント定義(ドラム)ページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+
+#ifndef _MIDIINSTDEFDRUMPAGE_H_
+#define _MIDIINSTDEFDRUMPAGE_H_
+
+class CMIDIInstDefDrumPage : public CPropertyPage {
+ DECLARE_DYNCREATE (CMIDIInstDefDrumPage)
+
+ //--------------------------------------------------------------------------
+ // メンバ変数
+ //--------------------------------------------------------------------------
+public:
+ CString m_strMIDIInstDefDrumName[MAXMIDIOUTDEVICENUM]; // MIDIインストゥルメント(ドラム)名
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMIDIInstDefDrumPage (); // コンストラクタ
+ virtual ~CMIDIInstDefDrumPage (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnSelChange (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+
+#endif
diff --git a/src/MIDIInstDefNormPage.cpp b/src/MIDIInstDefNormPage.cpp
new file mode 100644
index 0000000..8f2392b
--- /dev/null
+++ b/src/MIDIInstDefNormPage.cpp
@@ -0,0 +1,111 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDIインストゥルメント定義(通常)ページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInDevicePage.h"
+#include "MIDIOutDevicePage.h"
+#include "MIDIInstDefNormPage.h"
+#include "MIDIInstDefDrumPage.h"
+#include "MIDIDeviceSheet.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CMIDIInstDefNormPage, CPropertyPage)
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDIInstDefNormPage::CMIDIInstDefNormPage () :
+CPropertyPage (IDD_MIDIINSTDEFNORM) {
+}
+
+// デストラクタ
+CMIDIInstDefNormPage::~CMIDIInstDefNormPage () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CMIDIInstDefNormPage::DoDataExchange (CDataExchange* pDX) {
+ long i;
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ DDX_CBString (pDX, IDC_MIDIINSTDEFNORM_01 + i, m_strMIDIInstDefNormName[i]);
+ }
+}
+
+// ダイアログの初期化
+BOOL CMIDIInstDefNormPage::OnInitDialog () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lNum = MIDIIn_GetDeviceNum ();
+ long lPort = 0;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ MIDIInstrumentDefinition* pMIDIInstDef;
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIINSTDEFNORM_01 + lPort);
+ int nIndex = 0;
+ long i = 0;
+ for (i = 0; i < MAXMIDIINSTRUMENTNUM; i++) {
+ if (pSekaijuApp->m_pMIDIInstrument[i] != NULL) {
+ forEachInstrumentDefinition (pSekaijuApp->m_pMIDIInstrument[i], pMIDIInstDef) {
+ TCHAR szName[256];
+ memset (szName, 0, sizeof (szName));
+ MIDIInstrumentDefinition_GetTitle (pMIDIInstDef, szName, 255);
+ pComboBox->AddString (szName);
+ if (_tcscmp (szName, pSekaijuApp->m_strMIDIInstDefNormName[lPort]) == 0) {
+ pComboBox->SetCurSel (nIndex);
+ }
+ nIndex++;
+ }
+ }
+ }
+ }
+ CDialog::OnInitDialog(); // AddStringは基本関数の呼び出しより前(20090625)
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CMIDIInstDefNormPage, CPropertyPage)
+ ON_CONTROL_RANGE (CBN_SELCHANGE, IDC_MIDIINSTDEFNORM_01, IDC_MIDIINSTDEFNORM_16, OnSelChange)
+END_MESSAGE_MAP ()
+
+void CMIDIInstDefNormPage::OnSelChange (UINT nID) {
+ SetModified (TRUE);
+}
diff --git a/src/MIDIInstDefNormPage.h b/src/MIDIInstDefNormPage.h
new file mode 100644
index 0000000..ef51ee0
--- /dev/null
+++ b/src/MIDIInstDefNormPage.h
@@ -0,0 +1,56 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDIインストゥルメント定義(通常)ページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MIDIINSTDEFNORMPAGE_H_
+#define _MIDIINSTDEFNORMPAGE_H_
+
+class CMIDIInstDefNormPage : public CPropertyPage {
+ DECLARE_DYNCREATE (CMIDIInstDefNormPage)
+
+ //--------------------------------------------------------------------------
+ // メンバ変数
+ //--------------------------------------------------------------------------
+public:
+ CString m_strMIDIInstDefNormName[MAXMIDIOUTDEVICENUM]; // MIDIインストゥルメント(通常)名
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMIDIInstDefNormPage (); // コンストラクタ
+ virtual ~CMIDIInstDefNormPage (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnSelChange (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/MIDIOutDevicePage.cpp b/src/MIDIOutDevicePage.cpp
new file mode 100644
index 0000000..345688f
--- /dev/null
+++ b/src/MIDIOutDevicePage.cpp
@@ -0,0 +1,138 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI出力デバイスページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInDevicePage.h"
+#include "MIDIOutDevicePage.h"
+#include "MIDIInstDefNormPage.h"
+#include "MIDIInstDefDrumPage.h"
+#include "MIDIDeviceSheet.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+
+
+IMPLEMENT_DYNCREATE (CMIDIOutDevicePage, CPropertyPage)
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDIOutDevicePage::CMIDIOutDevicePage () :
+CPropertyPage (IDD_MIDIOUTDEVICE) {
+}
+
+// デストラクタ
+CMIDIOutDevicePage::~CMIDIOutDevicePage () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+void CMIDIOutDevicePage::DoDataExchange (CDataExchange* pDX) {
+ CString strMIDIMapper;
+ VERIFY (strMIDIMapper.LoadString (IDS_MIDI_MAPPER));
+ long i;
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ // 20100126:空文字列対応
+ // コントロール→メンバ変数
+ if (pDX->m_bSaveAndValidate) {
+ if (((CComboBox*)GetDlgItem (IDC_MIDIOUTDEVICE_01 + i))->GetCurSel () == 0) {
+ m_strMIDIOutName[i] = _T("");
+ }
+ else if (((CComboBox*)GetDlgItem (IDC_MIDIOUTDEVICE_01 + i))->GetCurSel () == 1) {
+ m_strMIDIOutName[i] = MIDIIO_MIDIMAPPER;
+ }
+ else {
+ DDX_CBString (pDX, IDC_MIDIOUTDEVICE_01 + i, m_strMIDIOutName[i]);
+ }
+ }
+ // メンバ変数→コントロール
+ else {
+ if (m_strMIDIOutName[i] == _T("")) {
+ ((CComboBox*)GetDlgItem (IDC_MIDIOUTDEVICE_01 + i))->SetCurSel (0);
+ }
+ else if (m_strMIDIOutName[i] == MIDIIO_MIDIMAPPER ||
+ m_strMIDIOutName[i] == MIDIIO_MIDIMAPPERJ ||
+ m_strMIDIOutName[i] == strMIDIMapper) {
+ ((CComboBox*)GetDlgItem (IDC_MIDIOUTDEVICE_01 + i))->SetCurSel (1);
+ }
+ else {
+ DDX_CBString (pDX, IDC_MIDIOUTDEVICE_01 + i, m_strMIDIOutName[i]);
+ }
+ }
+ }
+}
+
+// ダイアログの初期化
+BOOL CMIDIOutDevicePage::OnInitDialog () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lNum = MIDIOut_GetDeviceNum ();
+ /* 20081219 MIDIOut_GetDeviceNameが大変遅いのでループ順序変更 */
+ long lPort, j;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIOUTDEVICE_01 + lPort);
+ CString strNone;
+ VERIFY (strNone.LoadString (IDS_NONE));
+ pComboBox->AddString (strNone);
+ //CString strMIDIMapper;
+ //VERIFY (strMIDIMapper.LoadString (IDS_MIDI_MAPPER));
+ //pComboBox->AddString (strMIDIMapper);
+ pComboBox->AddString (_T(MIDIIO_MIDIMAPPER));
+ }
+ for (j = 0; j < lNum; j++) {
+ TCHAR szName[256];
+ memset (szName, 0, sizeof (szName));
+ MIDIOut_GetDeviceName (j, szName, 255);
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIOUTDEVICE_01 + lPort);
+ pComboBox->AddString (szName);
+ }
+ }
+ CDialog::OnInitDialog(); // AddStringは基本関数の呼び出しより前(20090625)
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CMIDIOutDevicePage, CPropertyPage)
+ ON_CONTROL_RANGE (CBN_SELCHANGE, IDC_MIDIOUTDEVICE_01, IDC_MIDIOUTDEVICE_16, OnSelChange)
+END_MESSAGE_MAP ()
+
+void CMIDIOutDevicePage::OnSelChange (UINT nID) {
+ SetModified (TRUE);
+}
diff --git a/src/MIDIOutDevicePage.h b/src/MIDIOutDevicePage.h
new file mode 100644
index 0000000..16ad6c3
--- /dev/null
+++ b/src/MIDIOutDevicePage.h
@@ -0,0 +1,56 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI出力デバイスページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MIDIOUTDEVICEPAGE_H_
+#define _MIDIOUTDEVICEPAGE_H_
+
+class CMIDIOutDevicePage : public CPropertyPage {
+ DECLARE_DYNCREATE (CMIDIOutDevicePage)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strMIDIOutName[MAXMIDIOUTDEVICENUM]; // MIDI出力同期モード
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMIDIOutDevicePage (); // コンストラクタ
+ virtual ~CMIDIOutDevicePage (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnSelChange (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/MIDIOutSyncModePage.cpp b/src/MIDIOutSyncModePage.cpp
new file mode 100644
index 0000000..e250928
--- /dev/null
+++ b/src/MIDIOutSyncModePage.cpp
@@ -0,0 +1,104 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI出力同期モードページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInSyncModePage.h"
+#include "MIDIOutSyncModePage.h"
+#include "MIDISyncModeSheet.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+
+
+IMPLEMENT_DYNCREATE (CMIDIOutSyncModePage, CPropertyPage)
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDIOutSyncModePage::CMIDIOutSyncModePage () :
+CPropertyPage (IDD_MIDIOUTSYNCMODE) {
+}
+
+// デストラクタ
+CMIDIOutSyncModePage::~CMIDIOutSyncModePage () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CMIDIOutSyncModePage::DoDataExchange (CDataExchange* pDX) {
+ long i;
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ DDX_CBIndex (pDX, IDC_MIDIOUTSYNCMODE_01 + i, m_nMIDIOutSyncMode[i]);
+ }
+}
+
+// ダイアログの初期化
+BOOL CMIDIOutSyncModePage::OnInitDialog () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CString strItem[6];
+ strItem[0].LoadString (IDS_NONE);
+ strItem[1].LoadString (IDS_SEND_MIDI_TIMING_CLOCK);
+ strItem[2].LoadString (IDS_SEND_SMPTE24_MTC);
+ strItem[3].LoadString (IDS_SEND_SMPTE25_MTC);
+ strItem[4].LoadString (IDS_SEND_SMPTE29P97_MTC);
+ strItem[5].LoadString (IDS_SEND_SMPTE30_MTC);
+ long lPort = 0;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_MIDIINSYNCMODE_01 + lPort);
+ pComboBox->AddString (strItem[0]);
+ pComboBox->AddString (strItem[1]);
+ pComboBox->AddString (strItem[2]);
+ pComboBox->AddString (strItem[3]);
+ pComboBox->AddString (strItem[4]);
+ pComboBox->AddString (strItem[5]);
+ }
+ CDialog::OnInitDialog(); // AddStringは基本関数の呼び出しより前(20090625)
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CMIDIOutSyncModePage, CPropertyPage)
+ ON_CONTROL_RANGE (CBN_SELCHANGE, IDC_MIDIOUTSYNCMODE_01, IDC_MIDIOUTSYNCMODE_16, OnSelChange)
+END_MESSAGE_MAP ()
+
+void CMIDIOutSyncModePage::OnSelChange (UINT nID) {
+ SetModified (TRUE);
+}
diff --git a/src/MIDIOutSyncModePage.h b/src/MIDIOutSyncModePage.h
new file mode 100644
index 0000000..136d087
--- /dev/null
+++ b/src/MIDIOutSyncModePage.h
@@ -0,0 +1,57 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI出力同期モードページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MIDIOUTSYNCMODEPAGE_H_
+#define _MIDIOUTSYNCMODEPAGE_H_
+
+
+class CMIDIOutSyncModePage : public CPropertyPage {
+ DECLARE_DYNCREATE (CMIDIOutSyncModePage)
+
+public:
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+ CMIDIOutSyncModePage (); // コンストラクタ
+ virtual ~CMIDIOutSyncModePage (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // メンバ変数
+ //--------------------------------------------------------------------------
+public:
+ int m_nMIDIOutSyncMode[MAXMIDIOUTDEVICENUM];
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX);
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnSelChange (UINT nID);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/MIDISyncModeSheet.cpp b/src/MIDISyncModeSheet.cpp
new file mode 100644
index 0000000..964ac39
--- /dev/null
+++ b/src/MIDISyncModeSheet.cpp
@@ -0,0 +1,66 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI同期モードプロパティシートクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "MIDIInSyncModePage.h"
+#include "MIDIOutSyncModePage.h"
+#include "MIDISyncModeSheet.h"
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMIDISyncModeSheet::CMIDISyncModeSheet (CWnd* pParentWnd) :
+CPropertySheet (IDS_MIDISYNCMODE, pParentWnd) {
+ AddPage (&m_theMIDIInSyncModePage);
+ AddPage (&m_theMIDIOutSyncModePage);
+ //m_nCurPage = iSelectPage;
+}
+
+// デストラクタ
+CMIDISyncModeSheet::~CMIDISyncModeSheet () {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CMIDISyncModeSheet, CPropertySheet)
+ ON_BN_CLICKED (ID_APPLY_NOW, OnApplyNow)
+END_MESSAGE_MAP ()
+
+
+// 『適用』ボタンが押された
+void CMIDISyncModeSheet::OnApplyNow () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ GetActivePage ()->UpdateData (TRUE);
+ pSekaijuApp->ApplyMIDISyncModeSheet (this);
+ m_theMIDIInSyncModePage.SetModified (FALSE);
+ m_theMIDIOutSyncModePage.SetModified (FALSE);
+}
+
diff --git a/src/MIDISyncModeSheet.h b/src/MIDISyncModeSheet.h
new file mode 100644
index 0000000..9562b91
--- /dev/null
+++ b/src/MIDISyncModeSheet.h
@@ -0,0 +1,51 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MIDI同期モードプロパティシートクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MIDISYNCMODESHEET_H_
+#define _MIDISYNCMODESHEET_H_
+
+#include "MIDIInSyncModePage.h"
+#include "MIDIOutSyncModePage.h"
+
+class CMIDISyncModeSheet : public CPropertySheet {
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMIDISyncModeSheet (CWnd* pParentWnd); // コンストラクタ
+ virtual ~CMIDISyncModeSheet (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // 各ページ
+ //--------------------------------------------------------------------------
+public:
+ CMIDIInSyncModePage m_theMIDIInSyncModePage; // MIDI入力同期モードページ
+ CMIDIOutSyncModePage m_theMIDIOutSyncModePage; // MIDI出力同期モードページ
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnApplyNow ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/MainFrame.cpp b/src/MainFrame.cpp
new file mode 100644
index 0000000..e11a4f1
--- /dev/null
+++ b/src/MainFrame.cpp
@@ -0,0 +1,773 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MDI親フレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "SekaijuDoc.h"
+
+
+#ifndef TBSTYLE_ALTDRAG
+#define TBSTYLE_ALTDRAG 0x0400
+#endif
+#ifndef TBSTYLE_FLAT
+#define TBSTYLE_FLAT 0x0800
+#endif
+#ifndef TBSTYLE_LIST
+#define TBSTYLE_LIST 0x1000
+#endif
+
+
+// デバッグ用
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNAMIC (CMainFrame, CMDIFrameWnd)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CMainFrame, CMDIFrameWnd)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_TIMER ()
+ ON_WM_HSCROLL ()
+ ON_WM_MOUSEWHEEL40 ()
+ ON_COMMAND (ID_VIEW_TOOLBAR1, OnViewToolbar1)
+ ON_UPDATE_COMMAND_UI (ID_VIEW_TOOLBAR1, OnUpdateViewToolbar1UI)
+ ON_COMMAND (ID_VIEW_TOOLBAR2, OnViewToolbar2)
+ ON_UPDATE_COMMAND_UI (ID_VIEW_TOOLBAR2, OnUpdateViewToolbar2UI)
+ ON_UPDATE_COMMAND_UI (ID_INDICATOR_INPUTVELOCITY, OnUpdateIndicatorInputVelocityUI)
+ ON_UPDATE_COMMAND_UI (ID_INDICATOR_OUTPUTVELOCITY, OnUpdateIndicatorOutputVelocityUI)
+ ON_UPDATE_COMMAND_UI (ID_INDICATOR_FORMAT, OnUpdateIndicatorFormatUI)
+ ON_UPDATE_COMMAND_UI (ID_INDICATOR_NUMTRACKS, OnUpdateIndicatorNumTracksUI)
+ ON_UPDATE_COMMAND_UI (ID_INDICATOR_TIMEBASE, OnUpdateIndicatorTimeBaseUI)
+
+
+ ON_MESSAGE (WM_COMMANDWAKEUP, OnCommandWakeUp)
+ ON_MESSAGE (WM_COMMANDREADSHM, OnCommandReadShm)
+ ON_MESSAGE (WM_COMMANDFILEOPEN, OnCommandFileOpen)
+END_MESSAGE_MAP ()
+
+// ステータス ライン インジケータ
+static UINT indicators[] = {
+ ID_SEPARATOR,
+ ID_SEPARATOR, // ID_INDICATOR_INPUTVELOCITY
+ ID_SEPARATOR, // ID_INDICATOR_OUTPUTVELOCITY
+ ID_SEPARATOR, // ID_INDICATOR_FORMAT
+ ID_SEPARATOR, // ID_INDICATOR_NUMTRACKS
+ ID_SEPARATOR, // ID_INDICATOR_TIMEBASE
+ ID_INDICATOR_KANA,
+ ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL,
+};
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMainFrame::CMainFrame () {
+ m_strWndClass = AfxGetAppName ();
+ m_strTempFileName = _T("");
+}
+
+// デストラクタ
+CMainFrame::~CMainFrame () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 再生位置スクロールバー(ツールバー2上)の範囲設定
+void CMainFrame::SetPositionScrollRange (long lStartTime, long lEndTime, BOOL bRedraw) {
+ ASSERT (m_wndPositionScroll.GetSafeHwnd ());
+ m_wndPositionScroll.SetScrollRange (lStartTime, lEndTime, bRedraw);
+}
+
+// SetWindowTextのテキストが異なる場合のみ更新するヴァージョン
+int CMainFrame::SetWindowTextWhenDifferent (CWnd* pWnd, LPCTSTR lpszText) {
+ ASSERT (pWnd);
+ CString strCurText;
+ pWnd->GetWindowText (strCurText);
+ if (_tcscmp (strCurText, lpszText) != 0) {
+ pWnd->SetWindowText (lpszText);
+ }
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウ作成直前
+BOOL CMainFrame::PreCreateWindow (CREATESTRUCT& cs) {
+ // 注意:このPreCreateWindowを有効に働かせるためには、
+ // CMainFrameをLoadFrameではなくCreate関数で作成すること。
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // デフォルトのMDIフレーム用WNDCLASSを作成し、登録する。
+ BOOL bRet = CMDIFrameWnd::PreCreateWindow (cs);
+ // cs.lpszClassが"AfxMDIFrame40(d)"になる.
+
+ // メインウィンドウのクラス名をm_strWndClassにする。
+ WNDCLASS wndcls;
+ HINSTANCE hInst = AfxGetInstanceHandle();
+ // m_strWndClassがまだ登録されていない場合
+ if (!::GetClassInfo(hInst, m_strWndClass, &wndcls)) {
+ // デフォルトのWNDCLASSを取得
+ bRet = ::GetClassInfo(hInst, cs.lpszClass, &wndcls);
+ if (bRet) {
+ // デフォルトのWNDCLASSを固定クラス名に改造して登録
+ wndcls.lpszClassName = m_strWndClass;
+ wndcls.hIcon = ::LoadIcon (hInst, MAKEINTRESOURCE(IDR_MAINFRAME));
+ if (::RegisterClass(&wndcls)) {
+ cs.lpszClass = m_strWndClass;
+ }
+ else {
+ bRet = FALSE;
+ }
+ }
+ }
+
+ // csの各メンバ変数を更新する。
+ //cs.hInstance;
+ //cs.hMenu;
+ //cs.hwndParent;
+ // 起動時に前回のウィンドウ位置を復元する場合
+ if (pSekaijuApp->m_theGeneralOption.m_bRestoreWindowPlacement) {
+ // 最小化
+ if (pSekaijuApp->m_theWindowPlacement.m_bIconic ||
+ pSekaijuApp->m_nCmdShow == SW_SHOWMINIMIZED) {
+ cs.cy = CW_USEDEFAULT;
+ cs.cx = CW_USEDEFAULT;
+ cs.y = CW_USEDEFAULT;
+ cs.x = CW_USEDEFAULT;
+ cs.style |= WS_MINIMIZE;
+ }
+ // 最大化
+ else if (pSekaijuApp->m_theWindowPlacement.m_bZoomed ||
+ pSekaijuApp->m_nCmdShow == SW_SHOWMAXIMIZED) {
+ cs.cy = CW_USEDEFAULT;
+ cs.cx = CW_USEDEFAULT;
+ cs.y = CW_USEDEFAULT;
+ cs.x = CW_USEDEFAULT;
+ cs.style |= WS_MAXIMIZE;
+ }
+ // その他
+ else {
+ cs.cy = pSekaijuApp->m_theWindowPlacement.m_nHeight;
+ cs.cx = pSekaijuApp->m_theWindowPlacement.m_nWidth;
+ cs.y = pSekaijuApp->m_theWindowPlacement.m_nY;
+ cs.x = pSekaijuApp->m_theWindowPlacement.m_nX;
+ }
+ }
+ // デフォルトのウィンドウ位置を用いる場合
+ else {
+ cs.cy = CW_USEDEFAULT;
+ cs.cx = CW_USEDEFAULT;
+ cs.y = CW_USEDEFAULT;
+ cs.x = CW_USEDEFAULT;
+ }
+ //cs.lpszName;
+ //cs.lpszClass;
+ //cs.dwExStyle;
+
+ // 注意:最小化と最大化は、ShowWindow時のm_nCmdShowの
+ // 値によって最終的に決まるので、ShowWindowの直前で
+ // m_nCmdShowの値も変更しておかなければならない。
+
+ // return直後のCreateWindowExにcsの各メンバ変数が渡される。
+
+ return bRet;
+}
+
+// 現在アクティブな子フレームウィンドウを取得(なければthis)
+CFrameWnd* CMainFrame::GetActiveFrame () {
+ // check first for MDI client window not created
+ if (m_hWndMDIClient == NULL) {
+ return this;
+ }
+ // MDI client has been created, get active MDI child
+ HWND hWnd = (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0, NULL);
+ if (!::IsWindow (hWnd)) {
+ return this;
+ }
+ CMDIChildWnd* pWnd = (CMDIChildWnd*)CWnd::FromHandle(hWnd);
+ if (pWnd == NULL) {
+ return this;
+ }
+ if (!pWnd->IsKindOf (RUNTIME_CLASS (CMDIChildWnd))) {
+ return this;
+ }
+
+ // check for special pseudo-inactive state
+ if (pWnd != NULL && pWnd->m_bPseudoInactive &&
+ (pWnd->GetStyle () & WS_VISIBLE) == 0) {
+ // Window is hidden, active, but m_bPseudoInactive -- return NULL
+ return this;
+ }
+ return pWnd;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ作成時
+int CMainFrame::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+ CRect rcTemp;
+
+ if (CMDIFrameWnd::OnCreate (lpCreateStruct) == -1) {
+ return -1;
+ }
+
+ // ツールバー1の作成
+ if (!m_wndToolBar1.Create (this) ||
+ !m_wndToolBar1.LoadToolBar (IDR_MAINFRAME1)) {
+ TRACE0 ("Failed to create toolbar\n");
+ return -1;
+ }
+ m_wndToolBar1.SetBarStyle (m_wndToolBar1.GetBarStyle () |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);
+ m_wndToolBar1.EnableDocking (CBRS_ALIGN_ANY);
+ EnableDocking (CBRS_ALIGN_ANY);
+ DockControlBar (&m_wndToolBar1);
+ //m_wndToolBar1.ModifyStyle( 0, TBSTYLE_FLAT );
+
+ // ツールバー2の作成
+ if (!m_wndToolBar2.Create (this) ||
+ !m_wndToolBar2.LoadToolBar (IDR_MAINFRAME2)) {
+ TRACE0 ("Failed to create toolbar\n");
+ return -1;
+ }
+ m_wndToolBar2.SetBarStyle (m_wndToolBar2.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ m_wndToolBar2.EnableDocking (CBRS_ALIGN_ANY);
+ EnableDocking (CBRS_ALIGN_ANY);
+ DockControlBar (&m_wndToolBar2);
+ //m_wndToolBar2.ModifyStyle( 0, TBSTYLE_FLAT );
+
+ // 時:分:秒:ミリ秒の作成
+ m_wndToolBar2.SetButtonInfo (0, IDC_MILLISECEDIT, TBBS_SEPARATOR, 100);
+ m_wndToolBar2.GetItemRect (0, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 22;
+ if (!m_wndMillisecEdit.CreateEx (
+ WS_EX_CLIENTEDGE, _T("EDIT"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD | ES_CENTER | ES_READONLY,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar2.GetSafeHwnd (), (HMENU)IDC_MILLISECEDIT)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndMillisecEdit.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // 小節:拍:ティックの作成
+ m_wndToolBar2.SetButtonInfo (2, IDC_TIMEEDIT, TBBS_SEPARATOR, 100);
+ m_wndToolBar2.GetItemRect (2, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 22;
+ if (!m_wndTimeEdit.CreateEx (
+ WS_EX_CLIENTEDGE, _T("EDIT"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD | ES_CENTER | ES_READONLY,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar2.GetSafeHwnd (), (HMENU)IDC_TIMEEDIT)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndTimeEdit.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // 再生位置スクロールバーの作成
+ m_wndToolBar2.SetButtonInfo (9, IDC_POSITIONSCROLL, TBBS_SEPARATOR, 120);
+ m_wndToolBar2.GetItemRect (9, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 22;
+ if (!m_wndPositionScroll.CreateEx (
+ 0, _T("SCROLLBAR"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar2.GetSafeHwnd (), (HMENU)IDC_POSITIONSCROLL)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+
+ // 拍子・調性の作成
+ m_wndToolBar2.SetButtonInfo (19, IDC_MILLISECEDIT, TBBS_SEPARATOR, 60);
+ m_wndToolBar2.GetItemRect (19, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 22;
+ if (!m_wndMeasureEdit.CreateEx (
+ WS_EX_CLIENTEDGE, _T("EDIT"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD | ES_CENTER | ES_READONLY,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar2.GetSafeHwnd (), (HMENU)IDC_MEASUREEDIT)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndMeasureEdit.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // テンポ[BPM]の作成
+ m_wndToolBar2.SetButtonInfo (21, IDC_TIMEEDIT, TBBS_SEPARATOR, 60);
+ m_wndToolBar2.GetItemRect (21, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 22;
+ if (!m_wndTempoEdit.CreateEx (
+ WS_EX_CLIENTEDGE, _T("EDIT"), NULL,
+ WS_VISIBLE | WS_TABSTOP | WS_CHILD | ES_CENTER | ES_READONLY,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar2.GetSafeHwnd (), (HMENU)IDC_TEMPOEDIT)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndTempoEdit.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // ステータスバーの作成
+ if (!m_wndStatusBar.Create (this) ||
+ !m_wndStatusBar.SetIndicators (indicators, sizeof(indicators)/sizeof(UINT))) {
+ TRACE0 ("Failed to create status bar\n");
+ return -1;
+ }
+
+ m_wndStatusBar.SetPaneInfo (0, 0, SBPS_STRETCH, 0);
+ m_wndStatusBar.SetPaneInfo (1, ID_INDICATOR_FORMAT, 0, 64);
+ m_wndStatusBar.SetPaneInfo (2, ID_INDICATOR_NUMTRACKS, 0, 64);
+ m_wndStatusBar.SetPaneInfo (3, ID_INDICATOR_TIMEBASE, 0, 96);
+ m_wndStatusBar.SetPaneInfo (4, ID_INDICATOR_INPUTVELOCITY, 0, 156);
+ m_wndStatusBar.SetPaneInfo (5, ID_INDICATOR_OUTPUTVELOCITY, 0, 156);
+
+ // ツールバーのテキスト更新用タイマー起動
+ SetTimer (0x03, 55, NULL);
+
+ // ステータスバーのゲージ更新用タイマー起動
+ SetTimer (0x04, 55, NULL);
+
+ // ファイルのドロップを許可
+ DragAcceptFiles (TRUE);
+
+ return TRUE;
+}
+
+// ウィンドウ破壊時
+void CMainFrame::OnDestroy () {
+ // ツールバーのテキスト更新用タイマー終了
+ KillTimer (0x03);
+ // ステータスバーのゲージ更新用タイマー起動
+ KillTimer (0x04);
+ // ウィンドウ位置の保持
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CRect rcWindow;
+ GetWindowRect (&rcWindow);
+ pSekaijuApp->m_theWindowPlacement.m_bIconic = this->IsIconic ();
+ pSekaijuApp->m_theWindowPlacement.m_bZoomed = this->IsZoomed ();
+ pSekaijuApp->m_theWindowPlacement.m_nX = rcWindow.left;
+ pSekaijuApp->m_theWindowPlacement.m_nY = rcWindow.top;
+ pSekaijuApp->m_theWindowPlacement.m_nWidth = rcWindow.Width ();
+ pSekaijuApp->m_theWindowPlacement.m_nHeight = rcWindow.Height ();
+
+}
+
+// タイマー処理時
+void CMainFrame::OnTimer (UINT nIDEvent) {
+ // ツールバーのテキスト更新用タイマー(0x03)
+ if (nIDEvent == 0x03) {
+ CFrameWnd* pActiveFrame = this->GetActiveFrame ();
+ if (pActiveFrame == NULL || pActiveFrame == this) {
+ /* 現在の時:分:秒:ミリ秒表示 */
+ SetWindowTextWhenDifferent (&m_wndTimeEdit, _T(""));
+ /* 現在の小節:拍:ティック値表示 */
+ SetWindowTextWhenDifferent (&m_wndMillisecEdit, _T(""));
+ /* スクロールポジションの更新 */
+ m_wndPositionScroll.SetScrollPos (0, TRUE);
+ /* 現在の拍子及び調性記号の表示 */
+ SetWindowTextWhenDifferent (&m_wndMeasureEdit, _T(""));
+ /* 現在のテンポ[BPM]の表示 */
+ SetWindowTextWhenDifferent (&m_wndTempoEdit, _T(""));
+ }
+ else {
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pActiveFrame->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ TCHAR szText[1024];
+ if (pSekaijuDoc->m_pMIDIData && pSekaijuDoc->m_pMIDIClock) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lCurTime, lMeasure, lBeat, lTick, lFrameNumber;
+ long lCurMillisec, lHour, lMinute, lSec, lMillisec;
+ long lCurTempo;
+ long nn, dd, cc, bb;
+ long sf, mi;
+ lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ lCurMillisec = MIDIClock_GetMillisec (pSekaijuDoc->m_pMIDIClock);
+ /* 現在の時:分:秒:ミリ秒表示 */
+ lHour = (lCurMillisec / 3600000);
+ lMinute = (lCurMillisec / 60000) % 60;
+ lSec = (lCurMillisec / 1000) % 60;
+ lMillisec = lCurMillisec % 1000;
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%02d:%02d:%02d:%03d"), lHour, lMinute, lSec, lMillisec);
+ SetWindowTextWhenDifferent (&m_wndMillisecEdit, szText);
+ /* 現在の小節:拍:ティック値表示 */
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ MIDIData_BreakTimeEx (pSekaijuDoc->m_pMIDIData, lCurTime, &lMeasure, &lBeat, &lTick,
+ &nn, &dd, &cc, &bb);
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%05d:%02d:%03d"), lMeasure + 1, lBeat + 1, lTick);
+ SetWindowTextWhenDifferent (&m_wndTimeEdit, szText);
+ }
+ else if (lTimeMode == MIDIDATA_SMPTE24BASE ||
+ lTimeMode == MIDIDATA_SMPTE25BASE ||
+ lTimeMode == MIDIDATA_SMPTE29BASE ||
+ lTimeMode == MIDIDATA_SMPTE30BASE) {
+ lFrameNumber = lCurTime / lTimeResolution;
+ lTick = lCurTime % lTimeResolution;
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%08d:%03d"), lFrameNumber, lTick);
+ SetWindowTextWhenDifferent (&m_wndTimeEdit, szText);
+ }
+ /* スクロールポジションの更新 */
+ m_wndPositionScroll.SetScrollPos (lCurTime, TRUE);
+ /* 現在の拍子記号及び調性記号の表示 */
+ MIDIData_FindTimeSignature (pSekaijuDoc->m_pMIDIData, lCurTime, &nn, &dd, &cc, &bb);
+ MIDIData_FindKeySignature (pSekaijuDoc->m_pMIDIData, lCurTime, &sf, &mi);
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%d/%d, %d%s"), nn, 1 << dd, abs(sf),
+ (sf > 0 ? _T("#") : (sf < 0 ? _T("b") : _T(" ")))); // 20100613修正
+ SetWindowTextWhenDifferent (&m_wndMeasureEdit, szText);
+ /* 現在のテンポ[BPM]の表示 */
+ MIDIData_FindTempo (pSekaijuDoc->m_pMIDIData, lCurTime, &lCurTempo);
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%1.2lf"), (double)60000000 / (double)lCurTempo);
+ SetWindowTextWhenDifferent (&m_wndTempoEdit, szText);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+ else {
+ /* 現在の時:分:秒:ミリ秒表示 */
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%05d:%02d:%03d"), 1, 1, 0);
+ SetWindowTextWhenDifferent (&m_wndTimeEdit, szText);
+ /* 現在の小節:拍:ティック値表示 */
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%02d:%02d:%02d:%03d"), 0, 0, 0, 0);
+ SetWindowTextWhenDifferent (&m_wndMillisecEdit, szText);
+ /* スクロールポジションの更新 */
+ m_wndPositionScroll.SetScrollPos (0, TRUE);
+ /* 現在の拍子記号及び調性記号の表示 */
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%d/%d, %d%s"), 4, 4, 0, _T(" "));
+ SetWindowTextWhenDifferent (&m_wndMeasureEdit, szText);
+ /* 現在のテンポ[BPM]の表示 */
+ memset (szText, 0, sizeof (szText));
+ _sntprintf (szText, 1023, _T("%1.2lf"), (double)60000000 / (double)600000);
+ SetWindowTextWhenDifferent (&m_wndTempoEdit, szText);
+ }
+ }
+ else {
+ /* 現在の時:分:秒:ミリ秒表示 */
+ SetWindowTextWhenDifferent (&m_wndTimeEdit, _T(""));
+ /* 現在の小節:拍:ティック値表示 */
+ SetWindowTextWhenDifferent (&m_wndMillisecEdit, _T(""));
+ /* スクロールポジションの更新 */
+ m_wndPositionScroll.SetScrollPos (0, TRUE);
+ /* 現在の拍子記号及び調性記号の表示 */
+ SetWindowTextWhenDifferent (&m_wndMeasureEdit, _T(""));
+ /* 現在のテンポ[BPM]の表示 */
+ SetWindowTextWhenDifferent (&m_wndTempoEdit, _T(""));
+ }
+ }
+ }
+ // ステータスバーのゲージ更新用タイマー(0x04)
+ else if (nIDEvent == 0x04) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp();
+ CRect rcItem;
+ CRect rcLeft;
+ CRect rcRight;
+ CDC* pDC = NULL;
+ long lPort;
+ long lPart;
+ long j = 0;
+ // 入力ベロシティゲージの描画
+ unsigned char ucMaxVelocity = 0;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ MIDIStatus* pMIDIInStatus = pSekaijuApp->m_pMIDIInStatus[lPort];
+ if (pMIDIInStatus) {
+ for (lPart = 0; lPart < 16; lPart++) {
+ MIDIPart* pMIDIPart = MIDIStatus_GetMIDIPart (pMIDIInStatus, lPart);
+ unsigned char ucVelocity[128];
+ memset (ucVelocity, 0, 128);
+ MIDIPart_GetNoteEx (pMIDIPart, ucVelocity, 128);
+ for (j = 0; j < 128; j++) {
+ if (ucVelocity[j] > ucMaxVelocity) {
+ ucMaxVelocity = ucVelocity[j];
+ }
+ }
+ }
+ }
+ }
+ m_wndStatusBar.GetItemRect (4, &rcItem);
+ rcLeft.left = rcItem.left + 32,
+ rcLeft.top = rcItem.top + 2;
+ rcLeft.right = rcItem.left + 32 + ucMaxVelocity;
+ rcLeft.bottom = rcItem.bottom - 2;
+ rcRight.left = rcItem.left + 32 + ucMaxVelocity;
+ rcRight.top = rcItem.top + 2;
+ rcRight.right = rcItem.right - 2;
+ rcRight.bottom = rcItem.bottom - 2;
+ pDC = m_wndStatusBar.GetDC ();
+ pDC->FillSolidRect (rcLeft, RGB (255,0,0));
+ pDC->FillSolidRect (rcRight, GetSysColor (COLOR_3DFACE));
+ m_wndStatusBar.ReleaseDC (pDC);
+ // 出力ベロシティゲージの描画
+ ucMaxVelocity = 0;
+ for (lPort = 0; lPort < MAXMIDIOUTDEVICENUM; lPort++) {
+ MIDIStatus* pMIDIOutStatus = pSekaijuApp->m_pMIDIOutStatus[lPort];
+ if (pMIDIOutStatus) {
+ for (lPart = 0; lPart < 16; lPart++) {
+ MIDIPart* pMIDIPart = MIDIStatus_GetMIDIPart (pMIDIOutStatus, lPart);
+ unsigned char ucVelocity[128];
+ memset (ucVelocity, 0, 128);
+ MIDIPart_GetNoteEx (pMIDIPart, ucVelocity, 128);
+ for (j = 0; j < 128; j++) {
+ if (ucVelocity[j] > ucMaxVelocity) {
+ ucMaxVelocity = ucVelocity[j];
+ }
+ }
+ }
+ }
+ }
+ m_wndStatusBar.GetItemRect (5, &rcItem);
+ rcLeft.left = rcItem.left + 32,
+ rcLeft.top = rcItem.top + 2;
+ rcLeft.right = rcItem.left + 32 + ucMaxVelocity;
+ rcLeft.bottom = rcItem.bottom - 2;
+ rcRight.left = rcItem.left + 32 + ucMaxVelocity;
+ rcRight.top = rcItem.top + 2;
+ rcRight.right = rcItem.right - 2;
+ rcRight.bottom = rcItem.bottom - 2;
+ pDC = m_wndStatusBar.GetDC ();
+ pDC->FillSolidRect (rcLeft, RGB (0,128,0));
+ pDC->FillSolidRect (rcRight, GetSysColor (COLOR_3DFACE));
+ m_wndStatusBar.ReleaseDC (pDC);
+
+ }
+}
+
+// ツールバー2上の位置スクロールバーの操作メッセージはここにはこない。
+void CMainFrame::OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ // ツールバー上のスクロールメッセージは、CSekaijuToolBar::OnHScrollで処理せよ。
+}
+
+// マウスホイールが回された時
+void CMainFrame::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ this->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ this->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+}
+
+
+// 『表示』-『ツールバー1』
+void CMainFrame::OnViewToolbar1 () {
+ ShowControlBar (&m_wndToolBar1, (m_wndToolBar1.GetStyle () & WS_VISIBLE) == 0, FALSE);
+}
+
+// 『表示』-『ツールバー1』
+void CMainFrame::OnUpdateViewToolbar1UI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck ((m_wndToolBar1.GetStyle () & WS_VISIBLE) ? 1 : 0);
+}
+
+// 『表示』-『ツールバー2』
+void CMainFrame::OnViewToolbar2 () {
+ ShowControlBar (&m_wndToolBar2, (m_wndToolBar2.GetStyle () & WS_VISIBLE) == 0, FALSE);
+}
+
+// 『表示』-『ツールバー2』
+void CMainFrame::OnUpdateViewToolbar2UI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck ((m_wndToolBar2.GetStyle () & WS_VISIBLE) ? 1 : 0);
+}
+
+// インジケーター-入力ベロシティ
+void CMainFrame::OnUpdateIndicatorInputVelocityUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetText (_T("IN"));
+}
+
+// インジケーター-出力ベロシティ
+void CMainFrame::OnUpdateIndicatorOutputVelocityUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetText (_T("OUT"));
+}
+
+// インジケーター-フォーマット
+void CMainFrame::OnUpdateIndicatorFormatUI (CCmdUI* pCmdUI) {
+ CFrameWnd* pFrameWnd = (CFrameWnd*)GetActiveFrame ();
+ if (pFrameWnd) {
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pFrameWnd->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ CString strText;
+ strText.Format (_T("Format%d"), lFormat);
+ pCmdUI->SetText (strText);
+ }
+ else {
+ pCmdUI->SetText (_T(""));
+ }
+ }
+ else {
+ pCmdUI->SetText (_T(""));
+ }
+}
+
+// インジケーター-トラック数
+void CMainFrame::OnUpdateIndicatorNumTracksUI (CCmdUI* pCmdUI) {
+ CFrameWnd* pFrameWnd = (CFrameWnd*)GetActiveFrame ();
+ if (pFrameWnd) {
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pFrameWnd->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lNumTracks = MIDIData_GetNumTrack (pMIDIData);
+ CString strText;
+ strText.Format (_T("%dTracks"), lNumTracks);
+ pCmdUI->SetText (strText);
+ }
+ else {
+ pCmdUI->SetText (_T(""));
+ }
+ }
+ else {
+ pCmdUI->SetText (_T(""));
+ }
+}
+
+// インジケーター-タイムベース
+void CMainFrame::OnUpdateIndicatorTimeBaseUI (CCmdUI* pCmdUI) {
+ CFrameWnd* pFrameWnd = (CFrameWnd*)GetActiveFrame ();
+ if (pFrameWnd) {
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pFrameWnd->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ CString strText;
+ switch (lTimeMode) {
+ case MIDIDATA_TPQNBASE:
+ strText.Format (_T("%dTPQN"), lTimeResolution);
+ break;
+ case MIDIDATA_SMPTE24BASE:
+ strText.Format (_T("SMPTE24/%d"), lTimeResolution);
+ break;
+ case MIDIDATA_SMPTE25BASE:
+ strText.Format (_T("SMPTE24/%d"), lTimeResolution);
+ break;
+ case MIDIDATA_SMPTE29BASE:
+ strText.Format (_T("SMPTE29.97/%d"), lTimeResolution);
+ break;
+ case MIDIDATA_SMPTE30BASE:
+ strText.Format (_T("SMPTE30/%d"), lTimeResolution);
+ break;
+ }
+ pCmdUI->SetText (strText);
+ }
+ else {
+ pCmdUI->SetText (_T(""));
+ }
+ }
+ else {
+ pCmdUI->SetText (_T(""));
+ }
+}
+
+
+// このウィンドウを最前面に出すことを要求
+long CMainFrame::OnCommandWakeUp (WPARAM wParam, LPARAM lParam) {
+ // メイン・ウィンドウが最小化されていれば元に戻す
+ if (this->IsIconic ()) {
+ ::ShowWindowAsync (this->GetSafeHwnd (), SW_RESTORE);
+ }
+ // メイン・ウィンドウを最前面に表示する
+ SetForegroundWindow ();
+ return 1;
+}
+
+// 共有メモリが変更されたので読み取ることを要求
+long CMainFrame::OnCommandReadShm (WPARAM wParam, LPARAM lParam) {
+ CString strMsg;
+ HANDLE hShare = CreateFileMapping
+ (INVALID_HANDLE_VALUE, NULL, FILE_MAP_READ, 0, 1024, AfxGetAppName ());
+ if (hShare == INVALID_HANDLE_VALUE) {
+ // 共有メモリ(受信側)オープンエラー
+ strMsg.LoadString (IDS_SHAREMEMORY_FOR_RECV_OPEN_ERROR);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return 0;
+ }
+ TCHAR *pShareMem = (TCHAR*)MapViewOfFile (hShare, FILE_MAP_READ, 0, 0, 1024);
+ if (pShareMem == NULL) {
+ // 共有メモリ(受信側)マッピングエラー
+ ::CloseHandle (hShare);
+ strMsg.LoadString (IDS_SHAREMEMORY_FOR_RECV_MAPPING_ERROR);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return 0;
+ }
+ m_strTempFileName = CString (pShareMem);
+ ::UnmapViewOfFile (pShareMem);
+ ::CloseHandle (hShare);
+ return 1;
+}
+
+// ファイルを開くことを要求(開くファイル名はm_strTempFileName)
+long CMainFrame::OnCommandFileOpen (WPARAM wParam, LPARAM lParam) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp();
+ CDocTemplate* pSekaijuDocTemplate = pSekaijuApp->m_pSekaijuDocTemplate;
+ CSekaijuDoc* pSekaijuDoc =
+ (CSekaijuDoc*)(pSekaijuDocTemplate->OpenDocumentFile (m_strTempFileName));
+ if (pSekaijuDoc == NULL) {
+ //MessageBox (m_strTempFileName, APPNAME, MB_ICONINFORMATION);
+ _RPT1 (_CRT_WARN, "新しいドキュメントを開けませんでした。-%s.", m_strTempFileName);
+ }
+
+ return 1;
+}
diff --git a/src/MetronomeDlg.cpp b/src/MetronomeDlg.cpp
new file mode 100644
index 0000000..5ffc882
--- /dev/null
+++ b/src/MetronomeDlg.cpp
@@ -0,0 +1,194 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// メトロノームダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "MetronomeDlg.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMetronomeDlg::CMetronomeDlg () : CDialog (CMetronomeDlg::IDD) {
+ m_nOn = 0;
+ m_nOutputPort = 0;
+ m_nOutputChannel = 10;
+ m_nNoteKey1 = 0;
+ m_nNoteVel1 = 1;
+ m_nNoteKey2 = 0;
+ m_nNoteVel2 = 1;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 出力先ポートコンボボックスの充満
+BOOL CMetronomeDlg::FillOutputPortCombo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_METRONOME_OUTPUTPORT);
+ if (pComboBox == NULL) {
+ return FALSE;
+ }
+ int nCurSel = pComboBox->GetCurSel (); // 初回はコンボボックス空のためエラー(-1)を返す
+ pComboBox->ResetContent ();
+ for (long lPort = 0; lPort < MAXMIDIOUTDEVICENUM; lPort++) {
+ CString strTextLine;
+ if (pSekaijuApp->m_strMIDIOutName[lPort] == _T("")) {
+ CString strNone;
+ VERIFY (strNone.LoadString (IDS_NONE));
+ strTextLine.Format (_T("%d-%s"), lPort + 1, strNone);
+ }
+ else {
+ strTextLine.Format (_T("%d-%s"), lPort + 1, pSekaijuApp->m_strMIDIOutName[lPort]);
+ }
+ pComboBox->AddString (strTextLine);
+ }
+ if (0 <= nCurSel && nCurSel <= 15) {
+ pComboBox->SetCurSel (nCurSel);
+ }
+ else {
+ pComboBox->SetCurSel (m_nOutputPort);
+ }
+ return TRUE;
+}
+
+// ノート・キーコンボボックスの充満
+BOOL CMetronomeDlg::FillNoteKeyCombo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lPort = ((CComboBox*)GetDlgItem (IDC_METRONOME_OUTPUTPORT))->GetCurSel ();
+ lPort = CLIP (0, lPort, 15);
+ CString strChannel;
+ GetDlgItem (IDC_METRONOME_OUTPUTCHANNEL)->GetWindowText (strChannel);
+ long lChannel = _ttol ((LPCTSTR)strChannel);
+ lChannel = CLIP (0, lChannel, 15);
+ long lOctaveSignature = pSekaijuApp->m_theGeneralOption.m_lOctaveSignature;
+
+ MIDIInstrumentDefinition* pMIDIInstDefDrum = pSekaijuApp->m_pMIDIInstDefDrum[lPort];
+ MIDINoteNameTable* pNoteNameTable = NULL;
+ if (pMIDIInstDefDrum && lChannel == 10) {
+ pNoteNameTable = MIDIInstrumentDefinition_GetNoteNameTable (pMIDIInstDefDrum, 0, 0);
+ }
+
+ for (long i = 0; i < 2; i++) {
+ CComboBox* pComboBox = (CComboBox*)GetDlgItem (IDC_METRONOME_NOTEKEY1 + i * 4);
+ if (pComboBox == NULL) {
+ continue;
+ }
+ int nCurSel = pComboBox->GetCurSel (); // 初回はコンボボックス空のためエラー(-1)を返す
+ pComboBox->ResetContent ();
+ for (long lKey = 0; lKey <= 127; lKey++) {
+ CString strTextLine;
+ if (pNoteNameTable) {
+ TCHAR szName[256];
+ memset (szName, 0, sizeof (szName));
+ MIDINoteNameTable_GetName (pNoteNameTable, lKey, szName, TSIZEOF (szName));
+ strTextLine.Format (_T("%d-%s"), lKey, szName);
+ }
+ else {
+ CString strName;
+ strName.LoadString (IDS_NOTEKEY_0S00 + lKey % 12);
+ strTextLine.Format (_T("%d-%s%d"), lKey, strName, lKey / 12 + lOctaveSignature - 5);
+ }
+ pComboBox->AddString (strTextLine);
+ }
+ if (0 <= nCurSel && nCurSel <= 127) {
+ pComboBox->SetCurSel (nCurSel);
+ }
+ else {
+ pComboBox->SetCurSel (i == 0 ? m_nNoteKey1 : m_nNoteKey2);
+ }
+ }
+ return TRUE;
+}
+
+
+// オーバーライド
+
+// データエクスチェンジ
+void CMetronomeDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ // DDV_MinMaxXXXは各々のDDX_TEXTの直後に配置すること(20090501訂正)
+ DDX_Check (pDX, IDC_METRONOME_ON, m_nOn);
+ DDX_CBIndex (pDX, IDC_METRONOME_OUTPUTPORT, m_nOutputPort);
+ DDX_Text (pDX, IDC_METRONOME_OUTPUTCHANNEL, m_nOutputChannel);
+ DDV_MinMaxInt (pDX, m_nOutputChannel, 1, 16);
+ DDX_CBIndex (pDX, IDC_METRONOME_NOTEKEY1, m_nNoteKey1);
+ DDX_Text (pDX, IDC_METRONOME_NOTEVEL1, m_nNoteVel1);
+ DDV_MinMaxInt (pDX, m_nNoteVel1, 1, 127);
+ DDX_CBIndex (pDX, IDC_METRONOME_NOTEKEY2, m_nNoteKey2);
+ DDX_Text (pDX, IDC_METRONOME_NOTEVEL2, m_nNoteVel2);
+ DDV_MinMaxInt (pDX, m_nNoteVel2, 1, 127);
+}
+
+
+// ダイアログの初期化
+BOOL CMetronomeDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ FillOutputPortCombo ();
+ FillNoteKeyCombo ();
+ //CString strValue;
+ //long lValue = 0;
+ //GetDlgItem (IDC_METRONOME_OUTPUT)->GetWindowText (strValue);
+ //lValue = atol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_METRONOME_OUTPUTCHANNELSP))->SetRange (1, 16);
+ //((CSpinButtonCtrl*)GetDlgItem (IDC_METRONOME_OUTPUTCHANNELSP))->SetPos (CLIP (1, lValue, 16));
+ //GetDlgItem (IDC_METRONOME_NOTEVEL1)->GetWindowText (strValue);
+ //lValue = atol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_METRONOME_NOTEVEL1SP))->SetRange (1, 127);
+ //((CSpinButtonCtrl*)GetDlgItem (IDC_METRONOME_NOTEVEL1SP))->SetPos (CLIP (1, lValue, 127));
+ //GetDlgItem (IDC_METRONOME_NOTEVEL1)->GetWindowText (strValue);
+ //lValue = atol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_METRONOME_NOTEVEL2SP))->SetRange (1, 127);
+ //((CSpinButtonCtrl*)GetDlgItem (IDC_METRONOME_NOTEVEL2SP))->SetPos (CLIP (1, lValue, 127));
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CMetronomeDlg, CDialog)
+ ON_CONTROL (CBN_SELCHANGE, IDC_METRONOME_OUTPUTPORT, OnChangeOutput)
+ ON_CONTROL (EN_CHANGE, IDC_METRONOME_OUTPUTCHANNEL, OnChangeOutput)
+END_MESSAGE_MAP ()
+
+// 出力先が変更された
+void CMetronomeDlg::OnChangeOutput () {
+ FillNoteKeyCombo ();
+}
+
+
diff --git a/src/MetronomeDlg.h b/src/MetronomeDlg.h
new file mode 100644
index 0000000..efb6792
--- /dev/null
+++ b/src/MetronomeDlg.h
@@ -0,0 +1,65 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// メトロノームダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _METRONOMEDLG_H_
+#define _METRONOMEDLG_H_
+
+class CMetronomeDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // メンバ変数
+ //--------------------------------------------------------------------------
+public:
+ int m_nOn; // オン(0=オフ、1=ON)
+ int m_nOutputPort; // 出力ポート(0〜15)
+ int m_nOutputChannel; // 出力チャンネル(0〜15)
+ int m_nNoteKey1; // ノートキー強打(0〜127)
+ int m_nNoteVel1; // ノートベロシティ強打(1〜127)
+ int m_nNoteKey2; // ノートキー弱打(0〜127)
+ int m_nNoteVel2; // ノーとベロシティ弱打(0〜127)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMetronomeDlg(); // コンストラクタ
+ enum {IDD = IDD_METRONOME};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ BOOL FillOutputPortCombo ();
+ BOOL FillNoteKeyCombo ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnChangeOutput ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/MusicalScoreFrame.cpp b/src/MusicalScoreFrame.cpp
new file mode 100644
index 0000000..b8282b2
--- /dev/null
+++ b/src/MusicalScoreFrame.cpp
@@ -0,0 +1,3960 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面フレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "common.h"
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "resource.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "ColorfulCheckListBox.h"
+#include "ColorfulComboBox.h"
+#include "MusicalScoreFrame.h"
+#include "MusicalScorePrintView.h"
+#include "MusicalScoreScaleView.h"
+#include "MusicalScoreTimeScaleView.h"
+#include "MusicalScoreTrackScaleView.h"
+#include "MusicalScoreTrackTimeView.h"
+#include "TrackListBox.h"
+#include "PropertyNoteDlg.h"
+
+// アロケーションの監視
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// 子ウィンドウのサイズ
+#define MUSICALSCOREFRAME_SCALEHEIGHT 32
+#define MUSICALSCOREFRAME_SCALEWIDTH 160
+#define MUSICALSCOREFRAME_TIMEWIDTH 600
+#define MUSICALSCOREFRAME_TRACKHEIGHT 256
+
+
+#define MUSICALSCOREFRAME_VELHEIGHT 128
+#define MUSICALSCOREFRAME_SCROLLBARHEIGHT 16
+#define MUSICALSCOREFRAME_SCROLLBARWIDTH 16
+#define MUSICALSCOREFRAME_BORDERWIDTH 2
+#define MUSICALSCOREFRAME_BORDERHEIGHT 2
+#define MUSICALSCOREFRAME_SPLITTERWIDTH 4
+#define MUSICALSCOREFRAME_SPLITTERHEIGHT 4
+#define MUSICALSCOREFRAME_TRACKLISTWIDTH 120
+
+// 子ウィンドウIDを定義
+#define MUSICALSCOREFRAME_DUMMYVIEW (AFX_IDW_PANE_FIRST + 0)
+#define MUSICALSCOREFRAME_PRINTVIEW (AFX_IDW_PANE_FIRST + 1)
+#define MUSICALSCOREFRAME_SCALEVIEW (AFX_IDW_PANE_FIRST + 32)
+#define MUSICALSCOREFRAME_TIMESCALEVIEW (AFX_IDW_PANE_FIRST + 33)
+#define MUSICALSCOREFRAME_TRACKSCALEVIEW (AFX_IDW_PANE_FIRST + 34)
+#define MUSICALSCOREFRAME_TRACKTIMEVIEW (AFX_IDW_PANE_FIRST + 35)
+#define MUSICALSCOREFRAME_VELSCALEVIEW (AFX_IDW_PANE_FIRST + 36)
+#define MUSICALSCOREFRAME_VELTIMEVIEW (AFX_IDW_PANE_FIRST + 37)
+#define MUSICALSCOREFRAME_TIMESCROLL (AFX_IDW_PANE_FIRST + 48)
+#define MUSICALSCOREFRAME_TRACKSCROLL (AFX_IDW_PANE_FIRST + 49)
+#define MUSICALSCOREFRAME_VELSCROLL (AFX_IDW_PANE_FIRST + 50)
+#define MUSICALSCOREFRAME_SIZEBOX (AFX_IDW_PANE_FIRST + 51)
+#define MUSICALSCOREFRAME_TIMEZOOMDOWN (AFX_IDW_PANE_FIRST + 52)
+#define MUSICALSCOREFRAME_TIMEZOOMUP (AFX_IDW_PANE_FIRST + 53)
+#define MUSICALSCOREFRAME_TRACKZOOMDOWN (AFX_IDW_PANE_FIRST + 54)
+#define MUSICALSCOREFRAME_TRACKZOOMUP (AFX_IDW_PANE_FIRST + 55)
+#define MUSICALSCOREFRAME_VELZOOMDOWN (AFX_IDW_PANE_FIRST + 56)
+#define MUSICALSCOREFRAME_VELZOOMUP (AFX_IDW_PANE_FIRST + 57)
+#define MUSICALSCOREFRAME_TRACKLIST (AFX_IDW_PANE_FIRST + 58)
+#define MUSICALSCOREFRAME_GRAPHKINDLIST (AFX_IDW_PANE_FIRST + 59)
+
+//
+// ピアノロールフレームのクライアント領域に配置されたオブジェクト
+//                             m_lScr ┃ m_lTrack
+// ┃←m_lScale→│← m_lTime  →│←ollBar→★← ListWidth →┃
+// Width Width    Width ┃
+// ─
+// ↑ ┏─────────────────────────────────┓
+// m_lToolBar1Height┃CToolBar ┃
+//  ↓ ┃m_wndToolBar1 ┃
+// ━ ┣━━━━━━┯━━━━━━━━━━━━━━┯━┳━━━━━━━┯━┫
+// ↑ ┃CView* │CView*    │↑┃CChcekListBox*│↑┃
+// m_lScaleHeight ┃m_pScaleView│m_pTimeScaleView    ├─┨m_pTrackListBo├─┨
+// ↓ ┠──────┼──────────────┤ ┃x (With Scroll│ ┃
+// ─ ┃CView*  │CView*      │□★ Bar) │□┃
+// ↑ ┃m_pTrackScal│m_pTrackTimeView   │ ┃ │ ┃
+// ┃eView │              ├─┨ │ ┃
+// m_lKeyHeight ┃    │ CScrollBar m_wndTrackScroll│↓┃ │ ┃
+// ┃    │              ├─┨ │ ┃
+// ┃    │ CButton m_wndTrackZoomDown│−┃ │ ┃
+// ┃    │              ├─┨       ├─┨
+// ↓ ┃    │  CButton m_wndTrackZoomUp│+┃       │↓┃
+// ↑ ┠─┬────┴────────┬─┬─┬─┼─┨─┬───┬─┼─┨
+//m_lScrollBarHeight┃←│   □         │→│−│+│⊿┃←│□  │→│ ┃  
+// ↓ ┗━┷━━━━━━━━━━━━━┷━┷━┷━┷━┻━┷━━━┷━┷━┛
+// ━ CScrollBar CButton CButton
+// m_wndTimeScroll m_wndTime m_wndTime
+// ZoomDown ZoomDown
+//
+// (あ)———:単純な境界線(0px)。
+// (い)━━━:太く立体的な境界線。BORDERWIDTH(2px)又はBORDERHEIGHT(2px)で示す幅を占領
+// (う)━★━:スプリッター境界線。(い)*2+SPRITTERWIDTH(4px)又はSPRITTERHEIGHT(4px)で示す幅を占領。
+//
+
+// 関数マクロ
+#define MUSICALSCOREFRAME_RANGE(A,B,C) ((A)>(B)?(A):((B)>(C)?(C):(B)))
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CMusicalScoreFrame, CChildFrame)
+
+BEGIN_MESSAGE_MAP (CMusicalScoreFrame, CChildFrame)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_SIZE ()
+ ON_WM_TIMER ()
+ ON_WM_ERASEBKGND ()
+ ON_WM_MDIACTIVATE ()
+ ON_WM_PAINT ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_HSCROLL ()
+ ON_WM_VSCROLL ()
+ ON_BN_CLICKED (MUSICALSCOREFRAME_TIMEZOOMDOWN, OnTimeZoomDown)
+ ON_BN_CLICKED (MUSICALSCOREFRAME_TIMEZOOMUP, OnTimeZoomUp)
+ ON_BN_CLICKED (MUSICALSCOREFRAME_TRACKZOOMDOWN, OnTrackZoomDown)
+ ON_BN_CLICKED (MUSICALSCOREFRAME_TRACKZOOMUP, OnTrackZoomUp)
+// ON_WM_CHILDACTIVATE ()
+ ON_COMMAND (ID_MUSICALSCORE_PEN, OnMusicalScorePen)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_PEN, OnUpdateMusicalScorePenUI)
+ ON_COMMAND (ID_MUSICALSCORE_ERASER, OnMusicalScoreEraser)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_ERASER, OnUpdateMusicalScoreEraserUI)
+ ON_COMMAND (ID_MUSICALSCORE_SELECT, OnMusicalScoreSelect)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_SELECT, OnUpdateMusicalScoreSelectUI)
+ ON_COMMAND (ID_MUSICALSCORE_SPEAKER, OnMusicalScoreSpeaker)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_SPEAKER, OnUpdateMusicalScoreSpeakerUI)
+ ON_COMMAND (ID_MUSICALSCORE_WHOLENOTE, OnMusicalScoreWholeNote)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_WHOLENOTE, OnUpdateMusicalScoreWholeNoteUI)
+ ON_COMMAND (ID_MUSICALSCORE_HALFNOTE, OnMusicalScoreHalfNote)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_HALFNOTE, OnUpdateMusicalScoreHalfNoteUI)
+ ON_COMMAND (ID_MUSICALSCORE_QUARTERNOTE, OnMusicalScoreQuarterNote)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_QUARTERNOTE, OnUpdateMusicalScoreQuarterNoteUI)
+ ON_COMMAND (ID_MUSICALSCORE_QUAVERNOTE, OnMusicalScoreQuaverNote)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_QUAVERNOTE, OnUpdateMusicalScoreQuaverNoteUI)
+ ON_COMMAND (ID_MUSICALSCORE_SEMIQUAVERNOTE, OnMusicalScoreSemiQuaverNote)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_SEMIQUAVERNOTE, OnUpdateMusicalScoreSemiQuaverNoteUI)
+ ON_COMMAND (ID_MUSICALSCORE_DEMISEMIQUAVERNOTE, OnMusicalScoreDemiSemiQuaverNote)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_DEMISEMIQUAVERNOTE, OnUpdateMusicalScoreDemiSemiQuaverNoteUI)
+ ON_COMMAND (ID_MUSICALSCORE_DOTTED, OnMusicalScoreDotted)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_DOTTED, OnUpdateMusicalScoreDottedUI)
+ ON_COMMAND (ID_MUSICALSCORE_TRIPLET, OnMusicalScoreTriplet)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_TRIPLET, OnUpdateMusicalScoreTripletUI)
+ ON_COMMAND (ID_MUSICALSCORE_ONLYCURTRACK, OnMusicalScoreOnlyCurTrack)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_ONLYCURTRACK, OnUpdateMusicalScoreOnlyCurTrackUI)
+ ON_COMMAND (ID_MUSICALSCORE_SHOWALLTRACK, OnMusicalScoreShowAllTrack)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_SHOWALLTRACK, OnUpdateMusicalScoreShowAllTrackUI)
+ ON_COMMAND (ID_MUSICALSCORE_AUTOPAGEUPDATE, OnMusicalScoreAutoPageUpdate)
+ ON_UPDATE_COMMAND_UI (ID_MUSICALSCORE_AUTOPAGEUPDATE, OnUpdateMusicalScoreAutoPageUpdateUI)
+
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEON, OnPopupTrackVisibleOn)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEON, OnUpdatePopupTrackVisibleOnUI)
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEOFF, OnPopupTrackVisibleOff)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEOFF, OnUpdatePopupTrackVisibleOffUI)
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEALL, OnPopupTrackVisibleAll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEALL, OnUpdatePopupTrackVisibleAllUI)
+ ON_COMMAND (ID_POPUP_EVENTPROPERTY, OnPopupEventProperty)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_EVENTPROPERTY, OnUpdatePopupEventPropertyUI)
+
+ ON_CBN_SELENDOK (IDC_SNAPCOMBO, OnSnapComboSelEndOK)
+ ON_CBN_SELENDOK (IDC_TRACKCOMBO, OnTrackComboSelEndOK)
+ ON_CLBN_CHKCHANGE (MUSICALSCOREFRAME_TRACKLIST, OnTrackListChkChange)
+ ON_LBN_SELCHANGE (MUSICALSCOREFRAME_TRACKLIST, OnTrackListSelChange)
+ ON_CBN_SELENDOK (IDC_RESOLUTIONCOMBO, OnResolutionComboSelEndOK)
+
+
+END_MESSAGE_MAP ()
+
+//-----------------------------------------------------------------------------
+// 構築と破壊
+//-----------------------------------------------------------------------------
+
+// コンストラクタ
+CMusicalScoreFrame::CMusicalScoreFrame () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_lKeyHeight = MUSICALSCOREFRAME_TRACKHEIGHT;
+ m_lScaleHeight = MUSICALSCOREFRAME_SCALEHEIGHT;
+ m_lScaleWidth = MUSICALSCOREFRAME_SCALEWIDTH;
+ m_lTimeWidth = MUSICALSCOREFRAME_TIMEWIDTH;
+ //m_lSplitterHeight = MUSICALSCOREFRAME_SPLITTERHEIGHT;
+ //m_lSplitterWidth = MUSICALSCOREFRAME_SPLITTERWIDTH;
+ m_lHScrollBarHeight = ::GetSystemMetrics (SM_CYHSCROLL);
+ m_lVScrollBarWidth = ::GetSystemMetrics (SM_CXVSCROLL);
+ m_lTrackListWidth = MUSICALSCOREFRAME_TRACKLISTWIDTH;
+ m_lTrackZoom = pSekaijuApp->m_theMusicalScoreOption.m_lDefTrackZoom;
+ m_lTimeZoom = pSekaijuApp->m_theMusicalScoreOption.m_lDefTimeZoom;
+ m_lTimeScrollPos = 0;
+ CString strFontName;
+ VERIFY (strFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (12, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strFontName);
+ CString strTimeMeasureFontName;
+ VERIFY (strTimeMeasureFontName.LoadString (IDS_TIMEMEASUREFONTNAME));
+ m_theTimeMeasureFont.CreateFont (16, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strTimeMeasureFontName);
+ m_lCurTool = ID_MUSICALSCORE_PEN;
+ m_bAutoPageUpdate = FALSE;
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ for (long i = 0; i < MAXMIDITRACKNUM; i++) {
+ m_bTrackVisible[i] = TRUE;
+ }
+}
+
+// デストラクタ
+CMusicalScoreFrame::~CMusicalScoreFrame () {
+ m_theFont.DeleteObject ();
+ m_theTimeMeasureFont.DeleteObject ();
+ // トラック情報配列削除
+ VERIFY (DeleteTrackInfoArray ());
+ // 小節情報配列削除
+ VERIFY (DeleteMeasureInfoArray ());
+
+}
+
+// ドキュメントの取得
+CSekaijuDoc* CMusicalScoreFrame::GetDocument () {
+ ASSERT (m_pDummyView);
+ return (CSekaijuDoc*)m_pDummyView->GetDocument ();
+}
+
+//-----------------------------------------------------------------------------
+// オペレーション
+//-----------------------------------------------------------------------------
+
+// 時間方向のズーム倍率取得
+long CMusicalScoreFrame::GetTimeZoom () {
+ return m_lTimeZoom;
+}
+
+// トラック方向のズーム倍率取得
+long CMusicalScoreFrame::GetTrackZoom () {
+ return m_lTrackZoom;
+}
+
+// y座標をトラックインデックスに変換
+long CMusicalScoreFrame::YtoTrackIndex (long y) {
+ long lNumTrackInfo = GetTrackInfoCount ();
+ long i;
+ for (i = 0; i < lNumTrackInfo; i++) {
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (i);
+ if (pTrackInfo->m_lTop * m_lTrackZoom <= y && y < (pTrackInfo->m_lTop + pTrackInfo->m_lHeight) * m_lTrackZoom) {
+ return i;
+ }
+ }
+ return MAXMIDITRACKNUM;
+}
+
+// y座標をノートキーに変換
+long CMusicalScoreFrame::TrackIndexYtoKey (long lTrackIndex, long y, long lKeySignature) {
+ long lNumTrackInfo = GetTrackInfoCount ();
+ if (lTrackIndex < 0 || lTrackIndex >= lNumTrackInfo) {
+ return -1;
+ }
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (lTrackIndex);
+ long lKey;
+ for (lKey = 0; lKey < 128; lKey++) {
+ long lTempY = TrackIndexKeytoY (lTrackIndex, lKey, lKeySignature);
+ if (lTempY < y) {
+ if (KeytoSF (lKey, lKeySignature) == 0) {
+ return lKey;
+ }
+ }
+ }
+ return 128;
+}
+
+// 指定の調性記号において、指定キーは譜面上の何番目の線に乗るかを返す。
+// 同じキーでも調性記号により36になったり37になったりする。
+long CMusicalScoreFrame::KeytoLineNo (long lKey, long lKeySignature) {
+ long lsf = lKeySignature & 0x000000FF;
+ long lmi = (lKeySignature >> 8) & 0x000000FF;
+ lsf = CLIP (-7, (char)lsf, 7);
+ long lDeltaTable[15][12] = {
+ // C, -, D, -, E, F, -, G, -, A, -, B
+ {0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7}, // 7b (Cb-major / Ab-minor)
+ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7}, // 6b (Gb-major / Eb-minor)
+ {0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7}, // 5b (Db-major / Bb-minor)
+ {0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7}, // 4b (Ab-major / F-minor)
+ {0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6}, // 3b (Eb-major / C-minor)
+ {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6}, // 2b (Bb-major / G-minor)
+ {0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6}, // 1b (F-major / D-minor)
+ {0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6}, // 0 (C-major / A-minor)
+ {0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6}, // 1# (G-major / E-minor)
+ {0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6}, // 2# (D-major / B-minor)
+ {0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6}, // 3# (A-major / F#-minor)
+ {-1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6}, // 4# (E-major / C#-minor)
+ {-1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6}, // 5# (B-major / G#-minor)
+ {-1, 0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6}, // 6# (F#-major / D#-minor)
+ {-1, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 6} // 7# (C#-major / A#-minor)
+ };
+ return ((lKey / 12) * 7 + lDeltaTable[lsf + 7][lKey % 12]);
+}
+
+// 指定の調性記号において、指定キーに#bの臨時記号が付くかどうかを返す。
+// 戻り値:0なし,2:bb,3:b,4:ナチュラル,5:#,6:##をつけるべきである。
+long CMusicalScoreFrame::KeytoSF (long lKey, long lKeySignature) {
+ long lsf = lKeySignature & 0x000000FF;
+ long lmi = (lKeySignature >> 8) & 0x000000FF;
+ lsf = CLIP (-7, (char)lsf, 7);
+ long lSFTable[15][12] = {
+ // C, -, D, -, E, F, -, G, -, A, -, B
+ {4, 0, 2, 0, 0, 4, 0, 4, 0, 2, 0, 0}, // 7b (Cb-major / Ab-minor)
+ {4, 0, 4, 0, 3, 0, 0, 4, 0, 2, 0, 0}, // 6b (Gb-major / Eb-minor)
+ {0, 0, 4, 0, 3, 0, 0, 4, 0, 4, 0, 3}, // 5b (Db-major / Bb-minor)
+ {0, 0, 4, 0, 4, 0, 3, 0, 0, 4, 0, 3}, // 4b (Ab-major / F-minor)
+ {0, 3, 0, 0, 4, 0, 3, 0, 0, 4, 0, 4}, // 3b (Eb-major / C-minor)
+ {0, 3, 0, 0, 4, 0, 5, 0, 3, 0, 0, 4}, // 2b (Bb-major / G-minor)
+ {0, 5, 0, 3, 0, 0, 5, 0, 3, 0, 0, 4}, // 1b (F-major / D-minor)
+ {0, 5, 0, 3, 0, 0, 5, 0, 5, 0, 3, 0}, // 0 (C-major / A-minor)
+ {0, 5, 0, 5, 0, 4, 0, 0, 5, 0, 3, 0}, // 1# (G-major / E-minor)
+ {4, 0, 0, 5, 0, 4, 0, 0, 5, 0, 5, 0}, // 2# (D-major / B-minor) // 20110111 G,G#修正
+ {4, 0, 0, 5, 0, 5, 0, 4, 0, 0, 5, 0}, // 3# (A-major / F#-minor)
+ {5, 0, 4, 0, 0, 5, 0, 4, 0, 0, 5, 0}, // 4# (E-major / C#-minor)
+ {5, 0, 4, 0, 0, 5, 0, 6, 0, 4, 0, 0}, // 5# (B-major / G#-minor)
+ {5, 0, 6, 0, 4, 0, 0, 6, 0, 4, 0, 0}, // 6# (F#-major / D#-minor)
+ {0, 0, 6, 0, 4, 0, 0, 6, 0, 6, 0, 4} // 7# (C#-major / A#-minor)
+ };
+ return (lSFTable[lsf + 7][lKey % 12]);
+}
+
+// トラックインデックス(0〜65535)・五線番号をY座標[pixel]に変換
+long CMusicalScoreFrame::TrackIndexLineNotoY (long lTrackIndex, long lLineNo) {
+ ASSERT (0<= lTrackIndex &&lTrackIndex < GetTrackInfoCount ());
+ // デフォルトのm_lTrackZoom=4。
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ VERIFY (pTrackInfo = GetTrackInfo (lTrackIndex));
+ long lTrackTop = pTrackInfo->m_lTop;
+ long lTrackHeight = pTrackInfo->m_lHeight;
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long lKey000Y = 0;
+ long ry = 4;
+ switch (lTrackFlags & 0x0000000F) {
+ case 1: // ト音記号
+ lKey000Y = (lTrackTop + lTrackHeight / 2) * m_lTrackZoom + 41 * ry;
+ break;
+ case 2: // へ音記号
+ lKey000Y = (lTrackTop + lTrackHeight / 2) * m_lTrackZoom + 29 * ry;
+ break;
+ case 3: // 大譜表
+ lKey000Y = (lTrackTop + lTrackHeight / 2) * m_lTrackZoom + 35 * ry;
+ break;
+ default:
+ lKey000Y = (lTrackTop + lTrackHeight / 2) * m_lTrackZoom + 35 * ry;
+ break;
+ }
+ return lKey000Y - lLineNo * ry;
+}
+
+// トラックインデックス(0〜65535)・ノートキー(0〜127)をy座標[pixel]に変換
+long CMusicalScoreFrame::TrackIndexKeytoY (long lTrackIndex, long lKey, long lKeySignature) {
+ long lLineNo = KeytoLineNo (lKey, lKeySignature);
+ return TrackIndexLineNotoY (lTrackIndex, lLineNo);
+}
+
+
+
+// x座標[pixel]からタイム[tick]を取得
+long CMusicalScoreFrame::XtoTime (long x) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lMeasureCount = m_theMeasureInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lMeasureCount - 1; j++) {
+ if (GetMeasureLeft (j + 1) * m_lTimeZoom > x) {
+ break;
+ }
+ }
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ VERIFY (pMeasureInfo = GetMeasureInfo (j));
+ long lDeltaX_TimeZoom = x -
+ (pMeasureInfo->m_lLeft + pMeasureInfo->m_lSignatureWidth +
+ pMeasureInfo->m_lPreWidth) * m_lTimeZoom;
+ lDeltaX_TimeZoom = MAX (0, lDeltaX_TimeZoom);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ return pMeasureInfo->m_lTime + lDeltaX_TimeZoom * lTimeResolution / 8 / m_lTimeZoom;
+ // 注:ズーム倍率1倍のとき4分音符の長さを8ピクセルと定義している。
+
+}
+
+// タイム[tick]をx座標[pixel]に変換
+long CMusicalScoreFrame::TimetoX (long lTime) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lMeasureCount = m_theMeasureInfoArray.GetSize ();
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ ASSERT (0 <= lMeasure && lMeasure < lMeasureCount);
+ long j;
+ for (j = 0; j < lMeasureCount - 1; j++) {
+ if (GetMeasureTime (j + 1) > lTime) {
+ break;
+ }
+ }
+ long lMeasureTime = GetMeasureTime (j);
+ long lDeltaTime = lTime - lMeasureTime;
+ ASSERT (lDeltaTime >= 0);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ VERIFY (pMeasureInfo = GetMeasureInfo (j));
+
+ return
+ pMeasureInfo->m_lLeft * m_lTimeZoom +
+ pMeasureInfo->m_lSignatureWidth * m_lTimeZoom +
+ pMeasureInfo->m_lPreWidth * m_lTimeZoom +
+ (lDeltaTime * 8 * m_lTimeZoom / lTimeResolution);
+ // 注:ズーム倍率1倍のとき4分音符の長さを8ピクセルと定義している。
+}
+
+// 小節をx座標[pixel]に変換(小節境界線位置)
+long CMusicalScoreFrame::MeasuretoX (long lMeasure) {
+ long lMeasureCount = GetMeasureInfoCount ();
+ ASSERT (0 <= lMeasure && lMeasure < lMeasureCount);
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ VERIFY (pMeasureInfo = GetMeasureInfo (lMeasure));
+ return pMeasureInfo->m_lLeft * m_lTimeZoom;
+}
+
+// 小節をx座標[pixel]に変換(小節境界線+拍子調整記号位置)
+long CMusicalScoreFrame::MeasuretoX2 (long lMeasure) {
+ long lMeasureCount = GetMeasureInfoCount ();
+ ASSERT (0 <= lMeasure && lMeasure < lMeasureCount);
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ VERIFY (pMeasureInfo = GetMeasureInfo (lMeasure));
+ return (pMeasureInfo->m_lLeft + pMeasureInfo->m_lSignatureWidth) * m_lTimeZoom;
+}
+
+// 時間方向のスクロールポジション取得
+long CMusicalScoreFrame::GetTimeScrollPos () {
+ return m_lTimeScrollPos;
+}
+
+// トラック方向のスクロールポジション取得
+long CMusicalScoreFrame::GetTrackScrollPos () {
+ return m_lTrackScrollPos;
+}
+
+// 時間方向のスクロールポジション設定
+long CMusicalScoreFrame::SetTimeScrollPos (long lTimeScrollPos) {
+ long lOldTimeScrollPos = m_lTimeScrollPos;
+ m_wndTimeScroll.SetScrollPos (lTimeScrollPos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ long lDeltaTimeScrollPos = m_lTimeScrollPos - lOldTimeScrollPos;
+ m_pTimeScaleView->ScrollWindow (-lDeltaTimeScrollPos, 0);
+ m_pTrackTimeView->ScrollWindow (-lDeltaTimeScrollPos, 0);
+ m_pTimeScaleView->UpdateWindow ();
+ m_pTrackTimeView->UpdateWindow ();
+ return m_lTimeScrollPos;
+}
+
+// トラック向のスクロールポジション設定
+long CMusicalScoreFrame::SetTrackScrollPos (long lTrackScrollPos) {
+ long lOldTrackScrollPos = m_lTrackScrollPos;
+ m_wndTrackScroll.SetScrollPos (lTrackScrollPos);
+ m_lTrackScrollPos = m_wndTrackScroll.GetScrollPos ();
+ long lDeltaTrackScrollPos = m_lTrackScrollPos - lOldTrackScrollPos;
+ m_pTrackScaleView->ScrollWindow (0, -lDeltaTrackScrollPos);
+ m_pTrackTimeView->ScrollWindow (0, -lDeltaTrackScrollPos);
+ m_pTrackScaleView->UpdateWindow ();
+ m_pTrackTimeView->UpdateWindow ();
+ return m_lTrackScrollPos;
+}
+
+
+// 表示されているタイムの左端を求める
+long CMusicalScoreFrame::GetVisibleLeftTime () {
+ return XtoTime (m_lTimeScrollPos);
+}
+
+// 表示されているタイムの右端を求める
+long CMusicalScoreFrame::GetVisibleRightTime () {
+ CRect rcClient;
+ m_pTimeScaleView->GetClientRect (&rcClient);
+ return XtoTime (m_lTimeScrollPos + rcClient.Width ());
+}
+
+// 表示されているトラックの上限を計算
+long CMusicalScoreFrame::GetVisibleTopTrack () {
+ long lTrackCount = GetTrackInfoCount ();
+ long lTrackIndex;
+ for (lTrackIndex = 0; lTrackIndex < lTrackCount - 1; lTrackIndex++) {
+ if (GetTrackInfo (lTrackIndex + 1)->m_lTop * m_lTrackZoom >= m_lTrackScrollPos) {
+ break;
+ }
+ }
+ return lTrackIndex;
+}
+
+// 表示されているトラックの下限を計算
+long CMusicalScoreFrame::GetVisibleBottomTrack () {
+ CRect rcClient;
+ m_pTrackScaleView->GetClientRect (&rcClient);
+ long lTrackCount = m_theTrackInfoArray.GetSize ();
+ long lTrackIndex;
+ for (lTrackIndex = 0; lTrackIndex < lTrackCount; lTrackIndex++) {
+ if (GetTrackInfo (lTrackIndex)->m_lTop * m_lTrackZoom >= m_lTrackScrollPos + rcClient.Height ()) {
+ break;
+ }
+ }
+ return lTrackIndex;
+}
+
+// スプリッターキャプターの描画
+void CMusicalScoreFrame::DrawSplitterCaptor (CDC* pDC, CPoint pt) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CPen pen;
+ CPen* pOldPen;
+ pen.CreatePen (PS_SOLID, 4, ::GetSysColor(COLOR_BTNSHADOW));
+ pDC->SetROP2 (R2_XORPEN);
+ pOldPen = pDC->SelectObject (&pen);
+ if (m_bSplitterMovingH) {
+ pDC->MoveTo (0, pt.y);
+ pDC->LineTo (rcClient.Width (), pt.y);
+ }
+ if (m_bSplitterMovingV) {
+ pDC->MoveTo (pt.x, 0);
+ pDC->LineTo (pt.x, rcClient.Height ());
+ }
+ pDC->SelectObject (pOldPen);
+}
+
+
+
+
+// 現在のトラックのインデックスを取得
+long CMusicalScoreFrame::GetCurTrackIndex () {
+ return m_pTrackListBox->GetCurSel ();
+}
+
+// 現在のチャンネルを取得
+long CMusicalScoreFrame::GetCurChannel () {
+ return m_wndChannelCombo.GetCurSel ();
+}
+
+// 現在のスナップ[ティック]を取得
+long CMusicalScoreFrame::GetCurSnap () {
+ CString strText;
+ m_wndSnapCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在のベロシティを取得
+long CMusicalScoreFrame::GetCurVelocity () {
+ CString strText;
+ m_wndVelocityCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在の(音符の)長さ[ティック]を取得
+long CMusicalScoreFrame::GetCurDuration () {
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在の表示精度[ティック]を取得
+long CMusicalScoreFrame::GetCurResolution () {
+ CString strText;
+ m_wndResolutionCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在のトラックのインデックスを設定
+BOOL CMusicalScoreFrame::SetCurTrackIndex (long lCurTrackIndex) {
+ ASSERT (0 <= lCurTrackIndex && lCurTrackIndex < MAXMIDITRACKNUM);
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ m_wndTrackCombo.SetCurSel (lCurTrackIndex);
+ m_pTrackListBox->SetCurSel (lCurTrackIndex);
+ //m_pCurTrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (m_bOnlyCurTrack) {
+ long lCount = m_pTrackListBox->GetCount ();
+ for (long i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, (i == lCurTrackIndex ? 1 : 0));
+ }
+ m_pTrackTimeView->Invalidate ();
+ }
+ return TRUE;
+}
+
+// 現在のチャンネルを設定
+BOOL CMusicalScoreFrame::SetCurChannel (long lCurChannel) {
+ ASSERT (0 <= lCurChannel && lCurChannel < 16);
+ m_wndChannelCombo.SetCurSel (lCurChannel);
+ return TRUE;
+}
+
+// 現在のスナップ[ティック]を設定
+BOOL CMusicalScoreFrame::SetCurSnap (long lCurSnap) {
+ ASSERT (1 <= lCurSnap);
+ CString strText;
+ strText.Format (_T("%d"), lCurSnap);
+ m_wndSnapCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 現在のベロシティを設定
+BOOL CMusicalScoreFrame::SetCurVelocity (long lCurVelocity) {
+ ASSERT (0 <= lCurVelocity && lCurVelocity <= 127);
+ CString strText;
+ strText.Format (_T("%d"), lCurVelocity);
+ m_wndVelocityCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 現在の(音符の)長さ[ティック]を設定
+BOOL CMusicalScoreFrame::SetCurDuration (long lCurDuration) {
+ ASSERT (0 <= lCurDuration);
+ CString strText;
+ strText.Format (_T("%d"), lCurDuration);
+ m_wndDurationCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 現在の表示精度[ティック]を設定
+BOOL CMusicalScoreFrame::SetCurResolution (long lCurResolution) {
+ ASSERT (0 <= lCurResolution);
+ CString strText;
+ strText.Format (_T("%d"), lCurResolution);
+ m_wndResolutionCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 指定インデックスのトラックが表示状態か調べる
+BOOL CMusicalScoreFrame::IsTrackVisible (long lTrackIndex) {
+ // (1)現在のトラックのみ表示がONのときは、現在のトラックのみがVisible、他はUnVisible。
+ // (2)すべてのトラックを表示がONのときは、全てのトラックがVisible。
+ // (3)その他の場合(通常時)は、m_bTrackVisible[MAXMIDITRACKNUM]の値に従う。
+ ASSERT (0 <= lTrackIndex && lTrackIndex < MAXMIDITRACKNUM);
+ if (m_bOnlyCurTrack == TRUE &&
+ GetCurTrackIndex () == lTrackIndex ||
+ m_bShowAllTrack == TRUE ||
+ m_bShowAllTrack == FALSE &&
+ m_bOnlyCurTrack == FALSE &&
+ m_bTrackVisible[lTrackIndex] == TRUE) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// 指定インデックスのトラックを表示状態にする
+BOOL CMusicalScoreFrame::SetTrackVisible (long lTrackIndex) {
+ // (1)現在のトラックのみ表示がONのときは、現在のトラックを指定トラックに変更する
+ // (2)すべてのトラックを表示がONのときは、何もしない。
+ // (3)その他の場合(通常時)は、m_bTrackVisible[lTrackIndex]をチェック・可視化する。
+ ASSERT (0 <= lTrackIndex && lTrackIndex < MAXMIDITRACKNUM);
+ if (m_bOnlyCurTrack == TRUE) {
+ m_wndTrackCombo.SetCurSel (lTrackIndex);
+ m_pTrackListBox->SetCurSel (lTrackIndex);
+ }
+ else if (m_bShowAllTrack == TRUE) {
+ ;
+ }
+ else {
+ m_pTrackListBox->SetCheck (lTrackIndex, TRUE);
+ m_bTrackVisible[lTrackIndex] = TRUE;
+ }
+ return TRUE;
+}
+
+
+
+// トラックコンボの更新
+BOOL CMusicalScoreFrame::UpdateTrackCombo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ //pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ // 旧状態の保持
+ static MIDITrack* pOldMIDITrack[MAXMIDITRACKNUM];
+ BOOL bOldTrackVisible[MAXMIDITRACKNUM];
+ memcpy (bOldTrackVisible, m_bTrackVisible, sizeof (BOOL) * MAXMIDITRACKNUM);
+ long lOldCurSel = m_wndTrackCombo.GetCurSel ();
+ long lOldCount = m_wndTrackCombo.GetCount ();
+ MIDITrack* pOldCurTrack = NULL;
+ if (0 <= lOldCurSel && lOldCurSel < __min (lOldCount, MAXMIDITRACKNUM)) {
+ pOldCurTrack = pOldMIDITrack[lOldCurSel];
+ }
+
+ // コンボの初期化
+ m_wndTrackCombo.RemoveAllItem ();
+
+ // コンボに項目を追加
+ long i = 0;
+ long j = 0;
+ TCHAR szTrackName1[1024];
+ TCHAR szTrackName2[1024];
+ CString strText;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ memset (szTrackName1, 0, sizeof (szTrackName1));
+ memset (szTrackName2, 0, sizeof (szTrackName2));
+ MIDITrack_GetName (pMIDITrack, szTrackName1, TSIZEOF (szTrackName1) - 1);
+ codestr2str (szTrackName1, TCSLEN (szTrackName1), szTrackName2, TSIZEOF (szTrackName2) - 1);
+ strText.Format (_T("%d-%s"), i + (bTrackZeroOrigin ? 0 : 1), szTrackName2);
+ long lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ m_wndTrackCombo.AddItem (strText, lForeColor, lBackColor);
+
+ // 現在のトラックである場合選択
+ if (pMIDITrack == pOldCurTrack) {
+ m_wndTrackCombo.SetCurSel (i);
+ }
+ i++;
+ }
+
+ // 現在選択しているものがない場合は強制選択
+ long lNewCount = m_wndTrackCombo.GetCount ();
+ long lNewCurSel = m_wndTrackCombo.GetCurSel ();
+ if (m_wndTrackCombo.GetCurSel () == CB_ERR) {
+ if (0 <= lOldCurSel && lOldCurSel < lNewCount) {
+ m_wndTrackCombo.SetCurSel (lOldCurSel);
+ }
+ else if (lNewCount >= 2) {
+ m_wndTrackCombo.SetCurSel (1);
+ }
+ else {
+ m_wndTrackCombo.SetCurSel (0);
+ }
+ }
+
+ // 次回のアップデート呼び出しに備えて現状を保持する。
+ i = 0;
+ memset (pOldMIDITrack, 0, sizeof (MIDITrack*) * MAXMIDITRACKNUM);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ pOldMIDITrack[i] = pMIDITrack;
+ i++;
+ }
+
+ //pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+
+// トラックリストボックスの更新
+BOOL CMusicalScoreFrame::UpdateTrackList () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ //pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ // 旧状態の保持
+ static MIDITrack* pOldMIDITrack[MAXMIDITRACKNUM];
+ BOOL bOldTrackVisible[MAXMIDITRACKNUM];
+ memcpy (bOldTrackVisible, m_bTrackVisible, sizeof (BOOL) * MAXMIDITRACKNUM);
+ long lOldCurSel = m_pTrackListBox->GetCurSel ();
+ long lOldCount = m_pTrackListBox->GetCount ();
+ MIDITrack* pOldCurTrack = NULL;
+ if (0 <= lOldCurSel && lOldCurSel < __min (lOldCount, MAXMIDITRACKNUM)) {
+ pOldCurTrack = pOldMIDITrack[lOldCurSel];
+ }
+
+ // リストの初期化
+ ((CColorfulCheckListBox*)m_pTrackListBox)->RemoveAllItem ();
+
+ // リストの更新
+ long i = 0;
+ long j = 0;
+ TCHAR szTrackName1[1024];
+ TCHAR szTrackName2[1024];
+ CString strText;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ memset (szTrackName1, 0, sizeof (szTrackName1));
+ memset (szTrackName2, 0, sizeof (szTrackName2));
+ MIDITrack_GetName (pMIDITrack, szTrackName1, TSIZEOF (szTrackName1) - 1);
+ codestr2str (szTrackName1, TCSLEN (szTrackName1), szTrackName2, TSIZEOF (szTrackName2) - 1);
+ strText.Format (_T("%d-%s"), i + (bTrackZeroOrigin ? 0 : 1), szTrackName2);
+ long lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ ((CColorfulCheckListBox*)m_pTrackListBox)->AddItem (strText, lForeColor, lBackColor);
+ // チェック状態変数の更新
+ m_bTrackVisible[i] = 1;
+ for (j = 0; j < MAXMIDITRACKNUM; j++) {
+ if (pOldMIDITrack[j] == NULL) {
+ break;
+ }
+ if (pOldMIDITrack[j] == pMIDITrack) {
+ m_bTrackVisible[i] = bOldTrackVisible[j];
+ break;
+ }
+ }
+ // 現在のトラックである場合選択
+ if (pMIDITrack == pOldCurTrack) {
+ m_pTrackListBox->SetCurSel (i);
+ }
+ i++;
+ }
+
+ // 現在選択しているものがない場合は強制選択
+ long lNewCount = m_pTrackListBox->GetCount ();
+ long lNewCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_pTrackListBox->GetCurSel () == LB_ERR) {
+ if (0 <= lOldCurSel && lOldCurSel < lNewCount) {
+ m_pTrackListBox->SetCurSel (lOldCurSel);
+ }
+ else if (lNewCount >= 2) {
+ m_pTrackListBox->SetCurSel (1);
+ }
+ else {
+ m_pTrackListBox->SetCurSel (0);
+ }
+ lNewCurSel = m_pTrackListBox->GetCurSel ();
+ }
+
+ // チェックボックスの完全更新
+ if (m_bShowAllTrack) {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, 1);
+ }
+ }
+ else if (m_bOnlyCurTrack) {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, 0);
+ }
+ if (0 <= lNewCurSel && lNewCurSel < lNewCount) {
+ m_pTrackListBox->SetCheck (lNewCurSel, 1);
+ }
+ }
+ else {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, m_bTrackVisible[i]);
+ }
+ }
+
+
+ // 次回のアップデート呼び出しに備えて現状を保持する。
+ i = 0;
+ memset (pOldMIDITrack, 0, sizeof (MIDITrack*) * MAXMIDITRACKNUM);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ pOldMIDITrack[i] = pMIDITrack;
+ i++;
+ }
+
+ //pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+
+// スナップコンボボックスの更新
+BOOL CMusicalScoreFrame::UpdateSnapCombo () {
+ CString strText;
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)GetDocument ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ long lCurSel = m_wndSnapCombo.GetCurSel ();
+ m_wndSnapCombo.ResetContent ();
+ // スナップコンボボックスの充満
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_4DIVNOTE)); // %d-4分音符
+ strText.Format (strFormat, lTimeResolution * 1);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVNOTE)); // %d-8分音符
+ strText.Format (strFormat, lTimeResolution / 2);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVNOTE)); // %d-3連8分音符
+ strText.Format (strFormat, lTimeResolution / 3);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_16DIVNOTE)); // %d-16分音符
+ strText.Format (strFormat, lTimeResolution / 4);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_24DIVNOTE)); // %d-3連16分音符
+ strText.Format (strFormat, lTimeResolution / 6);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_32DIVNOTE)); // %d-32分音符
+ strText.Format (strFormat, lTimeResolution / 8);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_48DIVNOTE)); // %d-3連32分音符
+ strText.Format (strFormat, lTimeResolution / 12);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_FREE)); // %d-自由
+ strText.Format (strFormat, 1);
+ m_wndSnapCombo.AddString (strText);
+ // カレントセル設定
+ if (lCurSel >= 0) {
+ m_wndSnapCombo.SetCurSel (lCurSel);
+ }
+ return TRUE;
+}
+
+// ベロシティコンボボックスの更新
+BOOL CMusicalScoreFrame::UpdateVelocityCombo () {
+ long i;
+ CString strText;
+ long lCurSel = m_wndVelocityCombo.GetCurSel ();
+ m_wndVelocityCombo.ResetContent ();
+ // ベロシティコンボボックスの充満
+ for (i = 127; i >= 1; i--) {
+ if (i == 127 || (i % 5) == 0) {
+ strText.Format (_T("%d"), i);
+ m_wndVelocityCombo.AddString (strText);
+ }
+ }
+ // カレントセル設定
+ if (lCurSel >= 0) {
+ m_wndVelocityCombo.SetCurSel (lCurSel);
+ }
+ return TRUE;
+}
+
+// 長さコンボボックスの更新
+BOOL CMusicalScoreFrame::UpdateDurationCombo () {
+ CString strText;
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)GetDocument ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ //long lCurSel = m_wndDurationCombo.GetCurSel (); // 20100328廃止
+ CString strCurText;
+ m_wndDurationCombo.GetWindowText (strCurText); // 20100328追加
+ long i = 0;
+ long lCurSel = -1;
+ for (i = 0; i < m_wndDurationCombo.GetCount (); i++) {
+ CString strLBText;
+ m_wndDurationCombo.GetLBText (i, strLBText);
+ if (strLBText == strCurText) {
+ lCurSel = i;
+ break;
+ }
+ } // 20100328追加
+ m_wndDurationCombo.ResetContent ();
+ // 長さコンボボックスの充満
+ strText.Format (_T("%d"), lTimeResolution * 4);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution * 3);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution * 2);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution * 1);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 2);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 3);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 4);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 6);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 8);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 12);
+ m_wndDurationCombo.AddString (strText);
+ // カレントセルの設定
+ if (lCurSel >= 0) {
+ m_wndDurationCombo.SetCurSel (lCurSel);
+ }
+ else { // 20100328追加
+ m_wndDurationCombo.SetWindowText (strCurText); // 20100328追加
+ }
+ return TRUE;
+}
+
+// 表示精度コンボボックスの更新
+BOOL CMusicalScoreFrame::UpdateResolutionCombo () {
+ CString strText;
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)GetDocument ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ long lCurSel = m_wndResolutionCombo.GetCurSel ();
+ m_wndResolutionCombo.ResetContent ();
+ // 表示精度コンボボックスの充満
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_4DIVNOTE)); // %d-4分音符
+ strText.Format (strFormat, lTimeResolution * 1);
+ m_wndResolutionCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVNOTE)); // %d-8分音符
+ strText.Format (strFormat, lTimeResolution / 2);
+ m_wndResolutionCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVNOTE)); // %d-3連8分音符
+ strText.Format (strFormat, lTimeResolution / 3);
+ m_wndResolutionCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_16DIVNOTE)); // %d-16分音符
+ strText.Format (strFormat, lTimeResolution / 4);
+ m_wndResolutionCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_24DIVNOTE)); // %d-3連16分音符
+ strText.Format (strFormat, lTimeResolution / 6);
+ m_wndResolutionCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_32DIVNOTE)); // %d-32分音符
+ strText.Format (strFormat, lTimeResolution / 8);
+ m_wndResolutionCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_48DIVNOTE)); // %d-3連32分音符
+ strText.Format (strFormat, lTimeResolution / 12);
+ m_wndResolutionCombo.AddString (strText);
+ // カレントセル設定
+ if (lCurSel >= 0) {
+ m_wndResolutionCombo.SetCurSel (lCurSel);
+ }
+ return TRUE;
+}
+
+
+// キースクロールバー(縦)のデザイン設定
+void CMusicalScoreFrame::RecalcTrackScrollInfo () {
+ long lTrackInfoCount = GetTrackInfoCount ();
+ MusicalScoreTrackInfo* pLastTrackInfo = NULL;
+ VERIFY (pLastTrackInfo = GetTrackInfo (lTrackInfoCount - 1));
+ long lLastTrackTop = pLastTrackInfo->m_lTop;//GetTrackTop (lTrackInfoCount - 1);
+ long lLastTrackHeight = pLastTrackInfo->m_lHeight;//GetTrackHeight (lTrackInfoCount - 1);
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = (lLastTrackTop + lLastTrackHeight) * m_lTrackZoom;
+ si.nPage = m_lKeyHeight;
+ m_wndTrackScroll.SetScrollInfo (&si, TRUE);
+ m_lTrackScrollPos = m_wndTrackScroll.GetScrollPos ();
+}
+
+
+// タイムスクロールバー(横)のデザイン設定
+void CMusicalScoreFrame::RecalcTimeScrollInfo () {
+ long lMeasureInfoCount = m_theMeasureInfoArray.GetSize ();
+ MusicalScoreMeasureInfo* pFirstMeasureInfo = NULL;
+ VERIFY (pFirstMeasureInfo = GetMeasureInfo (0));
+ long lStartX = pFirstMeasureInfo->m_lLeft + pFirstMeasureInfo->m_lSignatureWidth;
+ MusicalScoreMeasureInfo* pLastMeasureInfo = NULL;
+ VERIFY (pLastMeasureInfo = GetMeasureInfo (MAX (0, lMeasureInfoCount - 2)));
+ long lEndX = pLastMeasureInfo->m_lLeft;
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = lStartX * m_lTimeZoom;
+ si.nMax = lEndX * m_lTimeZoom;
+ si.nPage = m_lTimeWidth;
+ m_wndTimeScroll.SetScrollInfo (&si, TRUE);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ // 注:ズーム倍率1倍のとき4分音符の長さを8ピクセルと定義している。
+}
+
+
+// トラック情報配列削除(各トラック情報配列内の音符情報配列と音符グループ情報配列の削除を含む)
+BOOL CMusicalScoreFrame::DeleteTrackInfoArray () {
+ long i;
+ long lNumTrackInfo = GetTrackInfoCount ();
+ for (i = 0; i < lNumTrackInfo; i++) {
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (i);
+ // トラック情報配列[i]内の3連符グループ情報配列削除
+ VERIFY (DeleteTripletGroupInfoArray (i));
+ // トラック情報配列[i]内の音符グループ情報配列削除
+ VERIFY (DeleteNoteGroupInfoArray (i));
+ // トラック情報配列[i]内の音符情報配列削除
+ VERIFY (DeleteNoteInfoArray (i));
+ // トラック情報配列[i]を削除
+ delete (pTrackInfo);
+ }
+ m_theTrackInfoArray.RemoveAll ();
+ return TRUE;
+}
+
+// トラック情報配列[lTrackIndex]内の音符情報配列削除
+BOOL CMusicalScoreFrame::DeleteNoteInfoArray (long lTrackIndex) {
+ long lNumTrackInfo = GetTrackInfoCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lNumTrackInfo);
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (lTrackIndex);
+ ASSERT (pTrackInfo);
+ long j;
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ for (j = 0; j < lNumNoteInfo; j++) {
+ delete (pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ }
+ pTrackInfo->m_theNoteInfoArray.RemoveAll ();
+ return TRUE;
+}
+
+// トラック情報配列[lTrackIndex]内の音符グループ情報配列削除
+BOOL CMusicalScoreFrame::DeleteNoteGroupInfoArray (long lTrackIndex) {
+ long lNumTrackInfo = GetTrackInfoCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lNumTrackInfo);
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (lTrackIndex);
+ ASSERT (pTrackInfo);
+ long j;
+ long lNumNoteGroupInfo = pTrackInfo->m_theNoteGroupInfoArray.GetSize ();
+ for (j = 0; j < lNumNoteGroupInfo; j++) {
+ delete (pTrackInfo->m_theNoteGroupInfoArray.GetAt (j));
+ }
+ pTrackInfo->m_theNoteGroupInfoArray.RemoveAll ();
+ return TRUE;
+}
+
+// トラック情報配列[lTrackIndex]内の3連音符グループ情報配列削除
+BOOL CMusicalScoreFrame::DeleteTripletGroupInfoArray (long lTrackIndex) {
+ long lNumTrackInfo = GetTrackInfoCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lNumTrackInfo);
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (lTrackIndex);
+ ASSERT (pTrackInfo);
+ long j;
+ long lNumTripletGroupInfo = pTrackInfo->m_theTripletGroupInfoArray.GetSize ();
+ for (j = 0; j < lNumTripletGroupInfo; j++) {
+ delete (pTrackInfo->m_theTripletGroupInfoArray.GetAt (j));
+ }
+ pTrackInfo->m_theTripletGroupInfoArray.RemoveAll ();
+ return TRUE;
+}
+
+// 小節情報配列削除
+BOOL CMusicalScoreFrame::DeleteMeasureInfoArray () {
+ long j;
+ long lNumMeasureInfo = GetMeasureInfoCount ();
+ for (j = 0; j < lNumMeasureInfo; j++) {
+ free (m_theMeasureInfoArray.GetAt (j));
+ }
+ m_theMeasureInfoArray.RemoveAll ();
+ return TRUE;
+}
+
+// 小節情報配列更新
+BOOL CMusicalScoreFrame::UpdateMeasureInfoArray () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+
+ // 小節情報配列をいったん強制削除
+ VERIFY (DeleteMeasureInfoArray ());
+
+ long lEndMeasure, lEndBeat, lEndTick;
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndTimeM = lEndTime;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+ if (lEndBeat != 0 || lEndTick != 0) {
+ MIDIData_MakeTime (pMIDIData, lEndMeasure + 1, 0, 0, &lEndTimeM);
+ }
+ long lFeedTime = lTimeResolution * 4 * 120; // 4/4で120小節の余長
+ lEndTime = CLIP (0, lEndTimeM + lFeedTime, 0x7FFFFFFF);
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ long lMeasure;
+ long lOldTimeSignature = 4 | (2 << 8);
+ long lOldKeySignature = 0 | (0 << 8);
+ long lNextMeasureLeft = 0;
+ long lCurMeasureTime = 0;
+ long lNextMeasureTime = 0;
+ for (lMeasure = 0; lMeasure < lEndMeasure; lMeasure++) {
+ MusicalScoreMeasureInfo* pMeasureInfo = new MusicalScoreMeasureInfo ();
+ if (pMeasureInfo == NULL) {
+ break;
+ }
+ // 左座標[pixel]
+ long lMeasureLeft = lNextMeasureLeft;
+ pMeasureInfo->m_lLeft = lNextMeasureLeft;
+ // 開始時刻[Tick][Subframe]
+ pMeasureInfo->m_lTime = lCurMeasureTime;
+ // 長さ[Tick][Subframe]
+ MIDIData_MakeTime (pMIDIData, lMeasure + 1, 0, 0, &lNextMeasureTime);
+ pMeasureInfo->m_lDuration = lNextMeasureTime - lCurMeasureTime;
+ // 拍子記号
+ long lnn, ldd, lcc, lbb;
+ MIDIData_FindTimeSignature (pMIDIData, lCurMeasureTime, &lnn, &ldd, &lcc, &lbb);
+ long lTimeSignature = ((lnn & 0xFF) | ((ldd & 0xFF) << 8));
+ pMeasureInfo->m_lTimeSignature = lTimeSignature;
+ // 調性記号
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lCurMeasureTime, &lsf, &lmi);
+ long lKeySignature = ((lsf & 0xFF) | ((lmi & 0xFF) << 8));
+ pMeasureInfo->m_lKeySignature = lKeySignature;
+ // 拍子記号/調性記号用幅[pixel]
+ if (lKeySignature != lOldKeySignature ||
+ lTimeSignature != lOldTimeSignature ||
+ lMeasure == 0) { // 同じ記号が入っていても描画するので要調整
+ pMeasureInfo->m_lSignatureWidth = 16;
+ }
+ else {
+ pMeasureInfo->m_lSignatureWidth = 0;
+ }
+ // 左余白幅[pixel]
+ pMeasureInfo->m_lPreWidth = 4;
+ // 小節音符部幅[pixel]
+ // 注:ズーム倍率1倍のとき4分音符の長さを8ピクセルと定義している。
+ pMeasureInfo->m_lWidth = 8 * 4 * lnn / (1 << ldd);
+ // 右余白幅[pixel]
+ pMeasureInfo->m_lPostWidth = 0;
+ // フラグ
+ pMeasureInfo->m_lFlags = 0;
+ // 印刷用変数の仮設定
+ pMeasureInfo->m_lLeftPrint = pMeasureInfo->m_lLeft;
+ pMeasureInfo->m_lSignatureWidthPrint = pMeasureInfo->m_lSignatureWidth;
+ pMeasureInfo->m_lPreWidthPrint = pMeasureInfo->m_lPreWidth;
+ pMeasureInfo->m_lWidthPrint = pMeasureInfo->m_lWidth;
+ pMeasureInfo->m_lPostWidthPrint = pMeasureInfo->m_lPostWidth;
+ // 小節情報構造体を配列に追加
+ m_theMeasureInfoArray.Add (pMeasureInfo);
+ // 次回のループに備える
+ lCurMeasureTime = lNextMeasureTime;
+ lNextMeasureLeft =
+ lMeasureLeft +
+ pMeasureInfo->m_lSignatureWidth +
+ pMeasureInfo->m_lPreWidth +
+ pMeasureInfo->m_lWidth +
+ pMeasureInfo->m_lPostWidth;
+ lOldTimeSignature = lTimeSignature;
+ lOldKeySignature = lKeySignature;
+ }
+ return TRUE;
+}
+
+// トラック情報配列更新(各トラック情報配列内の音符情報配列・音符グループ情報配列の更新含む)
+BOOL CMusicalScoreFrame::UpdateTrackInfoArray () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ // トラック情報配列をいったん強制削除(各トラック情報配列内の音符情報配列・音符グループ情報配列の削除含む)
+ VERIFY (DeleteTrackInfoArray ());
+
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lNextTop = 0;
+ // 各トラックの最大キー・最小キー取得およびト音記号・ヘ音記号・大譜表の識別
+ long i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ MusicalScoreTrackInfo* pTrackInfo = new MusicalScoreTrackInfo ();
+ if (pTrackInfo == NULL) {
+ break;
+ }
+ pTrackInfo->m_lTop = lNextTop;
+ if (IsTrackVisible (i)) {
+ // このトラックのノートイベントの最大キーと最小キーを求める。
+ long lMaxKey = 0;
+ long lMinKey = 127;
+ long lCount = 0;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) || MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ long lKey = MIDIEvent_GetKey (pMIDIEvent);
+ if (lKey < lMinKey) {
+ lMinKey = lKey;
+ }
+ if (lKey > lMaxKey) {
+ lMaxKey = lKey;
+ }
+ lCount++;
+ }
+ }
+ // 音符が存在しない(ト音記号とする)
+ if (lMinKey == 127 && lMaxKey == 0) {
+ pTrackInfo->m_lFlags = 1;
+ pTrackInfo->m_lHeight = 24;
+ }
+ // ト音記号
+ else if (lMinKey >= 60 && lCount > 0) {
+ pTrackInfo->m_lFlags = 1;
+ pTrackInfo->m_lHeight = 24;
+ }
+ // ヘ音記号
+ else if (lMaxKey <= 60 && lCount > 0) {
+ pTrackInfo->m_lFlags = 2;
+ pTrackInfo->m_lHeight = 24;
+ }
+ // 大譜表
+ else {
+ pTrackInfo->m_lFlags = 3;
+ pTrackInfo->m_lHeight = 36;
+ }
+ }
+ else {
+ // 表示しない
+ pTrackInfo->m_lFlags = 0;
+ pTrackInfo->m_lHeight = 0;
+ }
+ // 印刷用変数の仮設定
+ pTrackInfo->m_lTopPrint = pTrackInfo->m_lTop;
+ pTrackInfo->m_lHeightPrint = pTrackInfo->m_lHeight;
+
+ m_theTrackInfoArray.Add (pTrackInfo);
+ lNextTop = pTrackInfo->m_lTop + pTrackInfo->m_lHeight;
+ i++;
+ }
+
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (IsTrackVisible (i)) {
+ // トラック情報配列[i]内の音符情報配列を更新
+ UpdateNoteInfoArray (i, pMIDITrack);
+ // トラック情報配列[i]内の音符グループ情報配列を更新
+ UpdateNoteGroupInfoArray (i, pMIDITrack);
+ // トラック情報配列[i]内の3連符グループ情報配列を更新
+ UpdateTripletGroupInfoArray (i, pMIDITrack);
+ }
+ i++;
+ }
+
+ return TRUE;
+}
+
+// トラック情報配列[lTrackIndex]内の音符情報配列を更新
+BOOL CMusicalScoreFrame::UpdateNoteInfoArray (long lTrackIndex, MIDITrack* pMIDITrack) {
+ long lNumTrackInfoArray = GetTrackInfoCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lNumTrackInfoArray);
+ ASSERT (pMIDITrack);
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDIEvent* pMIDIEvent = NULL;
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+
+ // トラック情報配列[lTrackIndex]内の音符情報配列をいったん削除
+ VERIFY (DeleteNoteInfoArray (lTrackIndex));
+
+ // SMPTEベースでは対応しない。
+ if (lTimeMode != MIDIDATA_TPQNBASE) {
+ return TRUE;
+ }
+
+ // 現在の表示精度[ティック]を取得
+ // 0=4分音符,1=8分音符,2=3連8分音符,3=16分音符,4=3連16分音符,5=32分音符,6=3連32分音符
+ long lViewResolutionIndex = m_wndResolutionCombo.GetCurSel ();
+ long lViewResolution = lTimeResolution; // 普通音符用表示解像度
+ long lViewResolution3 = lTimeResolution; // 3連音符用表示解像度
+ switch (lViewResolutionIndex) {
+ case 0: // 4分音符
+ lViewResolution = lTimeResolution;
+ lViewResolution3 = lTimeResolution;
+ break;
+ case 1: // 8分音符
+ lViewResolution = lTimeResolution / 2;
+ lViewResolution3 = lTimeResolution / 2;
+ break;
+ case 2: // 3連8分音符
+ lViewResolution = lTimeResolution / 2;
+ lViewResolution3 = lTimeResolution / 3;
+ break;
+ case 3: // 16分音符
+ lViewResolution = lTimeResolution / 4;
+ lViewResolution3 = lTimeResolution / 3;
+ break;
+ case 4: // 3連16分音符
+ lViewResolution = lTimeResolution / 4;
+ lViewResolution3 = lTimeResolution / 6;
+ break;
+ case 5: // 32分音符
+ lViewResolution = lTimeResolution / 8;
+ lViewResolution3 = lTimeResolution / 6;
+ break;
+ case 6: // 3連32分音符
+ lViewResolution = lTimeResolution / 8;
+ lViewResolution3 = lTimeResolution / 12;
+ break;
+ }
+ if (lViewResolution <= 0) {
+ lViewResolution = 1;
+ }
+ if (lViewResolution3 <= 0) {
+ lViewResolution = 1;
+ }
+
+ // 表現可能な音符の長さ
+ long lDur960 = lTimeResolution * 8;
+ long lDur840 = lTimeResolution * 7;
+ long lDur720 = lTimeResolution * 6;
+ long lDur600 = lTimeResolution * 5;
+ long lDur480 = lTimeResolution * 4; // 全音符
+ long lDur360 = lTimeResolution * 3; // 付点2分音符
+ long lDur240 = lTimeResolution * 2; // 2分音符
+ long lDur180 = lTimeResolution * 3 / 2; // 付点4分音符
+ long lDur120 = lTimeResolution; // 4分音符
+ long lDur90 = lTimeResolution * 3 / 4; // 付点8分音符
+ long lDur80 = lTimeResolution * 2 / 3; // 3連4分音符
+ long lDur60 = lTimeResolution / 2; // 8分音符
+ long lDur45 = lTimeResolution * 3 / 8; // 付点16分音符
+ long lDur40 = lTimeResolution / 3; // 3連8分音符
+ long lDur30 = lTimeResolution / 4; // 16分音符
+ long lDur20 = lTimeResolution / 6; // 3連16分音符
+ long lDur15 = lTimeResolution / 8; // 32分音符
+ long lDur10 = lTimeResolution / 12; // 3連32分音符
+
+ // 補正ノートオンタイムを計算し、m_lUser1に格納
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ long lInTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lOutTime = lInTime + MIDIEvent_GetDuration (pMIDIEvent);
+ // レゾ=例:16分音符でクォンタイズ
+ if (lInTime % (lViewResolution3) == 0) { // 3連n分音符(例:3連16分音符の倍数)
+ pMIDIEvent->m_lUser1 = lInTime;
+ }
+ else { // 通常n分音符又は付点n分音符(例:16分音符の倍数)
+ pMIDIEvent->m_lUser1 =
+ ((lInTime + lViewResolution / 2 - 1) / lViewResolution) * (lViewResolution);
+ }
+ }
+ }
+
+ // 補正ノートオフタイムを計算し、m_lUser2に格納
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ // このノートイベントの補正後開始時刻を取得
+ long lNoteOnTime, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick;
+ lNoteOnTime = pMIDIEvent->m_lUser1;
+ MIDIData_BreakTime (pMIDIData, lNoteOnTime, &lNoteOnMeasure, &lNoteOnBeat, &lNoteOnTick);
+ // このノートイベントの正式な終了時刻を取得
+ long lNoteOffTime, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick;
+ lNoteOffTime = MIDIEvent_GetTime (pMIDIEvent->m_pNextCombinedEvent);
+ MIDIData_BreakTime (pMIDIData, lNoteOffTime, &lNoteOffMeasure, &lNoteOffBeat, &lNoteOffTick);
+ // 次の時刻のノートイベントの補正後開始時刻を取得
+ long lNextOnTime, lNextOnMeasure, lNextOnBeat, lNextOnTick;
+ MIDIEvent* pNextEvent = MIDIEvent_GetNextEvent (pMIDIEvent);
+ while (pNextEvent) {
+ if (MIDIEvent_IsNoteOn (pNextEvent) && MIDIEvent_IsNote (pNextEvent)) {
+ if (pNextEvent->m_lUser1 > pMIDIEvent->m_lUser1) {
+ break;
+ }
+ }
+ pNextEvent = MIDIEvent_GetNextEvent (pNextEvent);
+ }
+ if (pNextEvent) {
+ lNextOnTime = pNextEvent->m_lUser1;
+ MIDIData_BreakTime (pMIDIData, lNextOnTime, &lNextOnMeasure, &lNextOnBeat, &lNextOnTick);
+ if (lNextOnMeasure > lNoteOffMeasure) {
+ lNextOnTime = GetMeasureTime (lNoteOffMeasure + 1);
+ }
+ }
+ else {
+ lNextOnTime = GetMeasureTime (lNoteOnMeasure + 1);
+ }
+ // 3連n分音符の場合
+ if (lNoteOnTime % lViewResolution3 == 0 &&
+ (lNextOnTime - lNoteOnTime) % lViewResolution != 0) {
+ pMIDIEvent->m_lUser2 =
+ ((lNoteOffTime + lViewResolution3 / 2 - 1) / lViewResolution3) * lViewResolution3;
+ if (pMIDIEvent->m_lUser2 - pMIDIEvent->m_lUser1 < lViewResolution3) {
+ pMIDIEvent->m_lUser2 = pMIDIEvent->m_lUser1 + lViewResolution3; // (例)フィル3連16分音符
+ }
+
+ }
+ // 通常n分音符又は付点n分音符の場合
+ else {
+ pMIDIEvent->m_lUser2 =
+ ((lNoteOffTime + lViewResolution / 2 - 1) / lViewResolution) * lViewResolution;
+ if (pMIDIEvent->m_lUser2 - pMIDIEvent->m_lUser1 < lViewResolution) {
+ pMIDIEvent->m_lUser2 = pMIDIEvent->m_lUser1 + lViewResolution; // (例)フィル16分音符
+ }
+ }
+ }
+ }
+
+ // 音符情報の生成と配列への登録
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (lTrackIndex);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ long lNoteOnMeasure, lNoteOnBeat, lNoteOnTick;
+ long lNoteOffMeasure, lNoteOffBeat, lNoteOffTick;
+
+ MIDIData_BreakTime (pMIDIData, pMIDIEvent->m_lUser1, &lNoteOnMeasure, &lNoteOnBeat, &lNoteOnTick);
+ MIDIData_BreakTime (pMIDIData, pMIDIEvent->m_lUser2, &lNoteOffMeasure, &lNoteOffBeat, &lNoteOffTick);
+
+ long lMeasure;
+ // このノートイベントの各所属小節について
+ for (lMeasure = lNoteOnMeasure; lMeasure <= lNoteOffMeasure; lMeasure++) {
+ MusicalScoreMeasureInfo* pMeasureInfo = GetMeasureInfo (lMeasure);
+ long lMeasureTime = pMeasureInfo->m_lTime; // この小節の開始タイム[ティック]
+ long lnn = (pMeasureInfo->m_lTimeSignature & 0xFF); // 分子(この小節の拍数)[拍]
+ long ldd = (pMeasureInfo->m_lTimeSignature & 0xFF00) >> 8; // 分母
+ long lBeatDur = 4 * lTimeResolution / (0x01 << ldd); // 1拍の長さ[ティック]
+ long lNextMeasureTime = lMeasureTime + lBeatDur * lnn; // 次の小節の開始タイム[ティック]
+ if (pMIDIEvent->m_lUser2 - lMeasureTime <= 0) {
+ break;
+ }
+ // パターンA:この小節で始まりこの小節で終わる
+ if (lMeasure == lNoteOnMeasure &&
+ (lMeasure == lNoteOffMeasure || (lMeasure == lNoteOffMeasure - 1 && lNoteOffBeat == 0 && lNoteOffTick == 0))) {
+ long lDur = pMIDIEvent->m_lUser2 - pMIDIEvent->m_lUser1;
+ // 通常音符で表現できない場合
+ if (lDur != lDur960 &&
+ lDur != lDur840 &&
+ lDur != lDur720 &&
+ lDur != lDur600 &&
+ lDur != lDur480 &&
+ lDur != lDur360 &&
+ lDur != lDur240 &&
+ lDur != lDur180 &&
+ lDur != lDur120 &&
+ lDur != lDur90 &&
+ lDur != lDur80 &&
+ lDur != lDur60 &&
+ lDur != lDur45 &&
+ lDur != lDur40 &&
+ lDur != lDur30 &&
+ lDur != lDur20 &&
+ lDur != lDur15 &&
+ lDur != lDur10) {
+ long lDivideTime1 = 0;
+ long lDivideMeasure1 = 0;
+ long lDivideBeat1 = 0;
+ long lDivideTick1 = 0;
+ long lDivideTime2 = 0;
+ long lDivideMeasure2 = 0;
+ long lDivideBeat2 = 0;
+ long lDivideTick2 = 0;
+ // a)最初の拍に半端があり、次の拍にまたがる場合
+ if (lNoteOnTick > 0 && (lDur > lBeatDur || (lNoteOnBeat != lNoteOffBeat && lNoteOffTick > 0 ))) {
+ lDivideTime1 = lMeasureTime + (lNoteOnBeat + 1) * lBeatDur;
+ lDivideMeasure1 = lMeasure;
+ lDivideBeat1 = lNoteOnBeat + 1;
+ lDivideTick1 = 0;
+ }
+ // b)最後の拍に半端があり、前の拍からつながる場合
+ if (lNoteOnBeat != lNoteOffBeat && lNoteOffTick > 0) {
+ lDivideTime2 = lMeasureTime + (lNoteOffBeat) * lBeatDur;
+ lDivideMeasure2 = lMeasure;
+ lDivideBeat2 = lNoteOffBeat;
+ lDivideTick2 = 0;
+ }
+ // c)最初の拍又は最後の拍につながるべき半端はない場合
+ if (lDivideTime1 == lDivideTime2) {
+ // 4分音符より短く、既存音符では表現できない長さの場合、8分音符+残りで表現
+ if (lDur < lDur120) {
+ lDivideTime2 = pMIDIEvent->m_lUser1 + lDur60;
+ MIDIData_BreakTime (pMIDIData, lDivideTime2, &lDivideMeasure2, &lDivideBeat2, &lDivideTick2);
+ }
+ // 2分音符より短く、既存音符では表現できない長さの場合、4分音符+残りで表現
+ else if (lDur < lDur240) {
+ lDivideTime2 = pMIDIEvent->m_lUser1 + lDur120;
+ MIDIData_BreakTime (pMIDIData, lDivideTime2, &lDivideMeasure2, &lDivideBeat2, &lDivideTick2);
+ }
+ // 付点2分音符より短く、既存音符では表現できない長さの場合、2分音符+残りで表現
+ else if (lDur < lDur360) {
+ lDivideTime2 = pMIDIEvent->m_lUser1 + lDur240;
+ MIDIData_BreakTime (pMIDIData, lDivideTime2, &lDivideMeasure2, &lDivideBeat2, &lDivideTick2);
+ }
+ // 1分音符より短く、既存音符では表現できない長さの場合、付点2分音符+残りで表現
+ else if (lDur < lDur480) {
+ lDivideTime2 = pMIDIEvent->m_lUser1 + lDur360;
+ MIDIData_BreakTime (pMIDIData, lDivideTime2, &lDivideMeasure2, &lDivideBeat2, &lDivideTick2);
+ }
+ // その他の場合、分割をあきらめ、最も近い音符で表現。
+ else {
+ lDivideTime2 = 0;
+ }
+ }
+ // 拍境界分割なし(音符1つ)
+ if (lDivideTime1 == 0 && lDivideTime2 == 0) {
+ MusicalScoreNoteInfo* pNoteInfo1 = CreateNote
+ (pMIDIEvent, pMIDIEvent->m_lUser1, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick,
+ pMIDIEvent->m_lUser2, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick, 0x00000000);
+ AddNoteInfo (pTrackInfo, pNoteInfo1);
+ }
+ // 最初の拍境界で分割(音符2つ)
+ else if (lDivideTime1 != 0 && lDivideTime2 == 0) {
+ MusicalScoreNoteInfo* pNoteInfo1 = CreateNote
+ (pMIDIEvent, pMIDIEvent->m_lUser1, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick,
+ lDivideTime1, lDivideMeasure1, lDivideBeat1, lDivideTick1, 0x00000001);
+ AddNoteInfo (pTrackInfo, pNoteInfo1);
+ MusicalScoreNoteInfo* pNoteInfo2 = CreateNote
+ (pMIDIEvent, lDivideTime1, lDivideMeasure1, lDivideBeat1, lDivideTick1,
+ pMIDIEvent->m_lUser2, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick, 0x00000002);
+ AddNoteInfo (pTrackInfo, pNoteInfo2);
+ }
+ // 最後の拍境界で分割(音符2つ)
+ else if (lDivideTime1 == 0 && lDivideTime2 != 0) {
+ MusicalScoreNoteInfo* pNoteInfo1 = CreateNote
+ (pMIDIEvent, pMIDIEvent->m_lUser1, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick,
+ lDivideTime2, lDivideMeasure2, lDivideBeat2, lDivideTick2, 0x00000001);
+ AddNoteInfo (pTrackInfo, pNoteInfo1);
+ MusicalScoreNoteInfo* pNoteInfo2 = CreateNote
+ (pMIDIEvent, lDivideTime2, lDivideMeasure2, lDivideBeat2, lDivideTick2,
+ pMIDIEvent->m_lUser2, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick, 0x00000002);
+ AddNoteInfo (pTrackInfo, pNoteInfo2);
+ }
+ // 最初の拍境界と最後の拍境界で分割(音符3つ)
+ else if (lDivideTime1 != 0 && lDivideTime2 != 0) {
+ MusicalScoreNoteInfo* pNoteInfo1 = CreateNote
+ (pMIDIEvent, pMIDIEvent->m_lUser1, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick,
+ lDivideTime1,lDivideMeasure1, lDivideBeat1, lDivideTick1, 0x00000001);
+ AddNoteInfo (pTrackInfo, pNoteInfo1);
+ MusicalScoreNoteInfo* pNoteInfo2 = CreateNote
+ (pMIDIEvent, lDivideTime1, lDivideMeasure1, lDivideBeat1, lDivideTick1,
+ lDivideTime2,lDivideMeasure2, lDivideBeat2, lDivideTick2, 0x00000003);
+ AddNoteInfo (pTrackInfo, pNoteInfo2);
+ MusicalScoreNoteInfo* pNoteInfo3 = CreateNote
+ (pMIDIEvent, lDivideTime2, lDivideMeasure2, lDivideBeat2, lDivideTick2,
+ pMIDIEvent->m_lUser2, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick, 0x00000002);
+ AddNoteInfo (pTrackInfo, pNoteInfo3);
+ }
+ }
+ // 通常の音符で表現できる場合
+ else {
+ MusicalScoreNoteInfo* pNoteInfo = CreateNote
+ (pMIDIEvent, pMIDIEvent->m_lUser1, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick,
+ pMIDIEvent->m_lUser2, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick, 0x00000000);
+ AddNoteInfo (pTrackInfo, pNoteInfo);
+ }
+ }
+ // パターンB:この小節から始まり次の小節へタイで続く
+ else if (lMeasure == lNoteOnMeasure && lMeasure < lNoteOffMeasure) {
+ long lDur = lNextMeasureTime - pMIDIEvent->m_lUser1;
+ // 拍境界をまたいでおり、通常音符で表現できない場合
+ if (lNoteOnBeat < lnn - 1 &&
+ lDur != lDur960 &&
+ lDur != lDur840 &&
+ lDur != lDur720 &&
+ lDur != lDur600 &&
+ lDur != lDur480 &&
+ lDur != lDur360 &&
+ lDur != lDur240 &&
+ lDur != lDur180 &&
+ lDur != lDur120 &&
+ lDur != lDur90 &&
+ lDur != lDur80 &&
+ lDur != lDur60 &&
+ lDur != lDur45 &&
+ lDur != lDur40 &&
+ lDur != lDur30 &&
+ lDur != lDur20 &&
+ lDur != lDur15 &&
+ lDur != lDur10) {
+ long lDivideTime = lMeasureTime + (lNoteOnBeat + 1) * lBeatDur;
+ long lDivideMeasure = lMeasure;
+ long lDivideBeat = lNoteOnBeat + 1;
+ long lDivideTick = 0;
+ MusicalScoreNoteInfo* pNoteInfo1 = CreateNote
+ (pMIDIEvent, pMIDIEvent->m_lUser1, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick,
+ lDivideTime, lDivideMeasure, lDivideBeat, lDivideTick, 0x00000001);
+ AddNoteInfo (pTrackInfo, pNoteInfo1);
+ MusicalScoreNoteInfo* pNoteInfo2 = CreateNote
+ (pMIDIEvent, lDivideTime, lDivideMeasure, lDivideBeat, lDivideTick,
+ lNextMeasureTime, lMeasure + 1, 0, 0, 0x00000006);
+ AddNoteInfo (pTrackInfo, pNoteInfo2);
+ }
+ // 音符ひとつで表現できる場合
+ else {
+ MusicalScoreNoteInfo* pNoteInfo = CreateNote
+ (pMIDIEvent, pMIDIEvent->m_lUser1, lNoteOnMeasure, lNoteOnBeat, lNoteOnTick,
+ lNextMeasureTime, lNoteOnMeasure + 1, 0, 0, 0x00000004);
+ AddNoteInfo (pTrackInfo, pNoteInfo);
+ }
+ }
+ // パターンC:前の小節からタイで続きこの小節で終了する
+ else if (lMeasure > lNoteOnMeasure &&
+ (lMeasure == lNoteOffMeasure || (lMeasure == lNoteOffMeasure - 1 && lNoteOffBeat == 0 && lNoteOffTick == 0))) {
+ long lDur = pMIDIEvent->m_lUser2 - lMeasureTime;
+ // 拍境界をまたいでおり、通常音符で表現できない場合
+ if (lNoteOffBeat > 0 &&
+ lDur != lDur960 &&
+ lDur != lDur840 &&
+ lDur != lDur720 &&
+ lDur != lDur600 &&
+ lDur != lDur480 &&
+ lDur != lDur360 &&
+ lDur != lDur240 &&
+ lDur != lDur180 &&
+ lDur != lDur120 &&
+ lDur != lDur90 &&
+ lDur != lDur80 &&
+ lDur != lDur60 &&
+ lDur != lDur45 &&
+ lDur != lDur40 &&
+ lDur != lDur30 &&
+ lDur != lDur20 &&
+ lDur != lDur15 &&
+ lDur != lDur10) {
+ long lDivideTime = lMeasureTime + (lNoteOffBeat) * lBeatDur;
+ long lDivideMeasure = lMeasure;
+ long lDivideBeat = lNoteOffBeat;
+ long lDivideTick = 0;
+ MusicalScoreNoteInfo* pNoteInfo1 = CreateNote
+ (pMIDIEvent, lMeasureTime, lMeasure, 0, 0,
+ lDivideTime, lDivideMeasure, lDivideBeat, lDivideTick, 0x00000007);
+ AddNoteInfo (pTrackInfo, pNoteInfo1);
+ MusicalScoreNoteInfo* pNoteInfo2 = CreateNote
+ (pMIDIEvent, lDivideTime, lDivideMeasure, lDivideBeat, lDivideTick,
+ pMIDIEvent->m_lUser2, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick, 0x00000002);
+ AddNoteInfo (pTrackInfo, pNoteInfo2);
+ }
+ // 音符ひとつで表現できる場合
+ else {
+ MusicalScoreNoteInfo* pNoteInfo = CreateNote
+ (pMIDIEvent, lMeasureTime, lMeasure, 0, 0,
+ pMIDIEvent->m_lUser2, lNoteOffMeasure, lNoteOffBeat, lNoteOffTick, 0x00000005);
+ AddNoteInfo (pTrackInfo, pNoteInfo);
+ }
+
+ }
+ // パターンD:前の小節からタイで続き次の小節へタイで続く(全音符のみ)
+ else if (lMeasure > lNoteOnMeasure && lMeasure < lNoteOffMeasure) {
+ MusicalScoreNoteInfo* pNoteInfo = CreateNote
+ (pMIDIEvent, lMeasureTime, lMeasure, 0, 0,
+ lNextMeasureTime, lMeasure + 1, 0, 0, 0x00000008);
+ AddNoteInfo (pTrackInfo, pNoteInfo);
+ }
+ }
+ }
+ }
+
+ // 音符情報のポインタ連結
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ if (j > 0) {
+ pNoteInfo->m_pPrevNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j - 1));
+ }
+ else {
+ pNoteInfo->m_pPrevNoteInfo = NULL;
+ }
+ if (j < lNumNoteInfo - 1) {
+ pNoteInfo->m_pNextNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j + 1));
+ }
+ else {
+ pNoteInfo->m_pNextNoteInfo = NULL;
+ }
+ }
+
+ // 補正ノートオンタイムと補正ノートオフタイムのゼロリセット
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ pMIDIEvent->m_lUser1 = 0;
+ pMIDIEvent->m_lUser2 = 0;
+ }
+ }
+ return TRUE;
+}
+
+// トラック情報配列[lTrackIndex]内の音符グループ情報配列を更新
+BOOL CMusicalScoreFrame::UpdateNoteGroupInfoArray (long lTrackIndex, MIDITrack* pMIDITrack) {
+ long lNumTrackInfoArray = GetTrackInfoCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lNumTrackInfoArray);
+ ASSERT (pMIDITrack);
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+
+ // 表現可能な音符の長さ
+ long lDur960 = lTimeResolution * 8;
+ long lDur840 = lTimeResolution * 7;
+ long lDur720 = lTimeResolution * 6;
+ long lDur600 = lTimeResolution * 5;
+ long lDur480 = lTimeResolution * 4; // 全音符
+ long lDur360 = lTimeResolution * 3; // 付点2分音符
+ long lDur240 = lTimeResolution * 2; // 2分音符
+ long lDur180 = lTimeResolution * 3 / 2; // 付点4分音符
+ long lDur120 = lTimeResolution; // 4分音符
+ long lDur90 = lTimeResolution * 3 / 4; // 付点8分音符
+ long lDur80 = lTimeResolution * 2 / 3; // 3連4分音符
+ long lDur60 = lTimeResolution / 2; // 8分音符
+ long lDur45 = lTimeResolution * 3 / 8; // 付点16分音符
+ long lDur40 = lTimeResolution / 3; // 3連8分音符
+ long lDur30 = lTimeResolution / 4; // 16分音符
+ long lDur20 = lTimeResolution / 6; // 3連16分音符
+ long lDur15 = lTimeResolution / 8; // 32分音符
+ long lDur10 = lTimeResolution / 12; // 3連32分音符
+
+ // トラック情報配列[lTrackIndex]内の音符グループ情報配列をいったん削除
+ VERIFY (DeleteNoteGroupInfoArray (lTrackIndex));
+
+ // 音符グループ情報の生成と配列への登録
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (lTrackIndex);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ MusicalScoreNoteGroupInfo* pNoteGroupInfo = NULL;
+ BOOL bGroupContinueFlag = FALSE;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ long lDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ // この音符は旗付けが必要である場合
+ if (lDur < lDur120 && lDur != lDur80) {
+ // この音符がまだどこのグループにも所属していない場合
+ if (pNoteInfo->m_pNoteGroupInfo == NULL) {
+ // 新しい音符グループ情報を生成する必要がある場合
+ if (bGroupContinueFlag == FALSE) {
+ pNoteGroupInfo =
+ CreateNoteGroupInfo (pNoteInfo);
+ AddNoteGroupInfo (pTrackInfo, pNoteGroupInfo);
+ }
+ pNoteInfo->m_pNoteGroupInfo = pNoteGroupInfo;
+ pNoteGroupInfo->m_pLastNoteInfo = pNoteInfo;
+ // 次の音符がある場合
+ if (j + 1 < lNumNoteInfo) {
+ MusicalScoreNoteInfo* pNextNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j + 1));
+ // 次の音符のオンタイムが現在の音符のオフタイムと離れている場合
+ // 次の音符のオンタイムが現在の音符のオンタイムと同一でない場合
+ if (pNoteInfo->m_lNoteOffTime != pNextNoteInfo->m_lNoteOnTime &&
+ pNoteInfo->m_lNoteOnTime != pNextNoteInfo->m_lNoteOnTime) {
+ bGroupContinueFlag = FALSE; // 現在の音符グループは終了
+ }
+ // 次の音符の所属拍が現在の音符の所属拍と異なる場合
+ else if (pNoteInfo->m_lNoteOnBeat != pNextNoteInfo->m_lNoteOnBeat ||
+ pNoteInfo->m_lNoteOnMeasure != pNextNoteInfo->m_lNoteOnMeasure) {
+ bGroupContinueFlag = FALSE; // 現在の音符グループは終了
+ }
+ // 次の音符が8分音符を超えるの長さの場合
+ else if (pNextNoteInfo->m_lNoteOffTime - pNextNoteInfo->m_lNoteOnTime > lTimeResolution / 2) {
+ bGroupContinueFlag = FALSE; // 現在の音符グループは終了
+ }
+ else {
+ bGroupContinueFlag = TRUE; // 現在の音符グループを続ける
+ }
+ }
+ // 次の音符がない場合
+ else {
+ bGroupContinueFlag = FALSE;
+ }
+ // グループ内最大キー・最小キーの更新
+ long lKey = MIDIEvent_GetKey (pNoteInfo->m_pNoteOnEvent);
+ if (pNoteGroupInfo->m_lMaxKey < lKey) {
+ pNoteGroupInfo->m_lMaxKey = lKey;
+ }
+ if (pNoteGroupInfo->m_lMinKey > lKey) {
+ pNoteGroupInfo->m_lMinKey = lKey;
+ }
+ // グループ内の最大長さ・最小長さの更新
+ long lDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ if (pNoteGroupInfo->m_lMaxDur < lDur) {
+ pNoteGroupInfo->m_lMaxDur = lDur;
+ }
+ if (pNoteGroupInfo->m_lMinDur > lDur) {
+ pNoteGroupInfo->m_lMinDur = lDur;
+ }
+ // 音符グループ内の音符数をインクリメント
+ pNoteGroupInfo->m_lNumNoteInfo++;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+// トラック情報配列[lTrackIndex]内の3連音符グループ情報配列を更新
+BOOL CMusicalScoreFrame::UpdateTripletGroupInfoArray (long lTrackIndex, MIDITrack* pMIDITrack) {
+ long lNumTrackInfoArray = GetTrackInfoCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lNumTrackInfoArray);
+ ASSERT (pMIDITrack);
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+
+ // 表現可能な音符の長さ
+ long lDur960 = lTimeResolution * 8;
+ long lDur840 = lTimeResolution * 7;
+ long lDur720 = lTimeResolution * 6;
+ long lDur600 = lTimeResolution * 5;
+ long lDur480 = lTimeResolution * 4; // 全音符
+ long lDur360 = lTimeResolution * 3; // 付点2分音符
+ long lDur240 = lTimeResolution * 2; // 2分音符
+ long lDur180 = lTimeResolution * 3 / 2; // 付点4分音符
+ long lDur120 = lTimeResolution; // 4分音符
+ long lDur90 = lTimeResolution * 3 / 4; // 付点8分音符
+ long lDur80 = lTimeResolution * 2 / 3; // 3連4分音符
+ long lDur60 = lTimeResolution / 2; // 8分音符
+ long lDur45 = lTimeResolution * 3 / 8; // 付点16分音符
+ long lDur40 = lTimeResolution / 3; // 3連8分音符
+ long lDur30 = lTimeResolution / 4; // 16分音符
+ long lDur20 = lTimeResolution / 6; // 3連16分音符
+ long lDur15 = lTimeResolution / 8; // 32分音符
+ long lDur10 = lTimeResolution / 12; // 3連32分音符
+
+
+ // トラック情報配列[lTrackIndex]内の音符グループ情報配列をいったん削除
+ VERIFY (DeleteTripletGroupInfoArray (lTrackIndex));
+
+ // 3連音符グループ情報の生成と配列への登録
+ MusicalScoreTrackInfo* pTrackInfo = GetTrackInfo (lTrackIndex);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ MusicalScoreTripletGroupInfo* pTripletGroupInfo = NULL;
+ BOOL bGroupContinueFlag = FALSE;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ long lDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ // 3連音符の場合
+ if (lDur == lDur80 ||
+ lDur == lDur40 ||
+ lDur == lDur20 ||
+ lDur == lDur10) {
+ // この音符がまだどこの3連グループにも所属していない場合
+ if (pNoteInfo->m_pTripletGroupInfo == NULL) {
+ // 新しい3連音符グループ情報を生成する必要がある場合
+ if (bGroupContinueFlag == FALSE) {
+ VERIFY (pTripletGroupInfo = CreateTripletGroupInfo (pNoteInfo));
+ VERIFY (AddTripletGroupInfo (pTrackInfo, pTripletGroupInfo));
+ }
+ // ポインタの設定
+ pNoteInfo->m_pTripletGroupInfo = pTripletGroupInfo;
+ pTripletGroupInfo->m_pLastNoteInfo = pNoteInfo;
+ // 次の音符がある場合
+ if (j + 1 < lNumNoteInfo) {
+ MusicalScoreNoteInfo* pNextNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j + 1));
+ // 次の音符がこの音符より後でかつ3連音符でない場合
+ long lNextDur = pNextNoteInfo->m_lNoteOffTime - pNextNoteInfo->m_lNoteOnTime;
+ if (pNextNoteInfo->m_lNoteOnTime >= pNoteInfo->m_lNoteOffTime &&
+ lNextDur != lDur80 &&
+ lNextDur != lDur40 &&
+ lNextDur != lDur20 &&
+ lNextDur != lDur10) {
+ bGroupContinueFlag = FALSE; // 現在の3連音符グループは終了
+ }
+ // 次の音符の所属小節が現在の音符の所属小節と異なる場合
+ else if (pNoteInfo->m_lNoteOnMeasure != pNextNoteInfo->m_lNoteOnMeasure) {
+ bGroupContinueFlag = FALSE; // 現在の3連音符グループは終了
+ }
+ // 次の音符の所属拍が現在の音符の所属拍と異なる場合(音符が拍境界で切れている場合のみ)
+ else if (pNoteInfo->m_lNoteOnBeat != pNextNoteInfo->m_lNoteOnBeat &&
+ pNextNoteInfo->m_lNoteOffTick > 0) {
+ bGroupContinueFlag = FALSE; // 現在の3連音符グループは終了
+ }
+ else {
+ bGroupContinueFlag = TRUE; // 現在の3連音符グループを続ける
+ }
+ }
+ // 次の音符がない場合
+ else {
+ bGroupContinueFlag = FALSE;
+ }
+ // グループ内最大キー・最小キーの更新
+ long lKey = MIDIEvent_GetKey (pNoteInfo->m_pNoteOnEvent);
+ if (pTripletGroupInfo->m_lMaxKey < lKey) {
+ pTripletGroupInfo->m_lMaxKey = lKey;
+ }
+ if (pTripletGroupInfo->m_lMinKey > lKey) {
+ pTripletGroupInfo->m_lMinKey = lKey;
+ }
+ // グループ内の最大長さ・最小長さの更新
+ long lDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ if (pTripletGroupInfo->m_lMaxDur < lDur) {
+ pTripletGroupInfo->m_lMaxDur = lDur;
+ }
+ if (pTripletGroupInfo->m_lMinDur > lDur) {
+ pTripletGroupInfo->m_lMinDur = lDur;
+ }
+ // 3連音符グループ内の音符数をインクリメント
+ pTripletGroupInfo->m_lNumNoteInfo++;
+ }
+ // 3連符開始時刻[Tick]と終了時刻[Tick]の補正
+ if (pTripletGroupInfo->m_lMinDur == lDur80) {
+ pTripletGroupInfo->m_lBeginTime =
+ (pTripletGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime / lDur80) * lDur80;
+ pTripletGroupInfo->m_lEndTime =
+ ((pTripletGroupInfo->m_pLastNoteInfo->m_lNoteOffTime + lDur80 - 1) / lDur80) * lDur80;
+ }
+ else if (pTripletGroupInfo->m_lMinDur == lDur40) {
+ pTripletGroupInfo->m_lBeginTime =
+ (pTripletGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime / lDur40) * lDur40;
+ pTripletGroupInfo->m_lEndTime =
+ ((pTripletGroupInfo->m_pLastNoteInfo->m_lNoteOffTime + lDur40 - 1) / lDur40) * lDur40;
+ }
+ else if (pTripletGroupInfo->m_lMinDur == lDur20) {
+ pTripletGroupInfo->m_lBeginTime =
+ (pTripletGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime / lDur20) * lDur20;
+ pTripletGroupInfo->m_lEndTime =
+ ((pTripletGroupInfo->m_pLastNoteInfo->m_lNoteOffTime + lDur20 - 1) / lDur20) * lDur20;
+ }
+ else if (pTripletGroupInfo->m_lMinDur == lDur10) {
+ pTripletGroupInfo->m_lBeginTime =
+ (pTripletGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime / lDur10) * lDur10;
+ pTripletGroupInfo->m_lEndTime =
+ ((pTripletGroupInfo->m_pLastNoteInfo->m_lNoteOffTime + lDur10 - 1) / lDur10) * lDur10;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+MusicalScoreNoteInfo* CMusicalScoreFrame::CreateNote
+ (MIDIEvent* pNoteEvent, long lNoteOnTime, long lNoteOnMeasure, long lNoteOnBeat, long lNoteOnTick,
+ long lNoteOffTime, long lNoteOffMeasure, long lNoteOffBeat, long lNoteOffTick, long lFlags) {
+ MusicalScoreNoteInfo* pNoteInfo = new MusicalScoreNoteInfo;
+ if (pNoteInfo == NULL) {
+ return NULL;
+ }
+ pNoteInfo->m_pNoteOnEvent = pNoteEvent;
+ pNoteInfo->m_pNoteOffEvent = pNoteEvent->m_pNextCombinedEvent;
+ pNoteInfo->m_lNoteOnTime = lNoteOnTime;
+ pNoteInfo->m_lNoteOnMeasure = lNoteOnMeasure;
+ pNoteInfo->m_lNoteOnBeat = lNoteOnBeat;
+ pNoteInfo->m_lNoteOnTick = lNoteOnTick;
+ pNoteInfo->m_lNoteOffTime = lNoteOffTime;
+ pNoteInfo->m_lNoteOffMeasure = lNoteOffMeasure;
+ pNoteInfo->m_lNoteOffBeat = lNoteOffBeat;
+ pNoteInfo->m_lNoteOffTick = lNoteOffTick;
+ pNoteInfo->m_lFlags = lFlags;
+ pNoteInfo->m_lSelected = (pNoteEvent->m_lUserFlag & MIDIEVENT_SELECTED) ? 1 : 0;
+ pNoteInfo->m_pNoteGroupInfo = NULL;
+ pNoteInfo->m_pTripletGroupInfo = NULL;
+ pNoteInfo->m_pNextNoteInfo = NULL;
+ pNoteInfo->m_pPrevNoteInfo = NULL;
+ ASSERT (MIDIEvent_GetParent (pNoteEvent));
+ return pNoteInfo;
+}
+
+void CMusicalScoreFrame::DeleteNoteInfo (MusicalScoreNoteInfo* pNoteInfo) {
+ delete (pNoteInfo);
+}
+
+BOOL CMusicalScoreFrame::AddNoteInfo (MusicalScoreTrackInfo* pTrackInfo, MusicalScoreNoteInfo* pNoteInfo) {
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ // lNoteOnTime順に指定トラックの音符情報配列に音符情報を登録する。
+ for (j = lNumNoteInfo - 1; j >= 0; j--) {
+ MusicalScoreNoteInfo* pNoteInfo2 = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ if (pNoteInfo2->m_lNoteOnTime <= pNoteInfo->m_lNoteOnTime) {
+ break;
+ }
+ }
+ pTrackInfo->m_theNoteInfoArray.InsertAt (j + 1, pNoteInfo);
+ return TRUE;
+}
+
+MusicalScoreNoteGroupInfo* CMusicalScoreFrame::CreateNoteGroupInfo
+ (MusicalScoreNoteInfo* pNoteInfo) {
+ MusicalScoreNoteGroupInfo* pNoteGroupInfo = new MusicalScoreNoteGroupInfo;
+ if (pNoteGroupInfo == NULL) {
+ return NULL;
+ }
+ pNoteGroupInfo->m_pFirstNoteInfo = pNoteInfo;
+ pNoteGroupInfo->m_pLastNoteInfo = pNoteInfo;
+ pNoteGroupInfo->m_lMinKey = MIDIEvent_GetKey (pNoteInfo->m_pNoteOnEvent);
+ pNoteGroupInfo->m_lMaxKey = MIDIEvent_GetKey (pNoteInfo->m_pNoteOnEvent);
+ pNoteGroupInfo->m_lMinDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ pNoteGroupInfo->m_lMaxDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ pNoteGroupInfo->m_lNumNoteInfo = 1;
+ return pNoteGroupInfo;
+}
+
+void CMusicalScoreFrame::DeleteNoteGroupInfo (MusicalScoreNoteGroupInfo* pNoteGroupInfo) {
+ delete (pNoteGroupInfo);
+}
+
+BOOL CMusicalScoreFrame::AddNoteGroupInfo (MusicalScoreTrackInfo* pTrackInfo, MusicalScoreNoteGroupInfo* pNoteGroupInfo) {
+ pTrackInfo->m_theNoteGroupInfoArray.Add (pNoteGroupInfo);
+ return TRUE;
+}
+
+MusicalScoreTripletGroupInfo* CMusicalScoreFrame::CreateTripletGroupInfo
+ (MusicalScoreNoteInfo* pNoteInfo) {
+ MusicalScoreTripletGroupInfo* pTripletGroupInfo = new MusicalScoreTripletGroupInfo;
+ if (pTripletGroupInfo == NULL) {
+ return NULL;
+ }
+ pTripletGroupInfo->m_pFirstNoteInfo = pNoteInfo;
+ pTripletGroupInfo->m_pLastNoteInfo = pNoteInfo;
+ pTripletGroupInfo->m_lMinKey = MIDIEvent_GetKey (pNoteInfo->m_pNoteOnEvent);
+ pTripletGroupInfo->m_lMaxKey = MIDIEvent_GetKey (pNoteInfo->m_pNoteOnEvent);
+ pTripletGroupInfo->m_lMinDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ pTripletGroupInfo->m_lMaxDur = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ pTripletGroupInfo->m_lNumNoteInfo = 1;
+ return pTripletGroupInfo;
+}
+
+void CMusicalScoreFrame::DeleteTripletGroupInfo (MusicalScoreTripletGroupInfo* pTripletGroupInfo) {
+ delete (pTripletGroupInfo);
+}
+
+BOOL CMusicalScoreFrame::AddTripletGroupInfo (MusicalScoreTrackInfo* pTrackInfo, MusicalScoreTripletGroupInfo* pTripletGroupInfo) {
+ pTrackInfo->m_theNoteGroupInfoArray.Add (pTripletGroupInfo);
+ return TRUE;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// オーバーライド
+//-----------------------------------------------------------------------------
+
+// ウィンドウ生成直前の構造体設定
+BOOL CMusicalScoreFrame::PreCreateWindow (CREATESTRUCT& cs) {
+ return (CWnd::PreCreateWindow(cs));
+}
+
+// ウィンドウタイトルの自動設定(CMDIChildWnd::OnUpdateFrameTitleのオーバーライド)
+void CMusicalScoreFrame::OnUpdateFrameTitle (BOOL bAddToTitle) {
+ // update our parent window first
+ GetMDIFrame()->OnUpdateFrameTitle (bAddToTitle);
+ if ((GetStyle() & FWS_ADDTOTITLE) == 0) {
+ return; // leave child window alone!
+ }
+ CDocument* pDocument = GetActiveDocument();
+ if (bAddToTitle && pDocument != NULL) {
+ CString strMusicalScore;
+ strMusicalScore.LoadString (IDS_MUSICALSCORE);
+ CString strTitle;
+ if (m_nWindow > 0) {
+ strTitle.Format (_T("%s:%d(%s)"), pDocument->GetTitle (), m_nWindow, strMusicalScore);
+ }
+ else {
+ strTitle.Format (_T("%s(%s)"), pDocument->GetTitle (), strMusicalScore);
+ }
+ this->SetWindowText (strTitle);
+ }
+}
+
+// 再配置用関数(CFrameWnd::RecalcLayoutのオーバーライド)
+void CMusicalScoreFrame::RecalcLayout (BOOL bNotify) {
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+
+ // 基本クラスの関数を処理
+ CFrameWnd::RecalcLayout (bNotify);
+
+ // アイコン化時には各コントロールのサイズを再計算しない。
+ if (rcClient.Width () == 0 || rcClient.Height () == 0) {
+ return;
+ }
+
+ // ツールバー1の高さ取得
+ CRect rcToolBar1;
+ m_wndToolBar1.GetWindowRect (&rcToolBar1);
+ m_lToolBar1Height = rcToolBar1.Height ();
+
+ // 高さ方向の位置計算
+ if (rcClient.Height () - m_lToolBar1Height <
+ MUSICALSCOREFRAME_SCALEHEIGHT + m_lHScrollBarHeight +
+ MUSICALSCOREFRAME_BORDERHEIGHT * 2) {
+ m_lScaleHeight = rcClient.Height () - m_lHScrollBarHeight -
+ MUSICALSCOREFRAME_BORDERHEIGHT * 2;
+ m_lKeyHeight = 0;
+ }
+ else if (rcClient.Height () - m_lToolBar1Height <
+ MUSICALSCOREFRAME_SCALEHEIGHT + m_lHScrollBarHeight +
+ MUSICALSCOREFRAME_BORDERHEIGHT * 2) {
+ m_lScaleHeight = MUSICALSCOREFRAME_SCALEHEIGHT;
+ m_lKeyHeight = 0;
+ }
+ else {
+ m_lScaleHeight = MUSICALSCOREFRAME_SCALEHEIGHT;
+ m_lKeyHeight = rcClient.Height () - m_lToolBar1Height -
+ m_lScaleHeight - m_lHScrollBarHeight -
+ MUSICALSCOREFRAME_BORDERHEIGHT * 2;
+ }
+ //m_lVelHeight = __min (m_lVelHeight, 128);
+
+ // 幅方向の位置計算
+ if (rcClient.Width () <
+ MUSICALSCOREFRAME_SCALEWIDTH + m_lVScrollBarWidth +
+ MUSICALSCOREFRAME_BORDERWIDTH * 4) {
+ m_lScaleWidth = rcClient.Width () -
+ m_lVScrollBarWidth - MUSICALSCOREFRAME_BORDERWIDTH * 4;
+ m_lTimeWidth = 0;
+ m_lTrackListWidth = 0;
+
+ }
+
+ else if (rcClient.Width () <
+ MUSICALSCOREFRAME_SCALEWIDTH + m_lVScrollBarWidth +
+ MUSICALSCOREFRAME_BORDERWIDTH * 4 + MUSICALSCOREFRAME_SPLITTERWIDTH + m_lTrackListWidth) {
+ //m_lScaleWidth = rcClient.Width () -
+ // m_lVScrollBarWidth - MUSICALSCOREFRAME_BORDERWIDTH * 2;
+ m_lScaleWidth = MUSICALSCOREFRAME_SCALEWIDTH;
+ m_lTimeWidth = 0;
+ m_lTrackListWidth = rcClient.Width () - m_lScaleWidth -
+ m_lVScrollBarWidth - MUSICALSCOREFRAME_BORDERWIDTH * 4 -
+ MUSICALSCOREFRAME_SPLITTERWIDTH;
+
+ }
+ else {
+ m_lScaleWidth = MUSICALSCOREFRAME_SCALEWIDTH;
+ m_lTimeWidth = rcClient.Width () - m_lScaleWidth -
+ m_lVScrollBarWidth - MUSICALSCOREFRAME_BORDERWIDTH * 4 -
+ MUSICALSCOREFRAME_SPLITTERWIDTH - m_lTrackListWidth;
+ m_lTrackListWidth = m_lTrackListWidth;
+ }
+
+ // ビューの整列
+ if (m_pScaleView) {
+ m_pScaleView->MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT,
+ m_lScaleWidth, m_lScaleHeight);
+ }
+
+ if (m_pTimeScaleView) {
+ m_pTimeScaleView->MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT,
+ m_lTimeWidth, m_lScaleHeight);
+ }
+
+ if (m_pTrackScaleView) {
+ m_pTrackScaleView->MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lScaleWidth, m_lKeyHeight);
+ }
+
+ if (m_pTrackTimeView) {
+ m_pTrackTimeView->MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lTimeWidth, m_lKeyHeight);
+ }
+
+ // スクロールバーの整列
+ m_wndTimeScroll.MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 1 + m_lScaleHeight + m_lKeyHeight,
+ m_lScaleWidth + m_lTimeWidth - m_lVScrollBarWidth * 2,
+ m_lHScrollBarHeight);
+
+ m_wndTrackScroll.MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT,
+ m_lVScrollBarWidth,
+ m_lScaleHeight + m_lKeyHeight - m_lVScrollBarWidth * 2);
+
+ m_wndSizeScroll.MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 1 + m_lScaleHeight + m_lKeyHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ // ズームボタンの整列
+ m_wndTimeZoomDown.MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lTimeWidth - m_lVScrollBarWidth * 2,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 1 + m_lScaleHeight + m_lKeyHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndTimeZoomUp.MoveWindow (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lTimeWidth - m_lVScrollBarWidth,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 1 + m_lScaleHeight + m_lKeyHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndTrackZoomDown.MoveWindow
+ (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT + m_lScaleHeight + m_lKeyHeight -
+ m_lVScrollBarWidth * 2,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndTrackZoomUp.MoveWindow
+ (MUSICALSCOREFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT + m_lScaleHeight + m_lKeyHeight -
+ m_lVScrollBarWidth,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+
+ // リストの整列
+ m_pTrackListBox->MoveWindow
+ (MUSICALSCOREFRAME_BORDERWIDTH * 3 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth + MUSICALSCOREFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT,
+ m_lTrackListWidth,
+ m_lScaleHeight + m_lKeyHeight + m_lHScrollBarHeight);
+
+
+ // スクロールバーのサイズが変化したので、バーのデザインを再調整する。
+ RecalcTrackScrollInfo ();
+ RecalcTimeScrollInfo ();
+}
+
+// クライアント領域の生成(CFrameWnd::OnCreateClientのオーバーライド)
+BOOL CMusicalScoreFrame::OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext) {
+
+ // サイズ調整用のダミービュー生成(Visible = FALSE)
+ CWnd* pWnd = NULL;
+ m_pDummyView = (CView*)CFrameWnd::CreateView (pContext, MUSICALSCOREFRAME_DUMMYVIEW);
+ if (m_pDummyView == NULL) {
+ return FALSE;
+ }
+ m_pDummyView->ShowWindow (SW_HIDE);
+
+ // 印刷用ビューの生成(Visible = FALSE)
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CMusicalScorePrintView);
+ m_pPrintView = (CView*)CFrameWnd::CreateView (pContext, MUSICALSCOREFRAME_PRINTVIEW);
+ if (m_pPrintView == NULL) {
+ return FALSE;
+ }
+ m_pPrintView->ShowWindow (SW_HIDE);
+
+ // ビュー1の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CMusicalScoreScaleView);
+ m_pScaleView = (CView*)CFrameWnd::CreateView (pContext, MUSICALSCOREFRAME_SCALEVIEW);
+ if (m_pScaleView == NULL) {
+ return FALSE;
+ }
+ m_pScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // ビュー2の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CMusicalScoreTimeScaleView);
+ m_pTimeScaleView = (CView*)CFrameWnd::CreateView (pContext, MUSICALSCOREFRAME_TIMESCALEVIEW);
+ if (m_pTimeScaleView == NULL) {
+ return FALSE;
+ }
+ m_pTimeScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+ // ビュー3の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CMusicalScoreTrackScaleView);
+ m_pTrackScaleView = (CView*)CFrameWnd::CreateView (pContext, MUSICALSCOREFRAME_TRACKSCALEVIEW);
+ if (m_pTrackScaleView == NULL) {
+ return FALSE;
+ }
+ m_pTrackScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+ // ビュー4の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CMusicalScoreTrackTimeView);
+ m_pTrackTimeView = (CView*)CFrameWnd::CreateView (pContext, MUSICALSCOREFRAME_TRACKTIMEVIEW);
+ if (m_pTrackTimeView == NULL) {
+ return FALSE;
+ }
+ m_pTrackTimeView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // スクロールバーの生成
+ m_wndTimeScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_HORZ, CRect(0,0,0,0), this, MUSICALSCOREFRAME_TIMESCROLL);
+ m_wndTrackScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_VERT, CRect(0,0,0,0), this, MUSICALSCOREFRAME_TRACKSCROLL);
+ m_wndSizeScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_SIZEBOX, CRect(0,0,0,0), this, MUSICALSCOREFRAME_SIZEBOX);
+
+ // ズームボタン類の生成
+ m_wndTimeZoomDown.Create
+ (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, MUSICALSCOREFRAME_TIMEZOOMDOWN);
+ m_wndTimeZoomUp.Create
+ (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, MUSICALSCOREFRAME_TIMEZOOMUP);
+ m_wndTrackZoomDown.Create
+ (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, MUSICALSCOREFRAME_TRACKZOOMDOWN);
+ m_wndTrackZoomUp.Create
+ (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, MUSICALSCOREFRAME_TRACKZOOMUP);
+
+ // トラックリストの作成
+ m_pTrackListBox =
+ new CTrackListBox (pContext->m_pCurrentDoc, IDR_POPUPMENU33);
+ m_pTrackListBox->Create
+ (WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|
+ LBS_NOTIFY|LBS_DISABLENOSCROLL|LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOINTEGRALHEIGHT,
+ CRect(0,0,0,0), this, MUSICALSCOREFRAME_TRACKLIST);
+
+
+ // コントロールの位置合わせはWM_SIZEなどによるRecalcLaoyoutに任せる。
+
+
+
+
+ // 描画情報配列の更新
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ RecalcTrackScrollInfo ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ return TRUE;
+
+}
+
+// 印刷用のコマンドをトラップ(CFrameWnd::OnCmdMsgのオーバーライド)
+BOOL CMusicalScoreFrame::OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 印刷用のコマンドの場合、強制的にCMusicalScorePrintViewに渡す。
+ if ((nID == ID_FILE_PRINT || nID == ID_FILE_PRINT_DIRECT || nID == ID_FILE_PRINT_PREVIEW) &&
+ pSekaijuApp->m_bRecording == FALSE) {
+ if (m_pPrintView) {
+ return ((CMusicalScorePrintView*)m_pPrintView)->OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+ }
+ return FALSE;
+ }
+ // その他のコマンドはデフォルトの処理とする。
+ return CFrameWnd::OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+}
+
+//-----------------------------------------------------------------------------
+// メッセージマップ
+//-----------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CMusicalScoreFrame::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+
+ CRect rcTemp;
+
+ // ツールバー1の作成
+ if (!m_wndToolBar1.Create (this) ||
+ !m_wndToolBar1.LoadToolBar (IDR_MUSICALSCORE1)) {
+ TRACE0 ("Failed to create toolbar\n");
+ return -1;
+ }
+ m_wndToolBar1.SetBarStyle (m_wndToolBar1.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ //m_wndToolBar1.EnableDocking (CBRS_ALIGN_ANY);
+ //EnableDocking (CBRS_ALIGN_ANY);
+ //DockControlBar (&m_wndToolBar1);
+
+ LoadAccelTable (MAKEINTRESOURCE (IDR_MUSICALSCORE));
+
+ // トラックコンボの作成
+ m_wndToolBar1.SetButtonInfo (5, IDC_TRACKCOMBO, TBBS_SEPARATOR, 80);
+ m_wndToolBar1.GetItemRect (5, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndTrackCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_TRACKCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndTrackCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // チャンネルコンボの作成
+ m_wndToolBar1.SetButtonInfo (7, IDC_CHANNELCOMBO, TBBS_SEPARATOR, 40);
+ m_wndToolBar1.GetItemRect (7, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndChannelCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_CHANNELCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndChannelCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // スナップコンボの作成
+ m_wndToolBar1.SetButtonInfo (9, IDC_SNAPCOMBO, TBBS_SEPARATOR, 100);
+ m_wndToolBar1.GetItemRect (9, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndSnapCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_SNAPCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndSnapCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // ベロシティコンボの作成
+ m_wndToolBar1.SetButtonInfo (11, IDC_VELOCITYCOMBO, TBBS_SEPARATOR, 50);
+ m_wndToolBar1.GetItemRect (11, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndVelocityCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWN,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_VELOCITYCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndVelocityCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // 長さコンボの作成
+ m_wndToolBar1.SetButtonInfo (13, IDC_DURATIONCOMBO, TBBS_SEPARATOR, 50);
+ m_wndToolBar1.GetItemRect (13, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndDurationCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWN,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_DURATIONCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndDurationCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // 表示精度コンボの作成
+ m_wndToolBar1.SetButtonInfo (24, IDC_RESOLUTIONCOMBO, TBBS_SEPARATOR, 100);
+ m_wndToolBar1.GetItemRect (24, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndResolutionCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_RESOLUTIONCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndResolutionCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+
+ // 親クラスの関数呼び出し
+ int nRet = CChildFrame::OnCreate (lpCreateStruct);
+
+ // スクロールポジションの位置あわせ
+ // SetTrackScrollPos (64 * m_lTrackZoom - m_lKeyHeight / 2);
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+
+ // トラックコンボボックスの充満
+ UpdateTrackCombo ();
+
+ // チャンネルコンボの充満
+ int i;
+ CString strText;
+ for (i = 0; i < 16; i++) {
+ strText.Format (_T("%d"), i + 1);
+ m_wndChannelCombo.AddString (strText);
+ }
+ m_wndChannelCombo.SetCurSel (0);
+
+ // カレントチャンネルの自動選択
+ if (pSekaijuDoc->m_pTempTrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+
+ // スナップコンボの充満
+ UpdateSnapCombo ();
+ m_wndSnapCombo.SetCurSel (3);
+
+ // ベロシティコンボの充満
+ UpdateVelocityCombo ();
+ m_wndVelocityCombo.SetCurSel (6);
+
+ // 長さコンボの充満
+ UpdateDurationCombo ();
+ m_wndDurationCombo.SetCurSel (3);
+
+ // 表示精度コンボの充満
+ UpdateResolutionCombo ();
+ m_wndResolutionCombo.SetCurSel (4);
+
+ // トラックリストの充満
+ UpdateTrackList ();
+ m_pTrackListBox->SetCurSel (0);
+ m_pTrackListBox->SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+ long lCount = m_pTrackListBox->GetCount ();
+ i = 0;
+ if (pSekaijuDoc->m_pTempTrack) {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (0 <= i && i < lCount) {
+ m_pTrackListBox->SetCheck (i, pMIDITrack == pSekaijuDoc->m_pTempTrack ? TRUE : FALSE);
+ m_bTrackVisible[i] = (pMIDITrack == pSekaijuDoc->m_pTempTrack ? TRUE : FALSE);
+ }
+ i++;
+ }
+ }
+ else {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (0 <= i && i < lCount) {
+ m_pTrackListBox->SetCheck (i, TRUE);
+ m_bTrackVisible[i] = (TRUE);
+ }
+ i++;
+ }
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+
+ // カレントトラックとカレントチャンネルを更新
+ long lTrackIndex = 0;
+ if (pSekaijuDoc->m_pTempTrack) {
+ lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ }
+ else if (MIDIData_GetFormat (pMIDIData) == 1 && lCount >= 2) {
+ lTrackIndex = 1;
+ }
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ }
+
+ // 自動ページ更新の設定
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) {
+ m_bAutoPageUpdate = TRUE;
+ }
+
+ SetActiveView (m_pTrackTimeView, FALSE);
+ m_pTrackTimeView->SetFocus ();
+
+ UpdateMeasureInfoArray ();
+ UpdateTrackInfoArray ();
+
+ int x = this->MeasuretoX2 (0) + 1;
+ this->SetTimeScrollPos (x);
+
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return nRet;
+}
+
+// ウィンドウ破棄時
+void CMusicalScoreFrame::OnDestroy () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ // トラック情報配列削除
+ VERIFY (DeleteTrackInfoArray ());
+ // 小節情報配列削除
+ VERIFY (DeleteMeasureInfoArray ());
+
+ m_pTrackListBox->DestroyWindow ();
+ delete m_pTrackListBox;
+ CChildFrame::OnDestroy ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// ウィンドウサイズ変更時
+void CMusicalScoreFrame::OnSize (UINT nType, int cx, int cy) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ // 基本クラスの関数呼び出し
+ CChildFrame::OnSize (nType, cx, cy);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// タイマー呼び出し時
+void CMusicalScoreFrame::OnTimer (UINT nIDEvent) {
+ //if (nIDEvent == 0x11) {
+ // m_pTrackTimeView->SendMessage (WM_TIMER, 11, NULL);
+ // m_pVelTimeView->SendMessage (WM_TIMER, 11, NULL);
+ //}
+}
+
+// 背景消去(CFrameWnd::OnEraseBkgndのオーバーライド)
+BOOL CMusicalScoreFrame::OnEraseBkgnd (CDC* pDC) {
+ return 0;
+}
+
+// ウィンドウがアクティブになったとき
+void CMusicalScoreFrame::OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd) {
+ CChildFrame::OnMDIActivate (bActivate, pActivateWnd, pDeactivateWnd);
+}
+
+// 描画するとき
+void CMusicalScoreFrame::OnPaint () {
+ CPaintDC dc (this);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ // 左側領域のくぼみ描画
+ CRect rcClient1 (rcClient);
+ rcClient1.top = m_lToolBar1Height;
+ rcClient1.bottom = m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 2 +
+ m_lScaleHeight + m_lKeyHeight + m_lHScrollBarHeight;
+ rcClient1.right = MUSICALSCOREFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth;
+ dc.Draw3dRect (&rcClient1, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient1.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient1, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 右上側領域のくぼみ描画
+ CRect rcClient3 (rcClient);
+ rcClient3.top = m_lToolBar1Height;
+ rcClient3.bottom = m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 2 +
+ m_lScaleHeight + m_lKeyHeight + m_lHScrollBarHeight;
+ rcClient3.left = MUSICALSCOREFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth + MUSICALSCOREFRAME_SPLITTERWIDTH;
+ dc.Draw3dRect (&rcClient3, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient3.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient3, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 横境界部分の描画
+ CBrush brush;
+ brush.CreateSolidBrush (::GetSysColor (COLOR_3DFACE));
+ CRect rcClient6 (rcClient);
+ rcClient6.left = rcClient1.right + 1;
+ rcClient6.right = rcClient3.left - 1;
+ dc.FillRect (&rcClient6, &brush);
+}
+
+// キーが押された時
+void CMusicalScoreFrame::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CWnd* pOldFocus = GetFocus ();
+ switch (nChar) {
+ // D(描画)P(ペン)
+ case 'D':
+ case 'P':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_PEN, 0);
+ }
+ break;
+ // L(線)
+ case 'L':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_LINE, 0);
+ }
+ break;
+ // E(消しゴム)
+ case 'E':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_ERASER, 0);
+ }
+ break;
+ // S(選択)
+ case 'S':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_SELECT, 0);
+ }
+ break;
+ // B(スクラブ)
+ case 'B':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_SPEAKER, 0);
+ }
+ break;
+ // 1(全音符)
+ case '1' :
+ case VK_NUMPAD1:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_WHOLENOTE, 0);
+ }
+ break;
+ // 2(2分音符)
+ case '2' :
+ case VK_NUMPAD2:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_HALFNOTE, 0);
+ }
+ break;
+ // 4(4分音符)
+ case '4' :
+ case VK_NUMPAD4:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_QUARTERNOTE, 0);
+ }
+ break;
+ // 8(8分音符)
+ case '8' :
+ case VK_NUMPAD8:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_QUAVERNOTE, 0);
+ }
+ break;
+ // 16(16分音符)
+ case '6' :
+ case VK_NUMPAD6:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_SEMIQUAVERNOTE, 0);
+ }
+ break;
+ // 32(32分音符)
+ case '9' :
+ case VK_NUMPAD9:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_DEMISEMIQUAVERNOTE, 0);
+ }
+ break;
+ // .(付点)
+ case '.' :
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_DOTTED, 0);
+ }
+ break;
+ // t(3連)
+ case 't' :
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_MUSICALSCORE_TRIPLET, 0);
+ }
+ break;
+ // ↑
+ case VK_UP:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndTrackScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // ↓
+ case VK_DOWN:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndTrackScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // PageUp
+ case VK_PRIOR:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndTrackScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // PageDown
+ case VK_NEXT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndTrackScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // ←
+ case VK_LEFT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // →
+ case VK_RIGHT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // Home
+ case VK_HOME:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // End
+ case VK_END:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // '-'(ズームダウン)
+ case 189:
+ case VK_SUBTRACT:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_theMusicalScoreOption.m_bEnableTrackZoomKey) {
+ this->PostMessage (WM_COMMAND, MUSICALSCOREFRAME_TRACKZOOMDOWN, 0);
+ }
+ if (pSekaijuApp->m_theMusicalScoreOption.m_bEnableTimeZoomKey) {
+ this->PostMessage (WM_COMMAND, MUSICALSCOREFRAME_TIMEZOOMDOWN, 0);
+ }
+ }
+ break;
+ // '+'(ズームアップ)
+ case 187:
+ case VK_ADD:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_theMusicalScoreOption.m_bEnableTrackZoomKey) {
+ this->PostMessage (WM_COMMAND, MUSICALSCOREFRAME_TRACKZOOMUP, 0);
+ }
+ if (pSekaijuApp->m_theMusicalScoreOption.m_bEnableTimeZoomKey) {
+ this->PostMessage (WM_COMMAND, MUSICALSCOREFRAME_TIMEZOOMUP, 0);
+ }
+ }
+ break;
+ }
+ return;
+}
+
+
+
+// マウス左ボタン押された時
+void CMusicalScoreFrame::OnLButtonDown (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 上半分(ピアノロール)と下半分(コントローラー)の境界線上をドラッグすると、境界線が上下に移動
+ if (m_bSplitterMovingH || m_bSplitterMovingV) {
+ SetCapture ();
+ m_ptMouseDown = m_ptMouseMoveOld = point;
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ if (m_bSplitterMovingH && m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeAll);
+ }
+ else if (m_bSplitterMovingH) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeNS);
+ }
+ else if (m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+ }
+}
+
+// マウス右ボタン押された時
+void CMusicalScoreFrame::OnRButtonDown (UINT nFlags, CPoint point) {
+}
+
+// マウス左ボタン離されたとき
+void CMusicalScoreFrame::OnLButtonUp (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (GetCapture () == this) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ ReleaseDC (pDC);
+ ReleaseCapture ();
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ CPoint ptDelta = point - m_ptMouseDown;
+ if (m_bSplitterMovingV) {
+ m_lTrackListWidth = MUSICALSCOREFRAME_RANGE (0,
+ (m_lTrackListWidth - ptDelta.x), 1600);
+ }
+ m_bSplitterMovingH = FALSE;
+ m_bSplitterMovingV = FALSE;
+ RecalcLayout ();
+ Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+}
+
+// マウス右ボタン離されたとき
+void CMusicalScoreFrame::OnRButtonUp (UINT nFlags, CPoint point) {
+
+
+}
+
+// マウスが動かされたとき
+void CMusicalScoreFrame::OnMouseMove (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // キャプター中
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ m_ptMouseMoveOld = point;
+ }
+ // 非キャプター中
+ else {
+ // カーソルが水平スプリッター上にあるか
+ m_bSplitterMovingH =
+ m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 2 + m_lScaleHeight + m_lKeyHeight <= point.y &&
+ point.y < m_lToolBar1Height + MUSICALSCOREFRAME_BORDERHEIGHT * 2 + m_lScaleHeight + m_lKeyHeight +
+ MUSICALSCOREFRAME_SPLITTERHEIGHT;
+ // カーソルが垂直スプリッター上にあるか
+ m_bSplitterMovingV =
+ MUSICALSCOREFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth + m_lVScrollBarWidth <= point.x &&
+ point.x < MUSICALSCOREFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth + m_lVScrollBarWidth +
+ MUSICALSCOREFRAME_SPLITTERWIDTH;
+ // カーソルが水平スプリッターと垂直スプリッターの交差部にある場合
+ if (m_bSplitterMovingH && m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeAll);
+ }
+ // カーソルが水平スプリッター上にある場合
+ else if (m_bSplitterMovingH) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeNS);
+ }
+ // カーソルが垂直スプリッター上にある場合
+ else if (m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+ // カーソルがスプリッターにない場合
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ }
+ }
+}
+
+// 時間方向ズームダウン(20091220:左端位置保持機能追加、自動ページ更新自動オフ追加)
+void CMusicalScoreFrame::OnTimeZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTimeZoom = m_lTimeZoom;
+ long lOldTimePos = m_wndTimeScroll.GetScrollPos ();
+ long lNewTimeZoom = CLIP (1, m_lTimeZoom - 1, 16);
+ long lNewTimePos = lOldTimePos * lNewTimeZoom / lOldTimeZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lTimeZoom = lNewTimeZoom;
+ RecalcTimeScrollInfo ();
+ m_wndTimeScroll.SetScrollPos (lNewTimePos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ m_pTimeScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ //m_bAutoPageUpdate = TRUE;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 時間方向ズームアップ(20091220:左端位置保持機能追加、自動ページ更新自動オフ追加)
+void CMusicalScoreFrame::OnTimeZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTimeZoom = m_lTimeZoom;
+ long lOldTimePos = m_wndTimeScroll.GetScrollPos ();
+ long lNewTimeZoom = CLIP (1, m_lTimeZoom + 1, 16);
+ long lNewTimePos = lOldTimePos * lNewTimeZoom / lOldTimeZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lTimeZoom = lNewTimeZoom;
+ RecalcTimeScrollInfo ();
+ m_wndTimeScroll.SetScrollPos (lNewTimePos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ m_pTimeScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ //m_bAutoPageUpdate = TRUE;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// トラック方向ズームダウン(20091220:上端位置保持機能追加)
+void CMusicalScoreFrame::OnTrackZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTrackZoom = m_lTrackZoom;
+ long lOldTrackPos = m_wndTrackScroll.GetScrollPos ();
+ long lNewTrackZoom = CLIP (1, m_lTrackZoom - 1, 8);
+ long lNewTrackPos = lOldTrackPos * lNewTrackZoom / lOldTrackZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lTrackZoom = lNewTrackZoom;
+ RecalcTrackScrollInfo ();
+ m_wndTrackScroll.SetScrollPos (lNewTrackPos);
+ m_lTrackScrollPos = m_wndTrackScroll.GetScrollPos ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// トラック方向ズームアップ(20091220:上端位置保持機能追加)
+void CMusicalScoreFrame::OnTrackZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTrackZoom = m_lTrackZoom;
+ long lOldTrackPos = m_wndTrackScroll.GetScrollPos ();
+ long lNewTrackZoom = CLIP (1, m_lTrackZoom + 1, 8);
+ long lNewTrackPos = lOldTrackPos * lNewTrackZoom / lOldTrackZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lTrackZoom = lNewTrackZoom;
+ RecalcTrackScrollInfo ();
+ m_wndTrackScroll.SetScrollPos (lNewTrackPos);
+ m_lTrackScrollPos = m_wndTrackScroll.GetScrollPos ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+
+// 水平スクロール
+void CMusicalScoreFrame::OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndTimeScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lTimeScrollPos;
+ switch (nSBCode) {
+ case SB_LINELEFT:
+ lNewPos = m_lTimeScrollPos - m_lTimeZoom;
+ break;
+ case SB_LINERIGHT:
+ lNewPos = m_lTimeScrollPos + m_lTimeZoom;
+ break;
+ case SB_PAGELEFT:
+ lNewPos = m_lTimeScrollPos - m_lTimeZoom * 4;
+ break;
+ case SB_PAGERIGHT:
+ lNewPos = m_lTimeScrollPos + m_lTimeZoom * 4;
+ break;
+ case SB_LEFT: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_RIGHT: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetTimeScrollPos (MUSICALSCOREFRAME_RANGE (0, lNewPos, 0x7FFFFFFF));
+ m_bAutoPageUpdate = FALSE;
+ m_pTrackTimeView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 垂直スクロール
+void CMusicalScoreFrame::OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndTrackScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ long ry = 4;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lTrackScrollPos;
+ switch (nSBCode) {
+ case SB_LINEUP:
+ lNewPos = m_lTrackScrollPos - ry * 2;
+ break;
+ case SB_LINEDOWN:
+ lNewPos = m_lTrackScrollPos + ry * 2;
+ break;
+ case SB_PAGEUP:
+ lNewPos = m_lTrackScrollPos - ry * 10;
+ break;
+ case SB_PAGEDOWN:
+ lNewPos = m_lTrackScrollPos + ry * 10;
+ break;
+ case SB_TOP: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_BOTTOM: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetTrackScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_pTrackTimeView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 『ツール(&T)』-『ペン(&P)』
+void CMusicalScoreFrame::OnMusicalScorePen () {
+ m_lCurTool = ID_MUSICALSCORE_PEN;
+}
+
+// 『ツール(&T)』-『ペン(&P)』
+void CMusicalScoreFrame::OnUpdateMusicalScorePenUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_MUSICALSCORE_PEN);
+}
+
+// 『ツール(&T)』-『線(&L)』
+void CMusicalScoreFrame::OnMusicalScoreLine () {
+ m_lCurTool = ID_MUSICALSCORE_LINE;
+}
+
+// 『ツール(&T)』-『線(&L)』
+void CMusicalScoreFrame::OnUpdateMusicalScoreLineUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_MUSICALSCORE_LINE);
+}
+
+// 『ツール(&T)』-『消しゴム(&E)』
+void CMusicalScoreFrame::OnMusicalScoreEraser () {
+ m_lCurTool = ID_MUSICALSCORE_ERASER;
+}
+
+// 『ツール(&T)』-『消しゴム(&E)』
+void CMusicalScoreFrame::OnUpdateMusicalScoreEraserUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_MUSICALSCORE_ERASER);
+}
+
+// 『ツール(&T)』-『選択(&S)』
+void CMusicalScoreFrame::OnMusicalScoreSelect () {
+ m_lCurTool = ID_MUSICALSCORE_SELECT;
+}
+
+// 『ツール(&T)』-『選択(&S)』
+void CMusicalScoreFrame::OnUpdateMusicalScoreSelectUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_MUSICALSCORE_SELECT);
+}
+
+// 『ツール(&T)』-『スピーカ(&P)』
+void CMusicalScoreFrame::OnMusicalScoreSpeaker () {
+ m_lCurTool = ID_MUSICALSCORE_SPEAKER;
+}
+
+// 『ツール(&T)』-『スピーカ(&P)』
+void CMusicalScoreFrame::OnUpdateMusicalScoreSpeakerUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_MUSICALSCORE_SPEAKER);
+}
+
+// 『ツール(&T)』-『全音符』
+void CMusicalScoreFrame::OnMusicalScoreWholeNote () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ strText.Format (_T("%d"), lTimeResolution * 4);
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『全音符』
+void CMusicalScoreFrame::OnUpdateMusicalScoreWholeNoteUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 全音符
+ pCmdUI->SetCheck (lCurDuration == lTimeResolution * 4);
+}
+
+// 『ツール(&T)』-『2分音符』
+void CMusicalScoreFrame::OnMusicalScoreHalfNote () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ // 2分音符
+ strText.Format (_T("%d"), lTimeResolution * 2);
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『2分音符』
+void CMusicalScoreFrame::OnUpdateMusicalScoreHalfNoteUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 2分音符・付点2分音符・3連2分音符
+ pCmdUI->SetCheck (lCurDuration == lTimeResolution * 2 ||
+ lCurDuration == lTimeResolution * 3 ||
+ lCurDuration == lTimeResolution * 4 / 3);
+}
+
+// 『ツール(&T)』-『4分音符』
+void CMusicalScoreFrame::OnMusicalScoreQuarterNote () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ strText.Format (_T("%d"), lTimeResolution * 1);
+ // 4分音符
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『4分音符』
+void CMusicalScoreFrame::OnUpdateMusicalScoreQuarterNoteUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 4分音符・付点4分音符・3連4分音符
+ pCmdUI->SetCheck (lCurDuration == lTimeResolution * 1 ||
+ lCurDuration == lTimeResolution * 3 / 2 ||
+ lCurDuration == lTimeResolution * 2 / 3);
+}
+
+// 『ツール(&T)』-『8分音符』
+void CMusicalScoreFrame::OnMusicalScoreQuaverNote () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ // 8分音符
+ strText.Format (_T("%d"), lTimeResolution / 2);
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『8分音符』
+void CMusicalScoreFrame::OnUpdateMusicalScoreQuaverNoteUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 8分音符・付点8分音符・3連8分音符
+ pCmdUI->SetCheck (lCurDuration == lTimeResolution / 2 ||
+ lCurDuration == lTimeResolution * 3 / 4 ||
+ lCurDuration == lTimeResolution * 1 / 3);
+}
+
+// 『ツール(&T)』-『16分音符』
+void CMusicalScoreFrame::OnMusicalScoreSemiQuaverNote () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ // 16分音符
+ strText.Format (_T("%d"), lTimeResolution / 4);
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『16分音符』
+void CMusicalScoreFrame::OnUpdateMusicalScoreSemiQuaverNoteUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration =_ttol (strText);
+ // 16分音符・付点16分音符・3連16分音符
+ pCmdUI->SetCheck (lCurDuration == lTimeResolution / 4 ||
+ lCurDuration == lTimeResolution * 3 / 8 ||
+ lCurDuration == lTimeResolution * 1 / 6);
+}
+
+// 『ツール(&T)』-『32分音符』
+void CMusicalScoreFrame::OnMusicalScoreDemiSemiQuaverNote () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ // 32分音符
+ strText.Format (_T("%d"), lTimeResolution / 8);
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『32分音符』
+void CMusicalScoreFrame::OnUpdateMusicalScoreDemiSemiQuaverNoteUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 32分音符・付点32分音符
+ pCmdUI->SetCheck (lCurDuration == lTimeResolution / 8 ||
+ lCurDuration == lTimeResolution * 1 / 12);
+}
+
+// 『ツール(&T)』-『付点』
+void CMusicalScoreFrame::OnMusicalScoreDotted () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 2分音符→付点2分音符
+ if (lCurDuration == lTimeResolution * 2) {
+ lCurDuration = lTimeResolution * 3;
+ }
+ // 4分音符→付点4分音符
+ else if (lCurDuration == lTimeResolution * 1) {
+ lCurDuration = lTimeResolution * 3 / 2;
+ }
+ // 8分音符→付点8分音符
+ else if (lCurDuration == lTimeResolution / 2) {
+ lCurDuration = lTimeResolution * 3 / 4;
+ }
+ // 16分音符→付点16分音符
+ else if (lCurDuration == lTimeResolution / 4) {
+ lCurDuration = lTimeResolution * 3 / 8;
+ }
+ // 付点2分音符→2分音符
+ else if (lCurDuration == lTimeResolution * 3) {
+ lCurDuration = lTimeResolution * 2;
+ }
+ // 付点4分音符→4分音符
+ else if (lCurDuration == lTimeResolution * 3 / 2) {
+ lCurDuration = lTimeResolution * 1;
+ }
+ // 付点8分音符→8分音符
+ else if (lCurDuration == lTimeResolution * 3 / 4) {
+ lCurDuration = lTimeResolution / 2;
+ }
+ // 付点16分音符→16分音符
+ else if (lCurDuration == lTimeResolution * 3 / 8) {
+ lCurDuration = lTimeResolution / 4;
+ }
+ strText.Format (_T("%d"), lCurDuration);
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『付点』
+void CMusicalScoreFrame::OnUpdateMusicalScoreDottedUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 2分音符・4分音符・8分音符・16分音符
+ // 付点2分音符・付点4分音符・付点8分音符・付点16分音符
+ pCmdUI->Enable (lCurDuration == lTimeResolution * 2 ||
+ lCurDuration == lTimeResolution * 3 ||
+ lCurDuration == lTimeResolution * 1 ||
+ lCurDuration == lTimeResolution * 3 / 2 ||
+ lCurDuration == lTimeResolution / 2 ||
+ lCurDuration == lTimeResolution * 3 / 4 ||
+ lCurDuration == lTimeResolution / 4 ||
+ lCurDuration == lTimeResolution * 3 / 8);
+ // 付点2分音符・付点4分音符・付点8分音符・付点16分音符
+ pCmdUI->SetCheck (lCurDuration == lTimeResolution * 3 ||
+ lCurDuration == lTimeResolution * 3 / 2 ||
+ lCurDuration == lTimeResolution * 3 / 4 ||
+ lCurDuration == lTimeResolution * 3 / 8);
+}
+
+// 『ツール(&T)』-『3連』
+void CMusicalScoreFrame::OnMusicalScoreTriplet () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 2分音符→3連2分音符
+ if (lCurDuration == lTimeResolution * 2) {
+ lCurDuration = lTimeResolution * 4 / 3;
+ }
+ // 4分音符→3連4分音符
+ else if (lCurDuration == lTimeResolution * 1) {
+ lCurDuration = lTimeResolution * 2 / 3;
+ }
+ // 8分音符→3連8分音符
+ else if (lCurDuration == lTimeResolution / 2) {
+ lCurDuration = lTimeResolution / 3;
+ }
+ // 16分音符→3連16分音符
+ else if (lCurDuration == lTimeResolution / 4) {
+ lCurDuration = lTimeResolution / 6;
+ }
+ // 32分音符→3連32分音符
+ else if (lCurDuration == lTimeResolution / 8) {
+ lCurDuration = lTimeResolution / 12;
+ }
+ // 3連2分音符→2分音符
+ else if (lCurDuration == lTimeResolution * 4 / 3) {
+ lCurDuration = lTimeResolution * 2;
+ }
+ // 3連4分音符→4分音符
+ else if (lCurDuration == lTimeResolution * 2 / 3) {
+ lCurDuration = lTimeResolution * 1;
+ }
+ // 3連8分音符→8分音符
+ else if (lCurDuration == lTimeResolution / 3) {
+ lCurDuration = lTimeResolution / 2;
+ }
+ // 3連16分音符→16分音符
+ else if (lCurDuration == lTimeResolution / 6) {
+ lCurDuration = lTimeResolution / 4;
+ }
+ // 3連32分音符→32分音符
+ else if (lCurDuration == lTimeResolution / 12) {
+ lCurDuration = lTimeResolution / 8;
+ }
+ strText.Format (_T("%d"), lCurDuration);
+ m_wndDurationCombo.SetWindowText (strText);
+}
+
+// 『ツール(&T)』-『3連』
+void CMusicalScoreFrame::OnUpdateMusicalScoreTripletUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ long lCurDuration = _ttol (strText);
+ // 2分音符・4分音符・8分音符・16分音符・32分音符
+ // 3連2分音符・3連4分音符・3連8分音符・3連16分音符・3連32分音符
+ pCmdUI->Enable (lCurDuration == lTimeResolution * 2 ||
+ lCurDuration == lTimeResolution * 4 / 3 ||
+ lCurDuration == lTimeResolution * 1 ||
+ lCurDuration == lTimeResolution * 2 / 3 ||
+ lCurDuration == lTimeResolution / 2 ||
+ lCurDuration == lTimeResolution / 3 ||
+ lCurDuration == lTimeResolution / 4 ||
+ lCurDuration == lTimeResolution / 6 ||
+ lCurDuration == lTimeResolution / 8 ||
+ lCurDuration == lTimeResolution / 12);
+ // 3連2分音符・3連4分音符・3連8分音符・3連16分音符・3連32分音符
+ pCmdUI->SetCheck
+ (lCurDuration == lTimeResolution * 4 / 3 ||
+ lCurDuration == lTimeResolution * 2 / 3 ||
+ lCurDuration == lTimeResolution / 3 ||
+ lCurDuration == lTimeResolution / 6 ||
+ lCurDuration == lTimeResolution / 12);
+}
+
+// 『ツール(&T)』-『現在のトラックのみ表示(&C)』
+void CMusicalScoreFrame::OnMusicalScoreOnlyCurTrack () {
+ long lTrackCount = m_pTrackListBox->GetCount ();
+ long lTrackCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bOnlyCurTrack) {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ }
+ else {
+ m_bOnlyCurTrack = TRUE;
+ m_bShowAllTrack = FALSE;
+ }
+ for (long i = 0; i < lTrackCount; i++) {
+ m_pTrackListBox->SetCheck (i, IsTrackVisible (i) ? 1 : 0);
+ }
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ RecalcTrackScrollInfo ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+}
+
+// 『ツール(&T)』-『現在のトラックのみ表示(&C)』
+void CMusicalScoreFrame::OnUpdateMusicalScoreOnlyCurTrackUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bOnlyCurTrack);
+}
+
+// 『ツール(&T)』-『全てのトラックを表示(&A)』
+void CMusicalScoreFrame::OnMusicalScoreShowAllTrack () {
+ long lTrackCount = m_pTrackListBox->GetCount ();
+ long lTrackCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bShowAllTrack) {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ }
+ else {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = TRUE;
+ }
+ for (long i = 0; i < lTrackCount; i++) {
+ m_pTrackListBox->SetCheck (i, IsTrackVisible (i) ? 1 : 0);
+ }
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ RecalcTrackScrollInfo ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+
+}
+
+// 『ツール(&T)』-『全てのトラックを表示(&A)』
+void CMusicalScoreFrame::OnUpdateMusicalScoreShowAllTrackUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bShowAllTrack);
+}
+
+
+// 『ツール(&T)』-『自動ページ更新』
+void CMusicalScoreFrame::OnMusicalScoreAutoPageUpdate () {
+ m_bAutoPageUpdate = !m_bAutoPageUpdate;
+}
+
+// 『ツール(&T)』-『自動ページ更新』
+void CMusicalScoreFrame::OnUpdateMusicalScoreAutoPageUpdateUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bAutoPageUpdate);
+}
+
+
+// トラックコンボが選択され終わった時
+void CMusicalScoreFrame::OnTrackComboSelEndOK () {
+ // カレントトラックを更新する
+ long lCurTrackIndex = m_wndTrackCombo.GetCurSel ();
+ SetCurTrackIndex (lCurTrackIndex);
+ SetTrackVisible (lCurTrackIndex);
+ // カレントチャンネルも更新する
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+}
+
+// トラックリストのチェックボックスが変化したとき
+void CMusicalScoreFrame::OnTrackListChkChange () {
+ // トラックの表示/非表示をチェックボックスの状態に合わせる
+ long lCount = m_pTrackListBox->GetCount ();
+ long lCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bOnlyCurTrack) {
+ m_bOnlyCurTrack = FALSE;
+ }
+ for (long i = 0; i < lCount; i++) {
+ m_bTrackVisible[i] = m_pTrackListBox->GetCheck (i);
+ if (m_bTrackVisible[i] == FALSE) { // TODO
+ m_bShowAllTrack = FALSE;
+ }
+ }
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ RecalcTrackScrollInfo ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+}
+
+// トラックリストの選択項目が変化したとき
+void CMusicalScoreFrame::OnTrackListSelChange () {
+ // カレントトラックを変更する
+ long lCurTrackIndex = m_pTrackListBox->GetCurSel ();
+ SetCurTrackIndex (lCurTrackIndex);
+ // カレントチャンネルも更新する
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+}
+
+// スナップコンボが選択され終わった時(20111017追加)
+void CMusicalScoreFrame::OnSnapComboSelEndOK () {
+ long lSnapComboIndex = m_wndSnapCombo.GetCurSel ();
+ long lResolutionComboIndex = m_wndResolutionCombo.GetCurSel ();
+ if (0 <= lSnapComboIndex && lSnapComboIndex <= 6 && lResolutionComboIndex < lSnapComboIndex) {
+ m_wndResolutionCombo.SetCurSel (lSnapComboIndex);
+ this->PostMessage (WM_COMMAND, (WPARAM)((CBN_SELENDOK << 16) | IDC_RESOLUTIONCOMBO),
+ (LPARAM)(m_wndResolutionCombo.GetSafeHwnd ()));
+ }
+}
+
+// 表示精度コンボが選択され終わった時
+void CMusicalScoreFrame::OnResolutionComboSelEndOK () {
+ // 全トラックの音符情報と音符グループ情報を更新する
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ UpdateTrackInfoArray ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+}
+
+
+// 『ポップアップ』-『このトラックのみ表示ON』
+void CMusicalScoreFrame::OnPopupTrackVisibleOn () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lCount = m_pTrackListBox->GetCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, i == lTrackIndex ? 1 : 0);
+ m_bTrackVisible[i] = (i == lTrackIndex ? TRUE : FALSE);
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // カレントトラックとカレントチャンネルを更新
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ // 譜面の作り直し
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『このトラックのみ表示ON』
+void CMusicalScoreFrame::OnUpdatePopupTrackVisibleOnUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『このトラックのみ表示OFF』
+void CMusicalScoreFrame::OnPopupTrackVisibleOff () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ return;
+ }
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lCount = m_pTrackListBox->GetCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, i == lTrackIndex ? 0 : 1);
+ m_bTrackVisible[i] = (i == lTrackIndex ? FALSE : TRUE);
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // カレントトラックとカレントチャンネルを更新
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ // 譜面の作り直し
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『このトラックのみ表示OFF』
+void CMusicalScoreFrame::OnUpdatePopupTrackVisibleOffUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『全トラック表示ON』
+void CMusicalScoreFrame::OnPopupTrackVisibleAll () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lCount = m_pTrackListBox->GetCount ();
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, 1);
+ m_bTrackVisible[i] = TRUE;
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // 譜面の作り直し
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ VERIFY (UpdateMeasureInfoArray ());
+ VERIFY (UpdateTrackInfoArray ());
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+
+}
+
+// 『ポップアップ』-『全トラック表示ON』
+void CMusicalScoreFrame::OnUpdatePopupTrackVisibleAllUI (CCmdUI* pCmdUI) {
+}
+
+
+// 『ポップアップ』-『このイベントのプロパティ(&R)』 // 20110109修正
+void CMusicalScoreFrame::OnPopupEventProperty () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ if (pSekaijuDoc->m_pTempEvent == NULL || pSekaijuDoc->m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsNote (pSekaijuDoc->m_pTempEvent)) {
+ return;
+ }
+ MIDIEvent* pNoteOffEvent = pSekaijuDoc->m_pTempEvent->m_pNextCombinedEvent;
+ if (pNoteOffEvent == NULL) {
+ return;
+ }
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lTime = MIDIEvent_GetTime (pSekaijuDoc->m_pTempEvent);
+ CString strTime;
+ pSekaijuDoc->LongTimeToStringTime (pSekaijuDoc->m_pMIDIData, lTime, &strTime);
+ CPropertyNoteDlg theDlg;
+ theDlg.m_bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ theDlg.m_bNoteOnNoteOn0 = (MIDIEvent_GetKind (pNoteOffEvent) & 0xF0) == 0x80 ? FALSE : TRUE;
+ MIDITrack* pMIDITrack;
+ forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) {
+ TCHAR szTrackName[256];
+ memset (szTrackName, 0, sizeof (szTrackName));
+ MIDITrack_GetName (pMIDITrack, szTrackName, TSIZEOF (szTrackName));
+ theDlg.m_theTrackNameArray.Add (szTrackName);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ theDlg.m_theTrackOutputChannelArray.Add ((DWORD)lTrackOutputChannel);
+ }
+ long lKey = 0;
+ for (lKey = 0; lKey < 128; lKey++) {
+ CString strKeyName;
+ strKeyName = pSekaijuDoc->GetKeyName (pSekaijuDoc->m_pTempTrack, lTime, lKey);
+ theDlg.m_theKeyNameArray.Add (strKeyName);
+ }
+ theDlg.m_nTrackIndex = (int)lTrackIndex;
+ theDlg.m_strTime = strTime;
+ theDlg.m_nChannel = (int)MIDIEvent_GetChannel (pSekaijuDoc->m_pTempEvent) + 1;
+ theDlg.m_nKey = (int)MIDIEvent_GetKey (pSekaijuDoc->m_pTempEvent);
+ theDlg.m_nOnVelocity = (int)MIDIEvent_GetVelocity (pSekaijuDoc->m_pTempEvent);
+ theDlg.m_nOffVelocity = (int)MIDIEvent_GetVelocity (pNoteOffEvent);
+ theDlg.m_nDuration = (int)MIDIEvent_GetDuration (pSekaijuDoc->m_pTempEvent);
+ if (theDlg.DoModal () == IDOK) {
+ // トラック抽出
+ long lTrackIndex = (long)theDlg.m_nTrackIndex;
+ if (MIDIData_GetFormat (pSekaijuDoc->m_pMIDIData) == 1 && lTrackIndex == 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ MIDITrack* pNewTrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ if (pNewTrack == NULL) {
+ CString strMsg;
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // タイム文字列をlong型に変換
+ long lTime = MIDIEvent_GetTime (pSekaijuDoc->m_pTempEvent);
+ long lErrorID = pSekaijuDoc->StringTimeToLongTime (pSekaijuDoc->m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ BeginWaitCursor ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_NOTE));
+ pSekaijuDoc->AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 所属トラックが変更されない場合
+ if (pNewTrack == pSekaijuDoc->m_pTempTrack) {
+ // EOTの履歴保持(20110109修正)
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pSekaijuDoc->m_pTempEvent);
+ VERIFY (pNewEvent = pSekaijuDoc->ReplaceMIDIEvent (pSekaijuDoc->m_pTempEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetChannel (pNewEvent, theDlg.m_nChannel - 1);
+ MIDIEvent_SetKey (pNewEvent, theDlg.m_nKey);
+ MIDIEvent_SetVelocity (pNewEvent, theDlg.m_nOnVelocity);
+ MIDIEvent_SetDuration (pNewEvent, theDlg.m_nDuration);
+ if (!theDlg.m_bNoteOnNoteOn0) {
+ MIDIEvent* pNewNoteOffEvent = pNewEvent->m_pNextCombinedEvent;
+ MIDIEvent_SetVelocity (pNewNoteOffEvent, theDlg.m_nOffVelocity);
+ }
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ // EOTの履歴保持(20110109修正)
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+ // 所属トラックが変更される場合
+ else {
+ // イベントの置換と除去
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pSekaijuDoc->m_pTempEvent);
+ VERIFY (pNewEvent = pSekaijuDoc->ReplaceMIDIEvent (pSekaijuDoc->m_pTempEvent));
+ VERIFY (MIDITrack_RemoveEvent (pSekaijuDoc->m_pTempTrack, pNewEvent));
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ // イベントの挿入と変更
+ VERIFY (MIDITrack_InsertEvent (pNewTrack, pNewEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetChannel (pNewEvent, theDlg.m_nChannel - 1);
+ MIDIEvent_SetKey (pNewEvent, theDlg.m_nKey);
+ MIDIEvent_SetVelocity (pNewEvent, theDlg.m_nOnVelocity);
+ MIDIEvent_SetDuration (pNewEvent, theDlg.m_nDuration);
+ if (!theDlg.m_bNoteOnNoteOn0) {
+ MIDIEvent* pNewNoteOffEvent = pNewEvent->m_pNextCombinedEvent;
+ MIDIEvent_SetVelocity (pNewNoteOffEvent, theDlg.m_nOffVelocity);
+ }
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ // EOTの履歴保持(20110109修正)
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ SetTrackVisible (theDlg.m_nTrackIndex);
+ SetCurTrackIndex (theDlg.m_nTrackIndex);
+ SetCurChannel (theDlg.m_nChannel - 1);
+ SetCurVelocity (theDlg.m_nOnVelocity);
+ SetCurDuration (theDlg.m_nDuration);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『このイベントのプロパティ(&R)』
+void CMusicalScoreFrame::OnUpdatePopupEventPropertyUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (pSekaijuDoc->m_pTempEvent == NULL || pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsNote (pSekaijuDoc->m_pTempEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ MIDIEvent* pNoteOffEvent = pSekaijuDoc->m_pTempEvent->m_pNextCombinedEvent;
+ if (pNoteOffEvent == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
diff --git a/src/MusicalScoreFrame.h b/src/MusicalScoreFrame.h
new file mode 100644
index 0000000..907dcd5
--- /dev/null
+++ b/src/MusicalScoreFrame.h
@@ -0,0 +1,352 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面フレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+
+
+// 音符情報(ひとつのおたまじゃくしにつきひとつ確保)
+typedef struct tagMusicalScoreNoteInfo {
+ MIDIEvent* m_pNoteOnEvent; // ノートオンイベントへのポインタ
+ MIDIEvent* m_pNoteOffEvent; // ノートオフイベントへのポインタ
+ long m_lNoteOnTime; // ノートオン時刻[Tick]
+ long m_lNoteOnMeasure; // ノートオン小節
+ long m_lNoteOnBeat; // ノートオン拍
+ long m_lNoteOnTick; // ノートオンティック
+ long m_lNoteOffTime; // ノートオフ時刻[Tick]
+ long m_lNoteOffMeasure; // ノートオフ小節
+ long m_lNoteOffBeat; // ノートオフ拍
+ long m_lNoteOffTick; // ノートオフティック
+ long m_lFlags; // フラグ
+ long m_lSelected; // 選択状態
+ struct tagMusicalScoreNoteInfo* m_pPrevNoteInfo; // 次の音符情報へのポインタ(なければNULL)
+ struct tagMusicalScoreNoteInfo* m_pNextNoteInfo; // 前の音符情報へのポインタ(なければNULL)
+ void* m_pNoteGroupInfo; // 旗グループ情報へのポインタ(なければNULL)
+ void* m_pTripletGroupInfo; // 3連符グループ情報へのポインタ(なければNULL)
+} MusicalScoreNoteInfo;
+
+// 旗グループ情報(複数の音符を旗をつなげて束ねる情報)
+typedef struct tagMusicalScoreNoteGroupInfo {
+ MusicalScoreNoteInfo* m_pFirstNoteInfo; // 最初の音符情報へのポインタ
+ MusicalScoreNoteInfo* m_pLastNoteInfo; // 最後の音符情報へのポインタ
+ long m_lBeginTime; // 開始時刻
+ long m_lEndTime; // 終了時刻
+ long m_lMinKey; // 最低音階(0-127)
+ long m_lMaxKey; // 最高音階(0-127)
+ long m_lMinDur; // 最短音長さ
+ long m_lMaxDur; // 最長音長さ
+ long m_lNumNoteInfo; // グループ内の音符数
+} MusicalScoreNoteGroupInfo;
+
+// 3連符グループ情報(複数の音符を-3-でつなげて束ねる情報)
+typedef struct tagMusicalScoreTripletGroupInfo {
+ MusicalScoreNoteInfo* m_pFirstNoteInfo; // 最初の音符情報へのポインタ
+ MusicalScoreNoteInfo* m_pLastNoteInfo; // 最後の音符情報へのポインタ
+ long m_lBeginTime; // 開始時刻
+ long m_lEndTime; // 終了時刻
+ long m_lMinKey; // 最低音階(0-127)
+ long m_lMaxKey; // 最高音階(0-127)
+ long m_lMinDur; // 最短音長さ
+ long m_lMaxDur; // 最長音長さ
+ long m_lNumNoteInfo; // グループ内の音符数
+} MusicalScoreTripletGroupInfo;
+
+// トラック情報
+typedef struct {
+ long m_lTop; // 上端座標[pixel]
+ long m_lHeight; // 高さ[pixel]
+ long m_lFlags; // フラグ
+ long m_lMinKey; // トラック内最低音階(0-127)
+ long m_lMaxKey; // トラック内最高音階(0-127)
+ CPtrArray m_theNoteInfoArray; // 音符情報の配列
+ CPtrArray m_theNoteGroupInfoArray; // 音符グループ情報の配列
+ CPtrArray m_theTripletGroupInfoArray; // 3連音符グループ情報の配列
+ long m_lTopPrint; // 上端座標(印刷用)[*1/10mm]
+ long m_lHeightPrint; // 高さ(印刷用)[*1/10mm]
+} MusicalScoreTrackInfo;
+
+// 小節情報
+typedef struct {
+ long m_lTime; // この小節の開始タイム[Tick][Subframe]
+ long m_lDuration; // この小節にの長さ[Tick][Subframe]
+ long m_lLeft; // この小節の左座標[pixel]
+ long m_lSignatureWidth; // この小節の拍子記号・調性記号用幅[pixel]
+ long m_lPreWidth; // この小節の左余白幅[pixel]
+ long m_lWidth; // この小節の幅[pixel]
+ long m_lPostWidth; // この小節の右余白幅[pixel]
+ long m_lFlags; // フラグ
+ long m_lTimeSignature; // この小節の拍子記号
+ long m_lKeySignature; // この小節の調性記号
+ long m_lLeftPrint; // この小節の左座標(印刷用)[*1/10mm]
+ long m_lSignatureWidthPrint; // この小節の拍子記号・調性記号用幅(印刷用)[*1/10mm]
+ long m_lPreWidthPrint; // この小節の左余白幅(印刷用)[*1/10mm]
+ long m_lWidthPrint; // この小節の幅(印刷用)[*1/10mm]
+ long m_lPostWidthPrint; // この小節の右余白幅[pixel](印刷用)[*1/10mm]
+} MusicalScoreMeasureInfo;
+
+
+
+
+class CMusicalScoreFrame : public CChildFrame {
+ DECLARE_DYNCREATE (CMusicalScoreFrame)
+
+ //-------------------------------------------------------------------------
+ // アトリビュート
+ //-------------------------------------------------------------------------
+protected:
+ long m_lToolBar1Height; // ツールバー1の高さ[pixel]
+ long m_lKeyHeight; // トラック番号-時間ビューの高さ[pixel]
+ long m_lScaleHeight; // 上部目盛りビューの高さ[pixel]
+ long m_lScaleWidth; // 左部目盛りビューの高さ[pixel]
+ long m_lTimeWidth; // トラック番号ー-時間ビューの幅[pixel]
+ long m_lHScrollBarHeight; // 水平スクロールバーの高さ[pixel]
+ long m_lVScrollBarWidth; // 垂直スクロールバーの高さ[pixel]
+ long m_lTrackListWidth; // トラックリストボックスの幅[pixel]
+ long m_lTrackZoom; // トラック方向拡大倍率[倍]
+ long m_lTimeZoom; // 時間方向拡大倍率[倍]
+ long m_lTrackScrollPos; // トラック方向スクロール位置[pixel]
+ long m_lTimeScrollPos; // 時間方向スクロール位置[pixel]
+public:
+ // 描画補助情報
+ CPtrArray m_theTrackInfoArray; // トラックごとの情報
+ CPtrArray m_theMeasureInfoArray; // 小節ごとの情報
+
+public:
+ CFont m_theFont; // 譜面ウィンドウで使うフォント
+ CFont m_theTimeMeasureFont; // 拍子記号・調性記号用のフォント
+ CSekaijuToolBar m_wndToolBar1; // ツールバー1(上)
+ CColorfulComboBox m_wndTrackCombo; // ツールバー上のトラックコンボボックス
+ CComboBox m_wndChannelCombo; // ツールバー上のチャンネルコンボボックス
+ CComboBox m_wndSnapCombo; // ツールバー上のスナップコンボボックス
+ CComboBox m_wndVelocityCombo; // ツールバー上のベロシティコンボボックス
+ CComboBox m_wndDurationCombo; // ツールバー上の音長さコンボボックス
+ CComboBox m_wndResolutionCombo; // ツールバー上の表示精度コンボボックス
+ CView* m_pDummyView; // ダミービュー(Visible=FALSE)へのポインタ
+ CView* m_pPrintView; // 印刷用ビュー(Visible=FALSE)へのポインタ
+ CView* m_pScaleView; // 目盛りビューへのポインタ
+ CView* m_pTimeScaleView; // 時間目盛りビューへのポインタ
+ CView* m_pTrackScaleView; // トラック番号目盛りビューへのポインタ
+ CView* m_pTrackTimeView; // トラック番号-タイムビューへのポインタ
+ CCheckListBox* m_pTrackListBox; // トラックリストボックス
+ CScrollBar m_wndTimeScroll; // 時間方向スクロールバー
+ CScrollBar m_wndTrackScroll; // トラック方向スクロールバー
+ CScrollBar m_wndSizeScroll; // サイズ用スクロールバー
+ CBitmapButton m_wndTimeZoomUp; // 時間方向拡大ボタン
+ CBitmapButton m_wndTimeZoomDown; // 時間方向縮小ボタン
+ CBitmapButton m_wndTrackZoomUp; // トラック方向拡大ボタン
+ CBitmapButton m_wndTrackZoomDown; // トラック方向縮小ボタン
+
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標(スプリッターを動かすのに使う)
+ CPoint m_ptMouseMoveOld; // マウスが動かされたときの前回の座標(スプリッターを動かすのに使う)
+ BOOL m_bSplitterMovingH; // 現在水平スプリッターを動かしているところか?
+ BOOL m_bSplitterMovingV; // 現在垂直スプリッターを動かしているところか?
+
+public:
+ BOOL m_bAutoPageUpdate; // 自動的にページを更新するか?
+ long m_lCurTool; // 現在の選択されているツール(0=描画,1=線画,2=消しゴム,3=選択,4=試聴)
+
+protected:
+ BOOL m_bOnlyCurTrack; // 現在のトラックのみを表示するか?
+ BOOL m_bShowAllTrack; // すべてのトラックを表示するか?
+ BOOL m_bTrackVisible[MAXMIDITRACKNUM]; // トラック[0〜65535]は可視か?
+
+ //-------------------------------------------------------------------------
+ // 構築と破壊
+ //-------------------------------------------------------------------------
+public:
+ CMusicalScoreFrame (); // コンストラクタ
+ virtual ~CMusicalScoreFrame (); // デストラクタ
+
+ //-------------------------------------------------------------------------
+ // オペレーション
+ //-------------------------------------------------------------------------
+public:
+ virtual CSekaijuDoc* GetDocument ();
+ virtual long GetTimeZoom ();
+ virtual long GetTrackZoom ();
+ virtual long XtoTime (long x);
+ virtual long TimetoX (long lTime);
+ virtual long MeasuretoX (long lMeasure);
+ virtual long MeasuretoX2 (long lMeasure);
+ virtual long YtoTrackIndex (long y);
+ virtual long TrackIndexYtoKey (long lTrackIndex, long y, long lKeySignature);
+ virtual long KeytoLineNo (long lKey, long lKeySignature);
+ virtual long KeytoSF (long lKey, long lKeySignature);
+ virtual long TrackIndexLineNotoY (long lTrackIndex, long lLineNo);
+ virtual long TrackIndexKeytoY (long lTrackIndex, long lKey, long lKeySignature);
+ virtual long GetTimeScrollPos ();
+ virtual long GetTrackScrollPos ();
+ virtual long SetTimeScrollPos (long lTimeScrollPos);
+ virtual long SetTrackScrollPos (long lTrackScrollPos);
+ virtual long GetVisibleLeftTime ();
+ virtual long GetVisibleRightTime ();
+ virtual long GetVisibleTopTrack ();
+ virtual long GetVisibleBottomTrack ();
+ virtual void DrawSplitterCaptor (CDC* pDC, CPoint pt);
+ virtual long GetCurTrackIndex ();
+ virtual long GetCurChannel ();
+ virtual long GetCurSnap ();
+ virtual long GetCurVelocity ();
+ virtual long GetCurDuration ();
+ virtual long GetCurResolution ();
+ virtual BOOL SetCurTrackIndex (long lCurTrackIndex);
+ virtual BOOL SetCurChannel (long lCurChannel);
+ virtual BOOL SetCurSnap (long lCurSnap);
+ virtual BOOL SetCurVelocity (long lCurVelocity);
+ virtual BOOL SetCurDuration (long lCurDuration);
+ virtual BOOL SetCurResolution (long lCurResolution);
+ virtual BOOL IsTrackVisible (long lTrackIndex);
+ virtual BOOL SetTrackVisible (long lTrackIndex);
+ virtual BOOL UpdateTrackCombo ();
+ virtual BOOL UpdateTrackList ();
+ virtual BOOL UpdateSnapCombo ();
+ virtual BOOL UpdateVelocityCombo ();
+ virtual BOOL UpdateDurationCombo ();
+ virtual BOOL UpdateResolutionCombo ();
+ virtual void RecalcTrackScrollInfo ();
+ virtual void RecalcTimeScrollInfo ();
+
+
+ virtual BOOL DeleteTrackInfoArray ();
+ virtual BOOL DeleteMeasureInfoArray ();
+ virtual BOOL DeleteNoteInfoArray (long lTrackIndex);
+ virtual BOOL DeleteNoteGroupInfoArray (long lTrackIndex);
+ virtual BOOL DeleteTripletGroupInfoArray (long lTrackIndex);
+ virtual BOOL UpdateMeasureInfoArray ();
+ virtual BOOL UpdateTrackInfoArray ();
+ virtual BOOL UpdateNoteInfoArray (long lTrackIndex, MIDITrack* pMIDITrack);
+ virtual BOOL UpdateNoteGroupInfoArray (long lTrackIndex, MIDITrack* pMIDITrack);
+ virtual BOOL UpdateTripletGroupInfoArray (long lTrackIndex, MIDITrack* pMIDITrack);
+ virtual MusicalScoreNoteInfo* CreateNote
+ (MIDIEvent* pNoteEvent, long lNoteOnTime, long lNoteOnMeasure, long lNoteOnBeat, long lNoteOnTick,
+ long lNoteOffTime, long lNoteOffMeasure, long lNoteOffBeat, long lNoteOffTick, long lFlags);
+ virtual void DeleteNoteInfo (MusicalScoreNoteInfo* pNoteInfo);
+ virtual BOOL AddNoteInfo (MusicalScoreTrackInfo* pTrackInfo, MusicalScoreNoteInfo* pNoteInfo);
+ MusicalScoreNoteGroupInfo* CreateNoteGroupInfo (MusicalScoreNoteInfo* pNoteInfo);
+ void DeleteNoteGroupInfo (MusicalScoreNoteGroupInfo* pNoteGroupInfo);
+ BOOL AddNoteGroupInfo (MusicalScoreTrackInfo* pTrackInfo, MusicalScoreNoteGroupInfo* pNoteGroupInfo);
+ MusicalScoreTripletGroupInfo* CreateTripletGroupInfo (MusicalScoreNoteInfo* pNoteInfo);
+ void DeleteTripletGroupInfo (MusicalScoreTripletGroupInfo* pTripletGroupInfo);
+ BOOL AddTripletGroupInfo (MusicalScoreTrackInfo* pTrackInfo, MusicalScoreTripletGroupInfo* pNoteGroupInfo);
+
+ virtual long GetTrackInfoCount ()
+ {return m_theTrackInfoArray.GetSize ();}
+ virtual MusicalScoreTrackInfo* GetTrackInfo (long lTrackIndex)
+ {return lTrackIndex < m_theTrackInfoArray.GetSize () ?
+ ((MusicalScoreTrackInfo*)m_theTrackInfoArray.GetAt (lTrackIndex)) : NULL;}
+
+ virtual long GetMeasureInfoCount ()
+ {return m_theMeasureInfoArray.GetSize ();}
+ virtual MusicalScoreMeasureInfo* GetMeasureInfo (long lMeasureIndex)
+ {return lMeasureIndex < m_theMeasureInfoArray.GetSize () ?
+ ((MusicalScoreMeasureInfo*)m_theMeasureInfoArray.GetAt (lMeasureIndex)) : NULL;}
+ virtual long GetMeasureTime (long lMeasureIndex)
+ {return lMeasureIndex < m_theMeasureInfoArray.GetSize () ?
+ ((MusicalScoreMeasureInfo*)m_theMeasureInfoArray.GetAt (lMeasureIndex))->m_lTime : 0;}
+ virtual long GetMeasureLeft (long lMeasureIndex)
+ {return lMeasureIndex < m_theMeasureInfoArray.GetSize () ?
+ ((MusicalScoreMeasureInfo*)m_theMeasureInfoArray.GetAt (lMeasureIndex))->m_lLeft : 0;}
+
+
+ //-------------------------------------------------------------------------
+ // オーバーライド
+ //-------------------------------------------------------------------------
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+ virtual void OnUpdateFrameTitle (BOOL bAddToTitle);
+ virtual void RecalcLayout (BOOL bNotify = TRUE);
+ virtual BOOL OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ virtual BOOL OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
+
+ //-------------------------------------------------------------------------
+ // メッセージマップ
+ //-------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnSize (UINT nType, int cx, int cy);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg BOOL OnEraseBkgnd (CDC* pDC);
+
+ afx_msg void OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd);
+ afx_msg void OnPaint ();
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnTimeZoomDown ();
+ afx_msg void OnTimeZoomUp ();
+ afx_msg void OnTrackZoomDown ();
+ afx_msg void OnTrackZoomUp ();
+ afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnMusicalScorePen ();
+ afx_msg void OnUpdateMusicalScorePenUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreLine ();
+ afx_msg void OnUpdateMusicalScoreLineUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreEraser ();
+ afx_msg void OnUpdateMusicalScoreEraserUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreSelect ();
+ afx_msg void OnUpdateMusicalScoreSelectUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreSpeaker ();
+ afx_msg void OnUpdateMusicalScoreSpeakerUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreWholeNote ();
+ afx_msg void OnUpdateMusicalScoreWholeNoteUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreHalfNote ();
+ afx_msg void OnUpdateMusicalScoreHalfNoteUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreQuarterNote ();
+ afx_msg void OnUpdateMusicalScoreQuarterNoteUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreQuaverNote ();
+ afx_msg void OnUpdateMusicalScoreQuaverNoteUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreSemiQuaverNote ();
+ afx_msg void OnUpdateMusicalScoreSemiQuaverNoteUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreDemiSemiQuaverNote ();
+ afx_msg void OnUpdateMusicalScoreDemiSemiQuaverNoteUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreDotted ();
+ afx_msg void OnUpdateMusicalScoreDottedUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreTriplet ();
+ afx_msg void OnUpdateMusicalScoreTripletUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreOnlyCurTrack ();
+ afx_msg void OnUpdateMusicalScoreOnlyCurTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreShowAllTrack ();
+ afx_msg void OnUpdateMusicalScoreShowAllTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnMusicalScoreAutoPageUpdate ();
+ afx_msg void OnUpdateMusicalScoreAutoPageUpdateUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnTrackComboSelEndOK ();
+ afx_msg void OnTrackListChkChange ();
+ afx_msg void OnTrackListSelChange ();
+ afx_msg void OnSnapComboSelEndOK ();
+ afx_msg void OnResolutionComboSelEndOK ();
+
+ afx_msg void OnPopupTrackVisibleOn ();
+ afx_msg void OnUpdatePopupTrackVisibleOnUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackVisibleOff ();
+ afx_msg void OnUpdatePopupTrackVisibleOffUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackVisibleAll ();
+ afx_msg void OnUpdatePopupTrackVisibleAllUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupEventProperty ();
+ afx_msg void OnUpdatePopupEventPropertyUI (CCmdUI* pCmdUI);
+
+ DECLARE_MESSAGE_MAP()
+};
+
+
diff --git a/src/MusicalScoreOptionPage.cpp b/src/MusicalScoreOptionPage.cpp
new file mode 100644
index 0000000..fe67d38
--- /dev/null
+++ b/src/MusicalScoreOptionPage.cpp
@@ -0,0 +1,88 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面オプションページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "MusicalScoreOptionPage.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMusicalScoreOptionPage::CMusicalScoreOptionPage () : CPropertyPage (CMusicalScoreOptionPage::IDD) {
+ m_lDefTrackZoom = 0;
+ m_lDefTimeZoom = 0;
+ m_bSpeakerModeVisibleTrack = FALSE;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CMusicalScoreOptionPage::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_MUSICALSCOREOPTION_DEFTRACKZOOM, m_lDefTrackZoom);
+ DDV_MinMaxInt (pDX, m_lDefTrackZoom, 1, 8);
+ DDX_Text (pDX, IDC_MUSICALSCOREOPTION_DEFTIMEZOOM, m_lDefTimeZoom);
+ DDV_MinMaxInt (pDX, m_lDefTimeZoom, 1, 16);
+ DDX_Check (pDX, IDC_MUSICALSCOREOPTION_ENABLETRACKZOOMKEY, m_bEnableTrackZoomKey);
+ DDX_Check (pDX, IDC_MUSICALSCOREOPTION_ENABLETIMEZOOMKEY, m_bEnableTimeZoomKey);
+ DDX_Radio (pDX, IDC_MUSICALSCOREOPTION_SPEAKERMODEALLTRACK, m_bSpeakerModeVisibleTrack);
+
+}
+
+// ダイアログの初期化
+BOOL CMusicalScoreOptionPage::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_MUSICALSCOREOPTION_DEFTRACKZOOMSP))->SetRange (1, 8);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_MUSICALSCOREOPTION_DEFTIMEZOOMSP))->SetRange (1, 16);
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CMusicalScoreOptionPage, CPropertyPage)
+END_MESSAGE_MAP ()
+
+
diff --git a/src/MusicalScoreOptionPage.h b/src/MusicalScoreOptionPage.h
new file mode 100644
index 0000000..7b35807
--- /dev/null
+++ b/src/MusicalScoreOptionPage.h
@@ -0,0 +1,61 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールオプションページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MUSICALSCOREOPTIONPAGE_H_
+#define _MUSICALSCOREOPTIONPAGE_H_
+
+class CMusicalScoreOptionPage : public CPropertyPage {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lDefTrackZoom; // デフォルトのトラック方向拡大倍率[倍]
+ long m_lDefTimeZoom; // デフォルトの時間方向拡大倍率[倍]
+ BOOL m_bEnableTrackZoomKey; // トラック方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bEnableTimeZoomKey; // 時間方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bSpeakerModeVisibleTrack; // 可視状態のトラックを試聴する
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMusicalScoreOptionPage (); // コンストラクタ
+ enum {IDD = IDD_MUSICALSCOREOPTION};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ //afx_msg void OnChangeEnableAutoSave ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/MusicalScorePrintView.cpp b/src/MusicalScorePrintView.cpp
new file mode 100644
index 0000000..adb0ff1
--- /dev/null
+++ b/src/MusicalScorePrintView.cpp
@@ -0,0 +1,2137 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面印刷ビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include <afxpriv.h>
+#include "common.h"
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "MusicalScoreFrame.h"
+#include "MusicalScorePrintView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+#define MUSICALSCOREPRINTVIEW_LEFTMARGIN 200
+#define MUSICALSCOREPRINTVIEW_RIGHTMARGIN 200
+#define MUSICALSCOREPRINTVIEW_TOPMARGIN 200
+#define MUSICALSCOREPRINTVIEW_BOTTOMMARGIN 200
+#define MUSICALSCOREPRINTVIEW_SCALEHEIGHT 100
+#define MUSICALSCOREPRINTVIEW_SCALEWIDTH 120
+
+
+IMPLEMENT_DYNCREATE (CMusicalScorePrintView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CMusicalScorePrintView, CSekaijuView)
+ ON_COMMAND (ID_FILE_PRINT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CMusicalScorePrintView::CMusicalScorePrintView () {
+ // 印刷用文字フォントの作成(2.5ミリ)
+ CString strDefaultFontName;
+ VERIFY (strDefaultFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (25, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strDefaultFontName);
+
+}
+
+// デストラクタ
+CMusicalScorePrintView::~CMusicalScorePrintView () {
+ m_theFont.DeleteObject ();
+ m_theRowPageInfoArray.RemoveAll ();
+ m_theRollPageInfoArray.RemoveAll ();
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 小節情報構造体配列の印刷関係部分を計算する。
+void CMusicalScorePrintView::CalcMeasureInfoArray () {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ m_theRollPageInfoArray.RemoveAll ();
+ long lTimeZoom = 4;
+ long lLeftMargin = MUSICALSCOREPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = MUSICALSCOREPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = MUSICALSCOREPRINTVIEW_SCALEWIDTH;
+ long lTimeWidth = m_sizLogPaper.cx - lScaleWidth - lLeftMargin - lRightMargin;
+ long lMeasureInfoCount = pMusicalScoreFrame->GetMeasureInfoCount ();
+ long lMeasure = 0;
+ long lMeasure2 = 0;
+ long lCurRollPage = 0;
+ while (lMeasure < lMeasureInfoCount) {
+ long lStartMeasure = lMeasure;
+ long lEndMeasure = lMeasure;
+ long lCurLeftPrint = 0;
+ long lNextLeftPrint = 0;
+ long lTempWidth = 0;
+ // このページに入る小節数と小節幅(仮)を計算
+ while (lMeasure < lMeasureInfoCount) {
+ MusicalScoreMeasureInfo* pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lMeasure);
+ // 次の小節の開始x位置[*1/10mm]を計算
+ // このページの最初の小節の場合、拍子記号・調性記号必要
+ if (lMeasure - lStartMeasure == 0) {
+ lNextLeftPrint =
+ lCurLeftPrint +
+ (16 + pMeasureInfo->m_lPreWidth +
+ pMeasureInfo->m_lWidth + pMeasureInfo->m_lPostWidth) * 3 * lTimeZoom;
+ }
+ // 通常の場合
+ else {
+ lNextLeftPrint =
+ lCurLeftPrint +
+ (pMeasureInfo->m_lSignatureWidth + pMeasureInfo->m_lPreWidth +
+ pMeasureInfo->m_lWidth + pMeasureInfo->m_lPostWidth) * 3 * lTimeZoom;
+ }
+ // 次の小節の開始x位置[*1/10mm]が譜面幅からはみ出している場合ループ脱出
+ if (lNextLeftPrint > lTimeWidth || lMeasure == lMeasureInfoCount - 1) {
+ lEndMeasure = lMeasure;
+ lTempWidth = lCurLeftPrint;
+ // ただし1ページに最低1小節は入れる。
+ // 最終小節の場合のみ、これ以上whileループしないため
+ if (lEndMeasure <= lStartMeasure || lMeasure == lMeasureInfoCount - 1) {
+ lEndMeasure = lMeasure + 1;
+ lTempWidth = lNextLeftPrint;
+ lMeasure++;
+ }
+ // lMeasureは今回のページには含めないので、インクリメントせずに脱出
+ break;
+ }
+ lCurLeftPrint = lNextLeftPrint;
+ lMeasure++;
+ }
+ // このページに入る小節の小節情報構造体の印刷関係部分を設定
+ lCurLeftPrint = 0;
+ lNextLeftPrint = 0;
+ for (lMeasure2 = lStartMeasure; lMeasure2 < lEndMeasure; lMeasure2++) {
+ MusicalScoreMeasureInfo* pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lMeasure2);
+ pMeasureInfo->m_lLeftPrint =
+ lTimeWidth * lCurRollPage + lCurLeftPrint;
+ // このページの最初の小節の場合、拍子記号・調性記号必要
+ if (lMeasure2 - lStartMeasure == 0) {
+ pMeasureInfo->m_lSignatureWidthPrint =
+ 16 * 3 * lTimeZoom * lTimeWidth / lTempWidth;
+ }
+ // 通常の場合
+ else {
+ pMeasureInfo->m_lSignatureWidthPrint =
+ pMeasureInfo->m_lSignatureWidth * 3 * lTimeZoom * lTimeWidth / lTempWidth;
+ }
+ pMeasureInfo->m_lPreWidthPrint =
+ pMeasureInfo->m_lPreWidth * 3 * lTimeZoom * lTimeWidth / lTempWidth;
+ pMeasureInfo->m_lWidthPrint =
+ pMeasureInfo->m_lWidth * 3 * lTimeZoom * lTimeWidth / lTempWidth;
+ pMeasureInfo->m_lPostWidthPrint =
+ pMeasureInfo->m_lPostWidth * 3 * lTimeZoom * lTimeWidth / lTempWidth;
+ lNextLeftPrint =
+ lCurLeftPrint + pMeasureInfo->m_lSignatureWidthPrint +
+ pMeasureInfo->m_lPreWidthPrint + pMeasureInfo->m_lWidthPrint +
+ pMeasureInfo->m_lPostWidthPrint;
+ lCurLeftPrint = lNextLeftPrint;
+ }
+ // 譜面ロール方向ページ情報配列に先頭小節番号を記録
+ m_theRollPageInfoArray.Add (lStartMeasure);
+ // ページ更新
+ lCurRollPage++;
+ }
+ m_theRollPageInfoArray.Add (lMeasureInfoCount - 1);
+}
+
+// トラック情報構造体配列の印刷関係部分を計算する。
+void CMusicalScorePrintView::CalcTrackInfoArray () {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ m_theRowPageInfoArray.RemoveAll ();
+ long lTrackZoom = 4;
+ long lTopMargin = MUSICALSCOREPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = MUSICALSCOREPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = MUSICALSCOREPRINTVIEW_SCALEHEIGHT;
+ long lTrackHeight = m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin;
+ long lTrackInfoCount = pMusicalScoreFrame->GetTrackInfoCount ();
+ long lTrack = 0;
+ long lTrack2 = 0;
+ long lCurRowPage = 0;
+ while (lTrack < lTrackInfoCount) {
+ long lStartTrack = lTrack;
+ long lEndTrack = lTrack;
+ long lCurTopPrint = 0;
+ long lNextTopPrint = 0;
+ long lTempHeight = 0;
+ // このページに入るトラック数とトラック高さ(仮)を計算
+ while (lTrack < lTrackInfoCount) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrack);
+ // 次のトラックの開始y位置[*1/10mm]を計算
+ lNextTopPrint =
+ lCurTopPrint + pTrackInfo->m_lHeight * 2 * lTrackZoom;
+ // 次のトラックの開始y位置[*1/10mm]が譜面高さからはみ出している場合ループ脱出
+ if (lNextTopPrint > lTrackHeight || lTrack == lTrackInfoCount - 1) {
+ lEndTrack = lTrack;
+ lTempHeight = lCurTopPrint;
+ // ただし1ページに最低1トラックは入れる。
+ // 最終トラックの場合のみ、これ以上whileループしないため
+ if (lEndTrack <= lStartTrack || lTrack == lTrackInfoCount - 1) {
+ lEndTrack = lTrack + 1;
+ lTempHeight = lNextTopPrint;
+ lTrack++;
+ }
+ // lTrackは今回のページに含めないのでインクリメントせずに脱出
+ break;
+ }
+ lCurTopPrint = lNextTopPrint;
+ lTrack++;
+ }
+ // このページに入るトラックのトラック情報構造体の印刷関係部分を設定
+ lCurTopPrint = 0;
+ lNextTopPrint = 0;
+ for (lTrack2 = lStartTrack; lTrack2 < lEndTrack; lTrack2++) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrack2);
+ pTrackInfo->m_lTopPrint =
+ lTrackHeight * lCurRowPage + lCurTopPrint;
+ if (lTrackHeight / lTempHeight >= 2) {
+ pTrackInfo->m_lHeightPrint =
+ pTrackInfo->m_lHeight * 2 * lTrackZoom * 2;
+ }
+ else {
+ pTrackInfo->m_lHeightPrint =
+ pTrackInfo->m_lHeight * 2 * lTrackZoom * lTrackHeight / lTempHeight;
+ }
+ lNextTopPrint =
+ lCurTopPrint + pTrackInfo->m_lHeightPrint;
+ lCurTopPrint = lNextTopPrint;
+ }
+ // 行方向ページ情報配列に先頭小節番号を記録
+ m_theRowPageInfoArray.Add (lStartTrack);
+ // ページ更新
+ lCurRowPage++;
+ }
+ m_theRowPageInfoArray.Add (lTrackInfoCount - 1);
+}
+
+
+// トラックインデックス・五線番号をY座標[*1/10mm]に変換
+long CMusicalScorePrintView::TrackIndexLineNotoY (long lTrackIndex, long lLineNo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ ASSERT (0 <= lTrackIndex &&lTrackIndex < pMusicalScoreFrame->GetTrackInfoCount ());
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackIndex));
+ long lTrackTopPrint = pTrackInfo->m_lTopPrint;
+ long lTrackHeightPrint = pTrackInfo->m_lHeightPrint;
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long lKey000Y = 0;
+ long ry = 8;
+ switch (lTrackFlags & 0x0000000F) {
+ case 1: // ト音記号
+ lKey000Y = (lTrackTopPrint + lTrackHeightPrint / 2) + 41 * ry;
+ break;
+ case 2: // へ音記号
+ lKey000Y = (lTrackTopPrint + lTrackHeightPrint / 2) + 29 * ry;
+ break;
+ case 3: // 大譜表
+ lKey000Y = (lTrackTopPrint + lTrackHeightPrint / 2) + 35 * ry;
+ break;
+ default:
+ lKey000Y = (lTrackTopPrint + lTrackHeightPrint / 2) + 35 * ry;
+ break;
+ }
+
+ long lTopMargin = MUSICALSCOREPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = MUSICALSCOREPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = MUSICALSCOREPRINTVIEW_SCALEHEIGHT;
+ long lTrackHeight = (m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin);
+
+ return lTrackHeight * m_lMaxRowPage - (lKey000Y - lLineNo * ry);
+}
+
+// トラックインデックス(0〜65535)・ノートキー(0〜127)をy座標[*1/10mm]に変換
+long CMusicalScorePrintView::TrackIndexKeytoY (long lTrackIndex, long lKey, long lKeySignature) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ long lLineNo = pMusicalScoreFrame->KeytoLineNo (lKey, lKeySignature);
+ return TrackIndexLineNotoY (lTrackIndex, lLineNo);
+}
+
+// タイム[Tick]をx座標[*1/10mm]に変換
+long CMusicalScorePrintView::TimetoX (long lTime) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lMeasureCount = pMusicalScoreFrame->GetMeasureInfoCount ();
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ ASSERT (0 <= lMeasure && lMeasure < lMeasureCount);
+ long j;
+ for (j = 0; j < lMeasureCount - 1; j++) {
+ if (pMusicalScoreFrame->GetMeasureTime (j + 1) > lTime) {
+ break;
+ }
+ }
+ long lMeasureTime = pMusicalScoreFrame->GetMeasureTime (j);
+ long lDeltaTime = lTime - lMeasureTime;
+ ASSERT (lDeltaTime >= 0);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ VERIFY (pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (j));
+
+ return
+ pMeasureInfo->m_lLeftPrint +
+ pMeasureInfo->m_lSignatureWidthPrint +
+ pMeasureInfo->m_lPreWidthPrint +
+ pMeasureInfo->m_lWidthPrint * lDeltaTime / pMeasureInfo->m_lDuration;
+}
+
+// 小節をx座標[pixel]に変換(小節境界線位置)
+long CMusicalScorePrintView::MeasuretoX (long lMeasure) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ long lMeasureInfoCount = pMusicalScoreFrame->GetMeasureInfoCount ();
+ ASSERT (0 <= lMeasure && lMeasure < lMeasureInfoCount);
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ VERIFY (pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lMeasure));
+ return pMeasureInfo->m_lLeftPrint;
+}
+
+// 小節をx座標[pixel]に変換(小節境界線+拍子調整記号位置)
+long CMusicalScorePrintView::MeasuretoX2 (long lMeasure) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ long lMeasureInfoCount = pMusicalScoreFrame->GetMeasureInfoCount ();
+ ASSERT (0 <= lMeasure && lMeasure < lMeasureInfoCount);
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ VERIFY (pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lMeasure));
+ return (pMeasureInfo->m_lLeftPrint + pMeasureInfo->m_lSignatureWidthPrint);
+}
+
+
+// おたまじゃくしを描画する
+void CMusicalScorePrintView::DrawTadpole
+ (CDC* pDC, long x, long y, long rx, long ry, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ if (lFlags & 0x00010000) {
+ pt[0].x = ptCenter.x + rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y + ry / 2;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y + ry;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y + ry;
+ pt[4].x = ptCenter.x - rx;
+ pt[4].y = ptCenter.y;
+ pt[5].x = ptCenter.x - rx;
+ pt[5].y = ptCenter.y - ry / 2;
+ pt[6].x = ptCenter.x - rx / 2;
+ pt[6].y = ptCenter.y - ry;
+ pt[7].x = ptCenter.x;
+ pt[7].y = ptCenter.y - ry;
+ pt[8].x = ptCenter.x + rx;
+ pt[8].y = ptCenter.y;
+ pDC->Polyline (pt, 9); // 白玉
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y + ry;
+ pt[1].x = ptCenter.x - rx / 2;
+ pt[1].y = ptCenter.y + ry;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y + ry / 2;
+ pt[3].x = ptCenter.x - rx;
+ pt[3].y = ptCenter.y;
+ pDC->Polygon (pt, 4); // 黒縁
+ pt[0].x = ptCenter.x + rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry / 2;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y - ry;
+ pDC->Polygon (pt, 4); // 黒縁
+ }
+ else {
+ pt[0].x = ptCenter.x + rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y + ry / 2;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y + ry;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y + ry;
+ pt[4].x = ptCenter.x - rx;
+ pt[4].y = ptCenter.y;
+ pt[5].x = ptCenter.x - rx;
+ pt[5].y = ptCenter.y - ry / 2;
+ pt[6].x = ptCenter.x - rx / 2;
+ pt[6].y = ptCenter.y - ry;
+ pt[7].x = ptCenter.x;
+ pt[7].y = ptCenter.y - ry;
+ pt[8].x = ptCenter.x + rx;
+ pt[8].y = ptCenter.y;
+ pDC->Polygon (pt, 8); // 黒玉
+ }
+
+}
+
+
+
+// ト音記号を描画する
+void CMusicalScorePrintView::DrawGClef
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[21];
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y - ry;
+ pt[1].x = ptCenter.x - rx;
+ pt[1].y = ptCenter.y;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y + ry;
+ pt[3].x = ptCenter.x + rx;
+ pt[3].y = ptCenter.y + ry;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y - ry;
+ pt[6].x = ptCenter.x + rx;
+ pt[6].y = ptCenter.y - ry * 2;
+ pt[7].x = ptCenter.x - rx * 1;
+ pt[7].y = ptCenter.y - ry * 2;
+ pt[8].x = ptCenter.x - rx * 2;
+ pt[8].y = ptCenter.y - ry;
+ pt[9].x = ptCenter.x - rx * 2;
+ pt[9].y = ptCenter.y + ry;
+ pt[10].x = ptCenter.x;
+ pt[10].y = ptCenter.y + ry * 4;
+ pt[11].x = ptCenter.x + rx * 1;
+ pt[11].y = ptCenter.y + ry * 5;
+ pt[12].x = ptCenter.x + rx * 1;
+ pt[12].y = ptCenter.y + ry * 8;
+ pt[13].x = ptCenter.x;
+ pt[13].y = ptCenter.y + ry * 6;
+ pt[14].x = ptCenter.x;
+ pt[14].y = ptCenter.y + ry * 4;
+ pt[15].x = ptCenter.x + rx;
+ pt[15].y = ptCenter.y - ry * 4;
+ pt[16].x = ptCenter.x;
+ pt[16].y = ptCenter.y - ry * 5;
+ pt[17].x = ptCenter.x - rx * 1 / 2;
+ pt[17].y = ptCenter.y - ry * 5;
+ pDC->Polyline (pt, 18);
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y + ry;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y + ry;
+ pt[3].x = ptCenter.x + rx * 2;
+ pt[3].y = ptCenter.y;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y + ry;
+ pt[5].x = ptCenter.x + rx;
+ pt[5].y = ptCenter.y + ry * 2;
+ pt[6].x = ptCenter.x;
+ pt[6].y = ptCenter.y + ry * 2;
+ pt[7].x = ptCenter.x - rx;
+ pt[7].y = ptCenter.y + ry;
+ pDC->Polygon (pt, 8);
+ pt[0].x = ptCenter.x - rx * 2;
+ pt[0].y = ptCenter.y + ry * 1;
+ pt[1].x = ptCenter.x - rx * 2;
+ pt[1].y = ptCenter.y + ry * 2;
+ pt[2].x = ptCenter.x + rx * 1;
+ pt[2].y = ptCenter.y + ry * 6;
+ pt[3].x = ptCenter.x + rx * 1;
+ pt[3].y = ptCenter.y + ry * 5;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y + ry * 6;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y + ry * 7;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y + ry * 8;
+ pt[3].x = ptCenter.x + rx;
+ pt[3].y = ptCenter.y + ry * 7;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x - rx * 1;
+ pt[0].y = ptCenter.y - ry * 9 / 2;
+ pt[1].x = ptCenter.x - rx * 1 / 2;
+ pt[1].y = ptCenter.y - ry * 4;
+ pt[2].x = ptCenter.x;
+ pt[2].y = ptCenter.y - ry * 9 / 2;
+ pt[3].x = ptCenter.x - rx * 1 / 2;
+ pt[3].y = ptCenter.y - ry * 5;
+ pDC->Polygon (pt, 4);
+}
+
+// ヘ音記号を描画する
+void CMusicalScorePrintView::DrawFClef
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x - rx * 2;
+ pt[1].y = ptCenter.y;
+ pt[2].x = ptCenter.x - rx * 2;
+ pt[2].y = ptCenter.y + ry;
+ pt[3].x = ptCenter.x - rx;
+ pt[3].y = ptCenter.y + ry * 2;
+ pt[4].x = ptCenter.x + rx;
+ pt[4].y = ptCenter.y + ry * 2;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y + ry;
+ pt[6].x = ptCenter.x + rx * 2;
+ pt[6].y = ptCenter.y - ry;
+ pt[7].x = ptCenter.x;
+ pt[7].y = ptCenter.y - ry * 4;
+ pt[8].x = ptCenter.x - rx * 2;
+ pt[8].y = ptCenter.y - ry * 6;
+ pDC->Polyline (pt, 9);
+ pt[0].x = ptCenter.x - rx * 2;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x - rx * 3 / 2;
+ pt[1].y = ptCenter.y + ry * 1 / 2;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y;
+ pt[3].x = ptCenter.x - rx * 3 / 2;
+ pt[3].y = ptCenter.y - ry * 1 / 2;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y + ry * 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y + ry * 1;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y - ry * 1;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y - ry * 4;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y - ry * 1;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y + ry * 1;
+ pt[6].x = ptCenter.x + rx * 1;
+ pt[6].y = ptCenter.y + ry * 2;
+ pDC->Polygon (pt, 7);
+ pt[0].x = ptCenter.x + rx * 3 + rx / 2;
+ pt[0].y = ptCenter.y + ry * 1;
+ pt[1].x = ptCenter.x + rx * 3;
+ pt[1].y = ptCenter.y + ry * 1 + ry / 2;
+ pt[2].x = ptCenter.x + rx * 3 - rx / 2;
+ pt[2].y = ptCenter.y + ry * 1;
+ pt[3].x = ptCenter.x + rx * 3;
+ pt[3].y = ptCenter.y + ry * 1 - ry / 2;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x + rx * 3 + rx / 2;
+ pt[0].y = ptCenter.y - ry * 1;
+ pt[1].x = ptCenter.x + rx * 3;
+ pt[1].y = ptCenter.y - ry * 1 + ry / 2;
+ pt[2].x = ptCenter.x + rx * 3 - ry / 2;
+ pt[2].y = ptCenter.y - ry * 1;
+ pt[3].x = ptCenter.x + rx * 3;
+ pt[3].y = ptCenter.y - ry * 1 - ry / 2;
+ pDC->Polygon (pt, 4);
+}
+
+// ♭の描画
+void CMusicalScorePrintView::DrawFlat
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y + ry;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y + ry;
+ pt[3].x = ptCenter.x + rx / 2;
+ pt[3].y = ptCenter.y;
+ pt[4].x = ptCenter.x - rx / 2;
+ pt[4].y = ptCenter.y - ry;
+ pt[5].x = ptCenter.x - rx / 2;
+ pt[5].y = ptCenter.y + ry * 4;
+ pDC->Polyline (pt, 6);
+}
+
+// #の描画
+void CMusicalScorePrintView::DrawSharp
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y - ry - ry / 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry + ry / 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y + ry - ry / 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y + ry + ry / 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y + ry * 2;
+ pt[1].x = ptCenter.x - rx / 2;
+ pt[1].y = ptCenter.y - ry * 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x + rx / 2;
+ pt[0].y = ptCenter.y + ry * 2;
+ pt[1].x = ptCenter.x + rx / 2;
+ pt[1].y = ptCenter.y - ry * 2;
+ pDC->Polyline (pt, 2);
+};
+
+// ナチュラルの描画
+void CMusicalScorePrintView::DrawNatural
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y + ry * 2;
+ pt[1].x = ptCenter.x - rx / 2;
+ pt[1].y = ptCenter.y - ry;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y - ry * 3 / 4;
+ pDC->Polyline (pt, 3);
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y + ry * 3 / 4;
+ pt[1].x = ptCenter.x + rx / 2;
+ pt[1].y = ptCenter.y + ry;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y - ry * 2;
+ pDC->Polyline (pt, 3);
+};
+
+// 水平補助線を描画する
+void CMusicalScorePrintView::DrawHorzAuxiliaryLine
+ (CDC* pDC, long x, long y, long r, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[2];
+ pt[0].x = ptCenter.x - r;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + r;
+ pt[1].y = ptCenter.y;
+ pDC->Polyline (pt, 2);
+}
+
+// 付点を描画する
+void CMusicalScorePrintView::DrawDot
+ (CDC* pDC, long x, long y, long rx, long ry, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x = x + rx * 2;
+ ptCenter.y = y + ry / 2;
+ POINT pt[4];
+ pt[0].x = ptCenter.x - 1;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y + 1;
+ pt[2].x = ptCenter.x + 1;
+ pt[2].y = ptCenter.y;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y - 1;
+ pDC->Polygon (pt, 4);
+
+}
+
+// 半タイを描画する
+void CMusicalScorePrintView::DrawTieHalf
+ (CDC* pDC, long x1, long x2, long y, long rx, long ry, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x;
+ ptCenter.y;
+ POINT pt[3];
+ pt[0].x = (x2 > x1 ? x1 + rx * 1 : x1 - rx * 1);
+ pt[0].y = y - ry * 1;
+ pt[1].x = (x2 > x1 ? x1 + rx * 2 : x1 - rx * 2);
+ pt[1].y = y - ry * 2;
+ pt[2].x = x2;
+ pt[2].y = y - ry * 2;
+ pDC->Polyline (pt, 3);
+
+}
+
+// 縦棒を描画する
+void CMusicalScorePrintView::DrawPole (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[2];
+ pt[0].x = x1 + rx;
+ pt[0].y = y1;
+ pt[1].x = x1 + rx;
+ pt[1].y = y2;
+ pDC->Polyline (pt, 2);
+}
+
+// 単一旗を描画する
+void CMusicalScorePrintView::DrawSingleFlag (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[4];
+ pt[0].x = x1 + rx;
+ pt[0].y = y2;
+ pt[1].x = x1 + rx * 3;
+ pt[1].y = y2 - ry * 2;
+ pt[2].x = x1 + rx * 3;
+ pt[2].y = y2 - ry * 3;
+ pt[3].x = x1 + rx;
+ pt[3].y = y2 - ry;
+ pDC->Polygon (pt, 4);
+ pt[0].x = x1 + rx * 3;
+ pt[0].y = y2 - ry * 3;
+ pt[1].x = x1 + rx;
+ pt[1].y = y2 - ry * 5;
+ pDC->Polyline (pt, 2);
+}
+
+// 連続旗を描画する
+void CMusicalScorePrintView::DrawChainedFlag (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[4];
+ pt[0].x = x1 + rx;
+ pt[0].y = y2;
+ pt[1].x = x2 + rx;
+ pt[1].y = y2;
+ pt[2].x = x2 + rx;
+ pt[2].y = y2 - ry;
+ pt[3].x = x1 + rx;
+ pt[3].y = y2 - ry;
+ pDC->Polygon (pt, 4);
+}
+
+// 3連符号を描画する(20110905追加)
+void CMusicalScorePrintView::DrawTripletSign (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[3];
+ pt[0].x = x1;
+ pt[0].y = y2;
+ pt[1].x = x1;
+ pt[1].y = y1;
+ pt[2].x = (x1 + x2) / 2 - 15;
+ pt[2].y = y1;
+ pDC->Polyline (pt, 3);
+ pt[0].x = (x1 + x2) / 2 + 15;
+ pt[0].y = y1;
+ pt[1].x = x2;
+ pt[1].y = y1;
+ pt[2].x = x2;
+ pt[2].y = y2;
+ pDC->Polyline (pt, 3);
+ CRect rcText ((x1 + x2) / 2 - 15, y1 - 15, (x1 + x2) / 2 + 15, y1 + 15);
+ CString strText;
+ strText.Format (_T("%d"), (lFlags & 0x000000FF));
+ pDC->DrawText (strText, &rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+}
+
+// 音符を描画する
+void CMusicalScorePrintView::DrawNote
+ (CDC* pDC, long lTrackIndex, MusicalScoreNoteInfo* pNoteInfo, long lFlags) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDIEvent* pNoteEvent = pNoteInfo->m_pNoteOnEvent;
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ ASSERT (0 <= lTrackIndex && lTrackIndex < pMusicalScoreFrame->GetTrackInfoCount ());
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackIndex));
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long lKey = MIDIEvent_GetKey (pNoteEvent);
+ long lDuration = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ long lNoteOnMeasure = pNoteInfo->m_lNoteOnMeasure;
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ ASSERT (0 <= lNoteOnMeasure && lNoteOnMeasure < pMusicalScoreFrame->GetMeasureInfoCount ());
+ VERIFY (pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lNoteOnMeasure));
+ long lKeySignature = pMeasureInfo->m_lKeySignature; // この小節の調性記号
+ long lTimeSignature = pMeasureInfo->m_lTimeSignature; // この小節の拍子記号
+ long lLineNo = pMusicalScoreFrame->KeytoLineNo (lKey, lKeySignature);
+ long lSF = pMusicalScoreFrame->KeytoSF (lKey, lKeySignature);
+ long lnn = lTimeSignature & 0xFF;
+ long ldd = (lTimeSignature & 0xFF00) >> 8;
+
+ long x = this->TimetoX (pNoteInfo->m_lNoteOnTime);
+ long y = 0;
+ long rx = 8;
+ long ry = 8;
+ long i = 0;
+
+ // 水平補助線の描画
+ switch (lTrackFlags & 0x0000000F) {
+ case 1: // ト音記号
+ if (lLineNo >= 47) {
+ for (i = 47; i <= lLineNo; i += 2) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ else if (lLineNo <= 35) {
+ for (i = 35; i >= lLineNo; i -= 2) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ break;
+ case 2: // ヘ音記号
+ if (lLineNo >= 35) {
+ for (i = 35; i <= lLineNo; i += 2) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ else if (lLineNo <= 23) {
+ for (i = 23; i >= lLineNo; i -= 2) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ break;
+ case 3: // 大譜表
+ if (lLineNo >= 47) {
+ for (i = 47; i <= lLineNo; i += 2) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ else if (lLineNo == 35) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, 35);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ else if (lLineNo <= 23) {
+ for (i = 23; i >= lLineNo; i -= 2) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ break;
+ }
+ // 臨時記号の描画
+ y = this->TrackIndexLineNotoY (lTrackIndex, lLineNo);
+ switch (lSF) {
+ case 0:
+ break;
+ case 2:
+ DrawFlat (pDC, x - 4 * rx, y, rx, ry);
+ DrawFlat (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 3:
+ DrawFlat (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 4:
+ DrawNatural (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 5:
+ DrawSharp (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 6:
+ DrawSharp (pDC, x - 2 * rx, y, rx, ry);
+ DrawSharp (pDC, x - 4 * rx, y, rx, ry);
+ break;
+ }
+
+
+ // おたまじゃくしの描画
+ y = this->TrackIndexLineNotoY (lTrackIndex, lLineNo);
+ long lFlags2 = 0;
+ if (lDuration >= lTimeResolution * 2) {
+ lFlags2 |= 0x00010000; // 白丸
+ }
+ if (lDuration < lTimeResolution * lnn * 4 / ldd) {
+ lFlags2 |= 0x00100000; // 縦線あり
+ }
+ DrawTadpole (pDC, x, y, rx, ry, lFlags2);
+
+ // 付点の描画
+ if (lDuration == lTimeResolution * 3 ||
+ lDuration == lTimeResolution * 3 / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution * 3 / 8) {
+ DrawDot (pDC, x, y, rx, ry, lFlags2);
+ }
+
+ // 半タイの描画
+ long x2 = 0;
+ long lPreWidth = 0;
+ long lPostWidth = 0;
+ switch (pNoteInfo->m_lFlags & 0x0000000F) {
+ case 1: // ♪_
+ x2 = this->TimetoX (pNoteInfo->m_lNoteOffTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 2: // _♪
+ x2 = this->TimetoX (pNoteInfo->m_lNoteOnTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 3: // _♪_
+ x2 = this->TimetoX (pNoteInfo->m_lNoteOffTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = this->TimetoX (pNoteInfo->m_lNoteOnTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 4: // ♪_|
+ x2 = this->MeasuretoX (pNoteInfo->m_lNoteOffMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 5: // |_♪
+ x2 = this->MeasuretoX (pNoteInfo->m_lNoteOnMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 6: // _♪_|
+ x2 = this->TimetoX (pNoteInfo->m_lNoteOnTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = this->MeasuretoX (pNoteInfo->m_lNoteOffMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 7: // |_♪_
+ x2 = this->MeasuretoX (pNoteInfo->m_lNoteOnMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = this->TimetoX (pNoteInfo->m_lNoteOffTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 8: // |_全音符_|
+ x2 = this->MeasuretoX (pNoteInfo->m_lNoteOnMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = this->MeasuretoX (pNoteInfo->m_lNoteOffMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ }
+
+ // 棒の描画
+ long lPoleKey = lKey;
+ MusicalScoreNoteGroupInfo* pNoteGroupInfo = (MusicalScoreNoteGroupInfo*)(pNoteInfo->m_pNoteGroupInfo);
+ if (pNoteGroupInfo) { // 旗つきの場合
+ lPoleKey = pNoteGroupInfo->m_lMaxKey;
+ }
+ long lLineNo2 = pMusicalScoreFrame->KeytoLineNo (lPoleKey, lKeySignature);
+ long y2 = this->TrackIndexLineNotoY (lTrackIndex, lLineNo2);
+ if (lDuration < lTimeResolution * 4) {
+ DrawPole (pDC, x, x2, y, y2 + ry * 7, rx, ry, lFlags2);
+ }
+
+ // 旗の描画
+ if (lDuration < lTimeResolution && lDuration != lTimeResolution * 2 / 3) {
+ // グループ内の音符の時刻が単一の場合
+ if (pNoteGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime == pNoteGroupInfo->m_pLastNoteInfo->m_lNoteOnTime) {
+ // 8分音符、付点8分音符、3連8分音符、16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution / 3 ||
+ lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawSingleFlag (pDC, x, x2, y, y2 + ry * 7, rx, ry, lFlags2);
+ }
+ // 16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawSingleFlag (pDC, x, x2, y, y2 + ry * 5, rx, ry, lFlags2);
+ }
+ // 32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawSingleFlag (pDC, x, x2, y, y2 + ry * 3, rx, ry, lFlags2);
+ }
+ }
+ // グループ内の音符が複数の時刻にまたがる場合
+ else {
+ long x1[3]; // 連旗左座標[1段目,2段目,3段目]
+ long x2[3]; // 連旗右座標[1段目,2段目,3段目]
+ // グループ内の最初の時刻の音符である場合
+ if (pNoteGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime == pNoteInfo->m_lNoteOnTime) {
+ x1[0] = x1[1] = x1[2] = x;
+ x2[0] = x2[1] = x2[2] = this->TimetoX (pNoteInfo->m_lNoteOffTime - lTimeResolution / 8);
+ }
+ // グループ内の最後の時刻の音符である場合
+ else if (pNoteGroupInfo->m_pLastNoteInfo->m_lNoteOnTime == pNoteInfo->m_lNoteOnTime) {
+ x1[0] = x1[1] = x1[2] = this->TimetoX (pNoteInfo->m_lNoteOnTime - lTimeResolution / 8);
+ x2[0] = x2[1] = x2[2] = x;
+ }
+ // グループ内の途中の時刻の音符である場合
+ else {
+ x1[0] = x1[1] = x1[2] = this->TimetoX (pNoteInfo->m_lNoteOnTime - lTimeResolution / 8);
+ x2[0] = x2[1] = x2[2] = this->TimetoX (pNoteInfo->m_lNoteOffTime - lTimeResolution / 8);
+ // 前の時刻の音符を取得
+ MusicalScoreNoteInfo* pPrevNoteInfo = pNoteInfo;
+ long lPrevDuration = 0;
+ while (pPrevNoteInfo) {
+ if (pPrevNoteInfo->m_lNoteOnTime < pNoteInfo->m_lNoteOnTime) {
+ break;
+ }
+ pPrevNoteInfo = pPrevNoteInfo->m_pPrevNoteInfo;
+ }
+ if (pPrevNoteInfo && pPrevNoteInfo->m_pNoteGroupInfo == pNoteGroupInfo) {
+ lPrevDuration = pPrevNoteInfo->m_lNoteOffTime - pPrevNoteInfo->m_lNoteOnTime;
+ }
+ // 次の時刻の音符を取得
+ MusicalScoreNoteInfo* pNextNoteInfo = pNoteInfo;
+ long lNextDuration = 0;
+ while (pNextNoteInfo) {
+ if (pNextNoteInfo->m_lNoteOnTime > pNoteInfo->m_lNoteOnTime) {
+ break;
+ }
+ pNextNoteInfo = pNextNoteInfo->m_pNextNoteInfo;
+ }
+ if (pNextNoteInfo && pNextNoteInfo->m_pNoteGroupInfo == pNoteGroupInfo) {
+ lNextDuration = pNextNoteInfo->m_lNoteOffTime - pNextNoteInfo->m_lNoteOnTime;
+ }
+ // 1段目の連旗取り消し
+ if (lDuration == lTimeResolution / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution / 3 ||
+ lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ if (lNextDuration == 0) {
+ x2[0] = x;
+ }
+ else if (lPrevDuration == 0) {
+ x1[0] = x;
+ }
+ }
+ // 2段目の連旗取り消し
+ if (lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ if (lNextDuration >= lDuration * 2) {
+ x2[1] = x;
+ }
+ else if (lPrevDuration >= lDuration * 2) {
+ x1[1] = x;
+ }
+ }
+ // 3段目の連旗取り消し
+ if (lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ if (lNextDuration >= lDuration * 2) {
+ x2[2] = x;
+ }
+ else if (lPrevDuration >= lDuration * 2) {
+ x1[2] = x;
+ }
+ }
+ }
+ // 連旗1段目
+ // 8分音符、付点8分音符、3連8分音符、16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution / 3 ||
+ lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawChainedFlag (pDC, x1[0], x2[0], y, y2 + ry * 7, rx, ry, lFlags2);
+ }
+ // 連旗2段目描画
+ // 16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawChainedFlag (pDC, x1[1], x2[1], y, y2 + ry * 5, rx, ry, lFlags2);
+ }
+ // 連旗3段目描画
+ // 32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawChainedFlag (pDC, x1[2], x2[2], y, y2 + ry * 3, rx, ry, lFlags2);
+ }
+ }
+ }
+
+ // 3連符号の描画(20110905追加)
+ if (pNoteInfo->m_pTripletGroupInfo) {
+ MusicalScoreTripletGroupInfo* pTripletGroupInfo =
+ (MusicalScoreTripletGroupInfo*)(pNoteInfo->m_pTripletGroupInfo);
+ if (pTripletGroupInfo->m_pFirstNoteInfo == pNoteInfo) {
+ long x1 = this->TimetoX (pTripletGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime);
+ long x2 = this->TimetoX (pTripletGroupInfo->m_pLastNoteInfo->m_lNoteOnTime);
+ long lMinLineNo = pMusicalScoreFrame->KeytoLineNo (pTripletGroupInfo->m_lMinKey, lKeySignature);
+ long y = this->TrackIndexLineNotoY (lTrackIndex, lMinLineNo);
+ long n12 = 12 * lTimeResolution / pTripletGroupInfo->m_lMinDur; // 12 * 3 or 12 * 6 or 12 * 12
+ long lSpan = pTripletGroupInfo->m_lEndTime - pTripletGroupInfo->m_lBeginTime;
+ if (lSpan >= 1) {
+ if (12 * lTimeResolution / lSpan >= 1) {
+ n12 /= (12 * lTimeResolution / lSpan);
+ }
+ else {
+ n12 /= 12;
+ }
+ }
+ else {
+ n12 /= 12;
+ }
+ DrawTripletSign (pDC, x1, x2, y - 4 * ry, y - 3 * ry, rx, ry, n12);
+ }
+ }
+
+}
+
+
+
+// 拍子記号・調性記号の描画
+void CMusicalScorePrintView::DrawTimeAndKeySignature
+ (CDC* pDC, long lTrackIndex, long lTime) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (0 <= lTrackIndex && lTrackIndex < pMusicalScoreFrame->GetTrackInfoCount ());
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackIndex));
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long lMeasure, lBeat, lTick;
+ long x;
+ if (lTime >= 0) {
+ MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ x = this->MeasuretoX (lMeasure);
+ }
+ else {
+ x = 120;
+ }
+ long y;
+ long rx = 8;
+ long ry = 8;
+ long lGCrefSharpLineNo[7] = {45, 42, 46, 43, 40, 44, 41};
+ long lFCrefSharpLineNo[7] = {31, 28, 32, 29, 33, 30, 34};
+ long lGCrefFlatLineNo[7] = {41, 44, 40, 43, 39, 42, 38};
+ long lFCrefFlatLineNo[7] = {27, 30, 26, 29, 25, 28, 24};
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lTime, &lsf, &lmi);
+ long lnn, ldd, lcc, lbb;
+ MIDIData_FindTimeSignature (pMIDIData, lTime, &lnn, &ldd, &lcc, &lbb);
+ CString strText1;
+ CString strText2;
+ strText1.Format (_T("%d"), lnn);
+ strText2.Format (_T("%d"), (1 << ldd));
+ CRect rcText1 (x + rx * 10 + rx * 2 * abs(lsf), 0, x + rx * 10 + rx * 2 * abs(lsf) + 24, 0);
+ CRect rcText2 (x + rx * 10 + rx * 2 * abs(lsf), 0, x + rx * 10 + rx * 2 * abs(lsf) + 24, 0);
+ long j;
+ switch (lTrackFlags & 0x0000000F) {
+ case 1: // ト音記号
+ y = this->TrackIndexLineNotoY (lTrackIndex, 39);
+ DrawGClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lGCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lGCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = this->TrackIndexLineNotoY (lTrackIndex, 41);
+ rcText1.top = y + ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y - ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ case 2: // ヘ音記号
+ y = this->TrackIndexLineNotoY (lTrackIndex, 31);
+ DrawFClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lFCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lFCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = this->TrackIndexLineNotoY (lTrackIndex, 29);
+ rcText1.top = y + ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y - ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ case 3: // 大譜表
+ y = this->TrackIndexLineNotoY (lTrackIndex, 39);
+ DrawGClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lGCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lGCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = this->TrackIndexLineNotoY (lTrackIndex, 41);
+ rcText1.top = y + ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y - ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+
+ y = this->TrackIndexLineNotoY (lTrackIndex, 31);
+ DrawFClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lFCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = this->TrackIndexLineNotoY (lTrackIndex, lFCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = this->TrackIndexLineNotoY (lTrackIndex, 29);
+ rcText1.top = y + ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y - ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ }
+}
+
+
+
+
+// 指定時刻にフラグとテキストを描画
+void CMusicalScorePrintView::DrawFlagAndText
+(CDC* pDC, long lTime, LPCTSTR lpszText, long lColor) {
+ long x = TimetoX (lTime);
+ CRect rcBack (x, MUSICALSCOREPRINTVIEW_SCALEHEIGHT / 2, x + 1024, MUSICALSCOREPRINTVIEW_SCALEHEIGHT);
+ CRect rcFlag (x, MUSICALSCOREPRINTVIEW_SCALEHEIGHT * 6 / 10, x + 20, MUSICALSCOREPRINTVIEW_SCALEHEIGHT * 9 / 10);
+ CRect rcText (x + 30, MUSICALSCOREPRINTVIEW_SCALEHEIGHT / 2, x + 1024, MUSICALSCOREPRINTVIEW_SCALEHEIGHT);
+ CPen pen;
+ pen.CreatePen (PS_SOLID, 1, lColor);
+ CPen* pOldPen = pDC->SelectObject (&pen);
+ pDC->FillSolidRect (&rcBack, ::GetSysColor (COLOR_BTNFACE));
+ pDC->FillSolidRect (&rcFlag, lColor);
+ pDC->MoveTo (x, MUSICALSCOREPRINTVIEW_SCALEHEIGHT * 5 / 10);
+ pDC->LineTo (x, MUSICALSCOREPRINTVIEW_SCALEHEIGHT * 9 / 10);
+ pDC->SetBkMode (TRANSPARENT);
+ long lOldColor = pDC->GetTextColor ();
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->SetTextColor (lColor);
+ pDC->DrawText (lpszText, rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ pDC->SetTextColor (lOldColor);
+ pDC->SelectObject (pOldFont);
+ pDC->SelectObject (pOldPen);
+}
+
+
+// トラック番号部描画
+void CMusicalScorePrintView::DrawTrackScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pTempTrack = NULL;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ long lTopMargin = MUSICALSCOREPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = MUSICALSCOREPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = MUSICALSCOREPRINTVIEW_SCALEHEIGHT;
+ long lTrackHeight = (m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin);
+
+ CFont* pOldFont = NULL;
+ pDC->SetBkMode (TRANSPARENT);
+ long lVisibleTopTrack = 0;
+ long lVisibleBottomTrack = MIDIData_CountTrack (pMIDIData);
+ long rx = 8;
+ long ry = 8;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ long i = 0;
+
+ // ボタン部描画
+ i = 0;
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ pOldFont = pDC->SelectObject (&(this->m_theFont));
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long x1 = 0;
+ long x2 = 100;
+ long y1 = lTrackHeight * m_lMaxRowPage - pTrackInfo->m_lTopPrint;
+ long y2 = lTrackHeight * m_lMaxRowPage - (pTrackInfo->m_lTopPrint + pTrackInfo->m_lHeightPrint);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lColorBtnFace);
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i + (bTrackZeroOrigin ? 0 : 1));
+ pDC->DrawText (szBuf, -1, &rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldFont);
+
+ // 背景の描画
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long x1 = 0;
+ long x2 = MUSICALSCOREPRINTVIEW_SCALEWIDTH;
+ long y1 = lTrackHeight * m_lMaxRowPage - pTrackInfo->m_lTopPrint;
+ long y2 = lTrackHeight * m_lMaxRowPage - (pTrackInfo->m_lTopPrint + pTrackInfo->m_lHeightPrint);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+ }
+ }
+ i++;
+ }
+
+ // 五線描画
+ i = 0;
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen* pOldPen = pDC->SelectObject (&penKey);
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lTrackTopPrint = pTrackInfo->m_lTopPrint;
+ long lTrackHeightPrint = pTrackInfo->m_lHeightPrint;
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long yc = (lTrackTopPrint + lTrackHeightPrint / 2);
+ long ii;
+ long y;
+ switch (lTrackFlags & 0x0000000F) {
+ case 0:
+ break;
+ case 1: // ト音記号
+ case 2: // ヘ音記号
+ for (ii = -2; ii <= 2; ii++) {
+ y = lTrackHeight * m_lMaxRowPage - (yc + ii * 2 * ry);
+ pDC->MoveTo (120, y);
+ pDC->LineTo (MUSICALSCOREPRINTVIEW_SCALEWIDTH, y);
+ }
+ break;
+ case 3: // 大譜表
+ for (ii = -5; ii <= -1; ii++) {
+ y = lTrackHeight * m_lMaxRowPage - (yc + ii * 2 * ry);
+ pDC->MoveTo (120, y);
+ pDC->LineTo (MUSICALSCOREPRINTVIEW_SCALEWIDTH, y);
+ }
+ for (ii = 1; ii <= 5; ii++) {
+ y = lTrackHeight * m_lMaxRowPage - (yc + ii * 2 * ry);
+ pDC->MoveTo (120, y);
+ pDC->LineTo (MUSICALSCOREPRINTVIEW_SCALEWIDTH, y);
+ }
+ break;
+ }
+ // 大譜表縦線描画
+ long y1, y2;
+ switch (lTrackFlags & 0x0000000F) {
+ case 3:
+ y1 = lTrackHeight * m_lMaxRowPage - (yc - 10 * ry);
+ y2 = lTrackHeight * m_lMaxRowPage - (yc + 10 * ry);
+ pDC->FillSolidRect
+ (120 - 2, y1, 2, y2 - y1 + 1, RGB (192, 192, 192));
+ pDC->FillSolidRect
+ (120 - 10, y1, 5, y2 - y1 + 1, RGB (192, 192, 192));
+ }
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldPen);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 譜面ロール部描画
+void CMusicalScorePrintView::DrawTrackTimeView (CDC* pDC, CPrintInfo* pInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long lCurRowPage = lCurPage % m_lMaxRowPage;
+ long lCurRollPage = lCurPage / m_lMaxRowPage;
+
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[1]);
+ CPen penBeat (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen penOctave (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[1]);
+
+ CFont* pOldFont = NULL;
+ pDC->SetBkMode (TRANSPARENT);
+ long lTopMargin = MUSICALSCOREPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = MUSICALSCOREPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = MUSICALSCOREPRINTVIEW_SCALEHEIGHT;
+ long lTrackHeight = m_sizLogPaper.cy - lTopMargin - lBottomMargin - lScaleHeight;
+ long x, y, lTime;
+ long lVisibleLeftMeasure = m_theRollPageInfoArray.GetAt (lCurRollPage);
+ long lVisibleRightMeasure = m_theRollPageInfoArray.GetAt (lCurRollPage + 1);
+ long lVisibleLeftTime = 0;
+ long lVisibleRightTime = 0;
+ MIDIData_MakeTime (pMIDIData, lVisibleLeftMeasure, 0, 0, &lVisibleLeftTime);
+ MIDIData_MakeTime (pMIDIData, lVisibleRightMeasure, 0, 0, &lVisibleRightTime);
+ long lVisibleTopTrack = m_theRowPageInfoArray.GetAt (lCurRowPage);
+ long lVisibleBottomTrack = m_theRowPageInfoArray.GetAt (lCurRowPage + 1);
+ long lnn, ldd, lcc, lbb;
+ long lUnitTick;
+
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ long i, j;
+
+ // 背景の描画
+ i = 0;
+ long lMeasureInfoCount = pMusicalScoreFrame->GetMeasureInfoCount ();
+ x = this->MeasuretoX (lMeasureInfoCount - 1);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long x1 = 0;
+ long x2 = x;
+ long y1 = lTrackHeight * m_lMaxRowPage - pTrackInfo->m_lTopPrint;
+ long y2 = lTrackHeight * m_lMaxRowPage - (pTrackInfo->m_lTopPrint + pTrackInfo->m_lHeightPrint);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+ }
+ }
+ i++;
+ }
+
+ //トラック名描画
+ i = 0;
+ pOldFont = pDC->SelectObject (&this->m_theFont);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreMeasureInfo* pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lVisibleLeftMeasure);
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lColor = MIDITrack_GetForeColor (pMIDITrack);
+ pDC->SetTextColor (lColor);
+ CString strTrackName;
+ strTrackName = GetCellString (i);
+ CRect rcTrackName
+ (pMeasureInfo->m_lLeftPrint,
+ lTrackHeight * m_lMaxRowPage - pTrackInfo->m_lTopPrint,
+ pMeasureInfo->m_lLeftPrint + 1000,
+ lTrackHeight * m_lMaxRowPage - (pTrackInfo->m_lTopPrint + pTrackInfo->m_lHeightPrint));
+ pDC->DrawText (strTrackName, &rcTrackName, DT_TOP | DT_LEFT);
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldFont);
+
+ // 五線の描画
+ CPen* pOldPen = pDC->SelectObject (&penKey);
+ long rx = 8;
+ long ry = 8;
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ ASSERT (0 <= i && i < pMusicalScoreFrame->GetTrackInfoCount ());
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i));
+ long lTrackTopPrint = pTrackInfo->m_lTopPrint;
+ long lTrackHeightPrint = pTrackInfo->m_lHeightPrint;
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long yc = (lTrackTopPrint + lTrackHeightPrint / 2);
+ long ii;
+ switch (lTrackFlags & 0x0000000F) {
+ case 0: // 表示しない
+ break;
+ case 1: // ト音記号
+ case 2: // ヘ音記号
+ for (ii = -2; ii <= 2; ii++) {
+ y = lTrackHeight * m_lMaxRowPage - (yc + ii * 2 * ry);
+ pDC->MoveTo (0, y);
+ pDC->LineTo (x, y);
+ }
+ break;
+ case 3: // 大譜表
+ for (ii = -5; ii <= -1; ii++) {
+ y = lTrackHeight * m_lMaxRowPage - (yc + ii * 2 * ry);
+ pDC->MoveTo (0, y);
+ pDC->LineTo (x, y);
+ }
+ for (ii = 1; ii <= 5; ii++) {
+ y = lTrackHeight * m_lMaxRowPage - (yc + ii * 2 * ry);
+ pDC->MoveTo (0, y);
+ pDC->LineTo (x, y);
+ }
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ // 縦線の描画
+ long lTrackInfoCount = pMusicalScoreFrame->GetTrackInfoCount ();
+ ASSERT (1 <= lTrackInfoCount && lTrackInfoCount < MAXMIDITRACKNUM);
+ MusicalScoreTrackInfo* pLastTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackInfoCount - 1);
+ long lTrackBottom = (pLastTrackInfo->m_lTopPrint + pLastTrackInfo->m_lHeightPrint);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ for (i = lVisibleLeftMeasure; i <= lVisibleRightMeasure; i++) {
+ // 小節線の描画
+ MIDIData_MakeTimeEx (pMIDIData, i, 0, 0, &lTime, &lnn, &ldd, &lcc, &lbb);
+ x = this->MeasuretoX (i);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, lTrackHeight * m_lMaxRowPage - 0);
+ pDC->LineTo (x, lTrackHeight * m_lMaxRowPage - lTrackBottom);
+ // 拍線の描画
+ pDC->SelectObject (&penBeat);
+ lUnitTick = lTimeResolution * 4 / (1 << ldd);
+ for (long j = 0; j < lnn; j++) {
+ x = this->TimetoX (lTime + j * lUnitTick);
+ pDC->MoveTo (x, lTrackHeight * m_lMaxRowPage - 0);
+ pDC->LineTo (x, lTrackHeight * m_lMaxRowPage - lTrackBottom);
+ }
+ }
+ }
+ else {
+ for (i = lVisibleLeftMeasure; i <= lVisibleRightMeasure; i++) {
+ // フレーム境界線の描画
+ lTime = i * lTimeResolution;
+ x = this->TimetoX (lTime);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, 0);
+ pDC->LineTo (x, lTrackHeight);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+
+ // 拍子記号・調性記号の描画(ページ先頭小節用)
+ CPen theTrackPen;
+ CBrush theTrackBrush;
+// pOldFont = pDC->SelectObject (&(pMusicalScoreFrame->m_theTimeMeasureFont));
+ long lMeasure = 0;
+ for (lMeasure = lVisibleLeftMeasure; lMeasure < lVisibleRightMeasure; lMeasure++) {
+ MusicalScoreMeasureInfo* pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lMeasure);
+ // 該当小節の拍子調性記号スペースがある場合
+ if (pMeasureInfo->m_lSignatureWidthPrint > 0) {
+ i = 0;
+ MIDITrack* pTempTrack;
+ MIDIData_MakeTime (pMIDIData, lMeasure, 0, 0, &lTime);
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ long lColor = MIDITrack_GetForeColor (pTempTrack);
+ pDC->SetTextColor (lColor);
+ theTrackPen.CreatePen (PS_SOLID, 1, lColor);
+ theTrackBrush.CreateSolidBrush (lColor);
+ CPen* pOldPen = pDC->SelectObject (&theTrackPen);
+ CBrush* pOldBrush = pDC->SelectObject (&theTrackBrush);
+ DrawTimeAndKeySignature (pDC, i, lTime);
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+ theTrackPen.DeleteObject ();
+ theTrackBrush.DeleteObject ();
+ }
+ i++;
+ }
+ }
+ }
+
+ // 拍子記号・調整記号の描画
+ pMIDITrack = pMIDIData->m_pFirstTrack;
+ if (pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (MIDIEvent_IsTimeSignature (pMIDIEvent) ||
+ MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ if (lVisibleLeftTime <= lTime && lTime <= lVisibleRightTime) {
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ long lMeasureInfoCount = pMusicalScoreFrame->GetMeasureInfoCount ();
+ ASSERT (0 <= lMeasure && lMeasure < lMeasureInfoCount);
+ MusicalScoreMeasureInfo* pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lMeasure);
+ i = 0;
+ MIDITrack* pTempTrack;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ long lColor = MIDITrack_GetForeColor (pTempTrack);
+ pDC->SetTextColor (lColor);
+ theTrackPen.CreatePen (PS_SOLID, 1, lColor);
+ theTrackBrush.CreateSolidBrush (lColor);
+ CPen* pOldPen = pDC->SelectObject (&theTrackPen);
+ CBrush* pOldBrush = pDC->SelectObject (&theTrackBrush);
+ DrawTimeAndKeySignature (pDC, i, lTime);
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+ theTrackPen.DeleteObject ();
+ theTrackBrush.DeleteObject ();
+ }
+ i++;
+ }
+ }
+ }
+ }
+ }
+// pDC->SelectObject (pOldFont);
+
+ // 音符の描画
+ CPen penBar (PS_SOLID, 1, RGB (0, 0, 0));
+ pDC->SelectObject (&penBar);
+ pOldFont = pDC->SelectObject (&(this->m_theFont));
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ long lColor = MIDITrack_GetForeColor (pMIDITrack);
+ pDC->SetTextColor (lColor);
+ CPen theSelectedPen;
+ CBrush theSelectedBrush;
+ theTrackPen.CreatePen (PS_SOLID, 1, lColor);
+ theTrackBrush.CreateSolidBrush (lColor);
+ theSelectedPen.CreatePen (PS_SOLID, 1, RGB (0, 0, 0));
+ theSelectedBrush.CreateSolidBrush (RGB (0, 0, 0));
+ MusicalScoreTrackInfo* pTrackInfo = (MusicalScoreTrackInfo*)(pMusicalScoreFrame->m_theTrackInfoArray.GetAt (i));
+ long jMax = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ for (j = 0; j < jMax; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ MIDIEvent* pNoteEvent = pNoteInfo->m_pNoteOnEvent;
+ if (lVisibleLeftTime <= pNoteInfo->m_lNoteOnTime && pNoteInfo->m_lNoteOnTime <= lVisibleRightTime ||
+ lVisibleRightTime <= pNoteInfo->m_lNoteOffTime && pNoteInfo->m_lNoteOffTime < lVisibleRightTime ||
+ pNoteInfo->m_lNoteOnTime <= lVisibleLeftTime && lVisibleRightTime < pNoteInfo->m_lNoteOffTime) {
+ CPen* pOldPen = pDC->SelectObject (pSekaijuDoc->IsEventSelected (pNoteEvent) ? &theSelectedPen : &theTrackPen);
+ CBrush* pOldBrush = pDC->SelectObject (pSekaijuDoc->IsEventSelected (pNoteEvent) ? & theSelectedBrush : &theTrackBrush);
+ DrawNote (pDC, i, pNoteInfo, 0x00000000);
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+ }
+ }
+ theTrackPen.DeleteObject ();
+ theTrackBrush.DeleteObject ();
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldFont);
+ pDC->SelectObject (pOldPen);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ Sleep (0);
+}
+
+
+// 左上余白部描画
+void CMusicalScorePrintView::DrawScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ // 左上余白部塗りつぶし
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (0, 0, MUSICALSCOREPRINTVIEW_SCALEWIDTH, MUSICALSCOREPRINTVIEW_SCALEHEIGHT, lColorBtnFace);
+}
+
+// 時刻目盛り描画
+void CMusicalScorePrintView::DrawTimeScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long lCurRowPage = lCurPage % m_lMaxRowPage;
+ long lCurRollPage = lCurPage / m_lMaxRowPage;
+
+ long lVisibleLeftMeasure = m_theRollPageInfoArray.GetAt (lCurRollPage);
+ long lVisibleRightMeasure = m_theRollPageInfoArray.GetAt (lCurRollPage + 1);
+
+ // 背景塗りつぶし
+ long lLeftMargin = MUSICALSCOREPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = MUSICALSCOREPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = MUSICALSCOREPRINTVIEW_SCALEWIDTH;
+ long lTimeWidth = m_sizLogPaper.cx - lScaleWidth - lLeftMargin - lRightMargin;
+ pDC->FillSolidRect (0, 0, lTimeWidth * m_lMaxRollPage, MUSICALSCOREPRINTVIEW_SCALEHEIGHT, lColorBtnFace);
+
+ // 時刻ロール部文字
+ pDC->SetBkMode (TRANSPARENT);
+ long lOldTime = 0;
+ CString strText1;
+ CString strText2;
+ pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ if (pMIDITrack) {
+ long lColorTrack1 = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ // テンポ
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ strText1.Format (_T("%1.2lf"), (double)60000000 / (double)lTempo);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 拍子記号
+ else if (MIDIEvent_IsTimeSignature (pMIDIEvent)) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ strText1.Format (_T("%d/%d"), lnn, 1 << ldd);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 調性記号
+ else if (MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ strText1.Format (_T("%d%s"), labs (lsf), lsf >= 0 ? _T("#") : _T("b"));
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // マーカー
+ else if (MIDIEvent_IsMarker (pMIDIEvent)) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIEvent_GetText (pMIDIEvent, szBuf, TSIZEOF (szBuf) - 1);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += szBuf;
+ lOldTime = lTime;
+ }
+ }
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ }
+
+ // 時刻目盛部
+ pDC->SetTextColor (lColorBtnText);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long j;
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ for (j = lVisibleLeftMeasure; j < lVisibleRightMeasure; j++) {
+ long x1 = MeasuretoX (j);
+ long x2 = MeasuretoX (j + 1);
+ long y1 = 0;
+ long y2 = MUSICALSCOREPRINTVIEW_SCALEHEIGHT / 2;
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ CString strText;
+ strText.Format (_T("%d"), j + 1);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ pDC->SelectObject (pOldFont);
+ }
+ else {
+ long lEndFrameNumber = lEndTime / lTimeResolution;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+
+}
+
+// セルの文字列を取得(トラック名限定)
+CString CMusicalScorePrintView::GetCellString (long lTrack) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ ASSERT (0 <= lTrack && lTrack < MAXMIDITRACKNUM);
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrack);
+ MIDIEvent* pMIDIEvent = NULL;
+ CString strText;
+ strText = pSekaijuDoc->GetTrackName (pMIDITrack);
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ codestr2str ((LPTSTR)(LPCTSTR)strText, strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ strText = szBuf2;
+ return strText;
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 印刷時
+void CMusicalScorePrintView::OnPrint (CDC* pDC, CPrintInfo* pInfo) {
+
+ pDC->SetMapMode (MM_LOMETRIC);
+ CPoint ptWindowOrg (0, 0);
+
+ long lLeftMargin = MUSICALSCOREPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = MUSICALSCOREPRINTVIEW_RIGHTMARGIN;
+ long lTopMargin = MUSICALSCOREPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = MUSICALSCOREPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = MUSICALSCOREPRINTVIEW_SCALEHEIGHT;
+ long lTrackHeight = (m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin);
+ long lScaleWidth = MUSICALSCOREPRINTVIEW_SCALEWIDTH;
+ long lTimeWidth = m_sizLogPaper.cx - lScaleWidth - lLeftMargin - lRightMargin;
+
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long lCurRowPage = lCurPage % m_lMaxRowPage;
+ long lCurRollPage = lCurPage / m_lMaxRowPage;
+
+
+
+ CRgn theRgn;
+ CRect rcClip;
+
+
+ // トラック目盛り部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lTrackHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin + lTrackHeight * (m_lMaxRowPage - lCurRowPage - 1);
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawTrackScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 左上余白部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = -lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin + lTrackHeight;
+ rcClip.bottom = lBottomMargin + lTrackHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lTrackHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 譜面ロール部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lTimeWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lTrackHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lTimeWidth * lCurRollPage;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin + lTrackHeight * (m_lMaxRowPage - lCurRowPage - 1);
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawTrackTimeView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 時刻目盛り部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lTimeWidth;
+ rcClip.top = lBottomMargin + lTrackHeight;
+ rcClip.bottom = lBottomMargin + lTrackHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lTimeWidth * lCurRollPage;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lTrackHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawTimeScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // ヘッダー(タイトル)
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ pDC->SetTextColor (RGB (0, 0 ,0));
+ CRect rcText;
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = m_sizLogPaper.cy - lTopMargin;
+ rcText.bottom = m_sizLogPaper.cy - lTopMargin / 2;
+ TCHAR szText[256];
+ memset (szText, 0, sizeof (szText));
+ MIDIData_GetTitle (GetDocument()->m_pMIDIData, szText, TSIZEOF (szText));
+ CString strText;
+ if (TCSLEN (szText) == 0) {
+ strText = GetDocument()->GetTitle ();
+ }
+ else {
+ strText.Format (_T("%s"), szText);
+ }
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+ // フッター(ページ数/全ページ数)
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = lTopMargin / 2;
+ rcText.bottom = lTopMargin;
+ strText.Format (_T("%d/%d"), pInfo->m_nCurPage, pInfo->GetMaxPage ());
+ pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+}
+
+// 印刷準備時
+BOOL CMusicalScorePrintView::OnPreparePrinting (CPrintInfo* pInfo) {
+ // デフォルトの印刷準備
+ return DoPreparePrinting (pInfo);
+}
+
+// 印刷開始時
+void CMusicalScorePrintView::OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // 紙サイズの取得
+ m_sizDevPaper.cx = pDC->GetDeviceCaps (HORZRES); // [pixel]
+ m_sizDevPaper.cy = pDC->GetDeviceCaps (VERTRES); // [pixel]
+ m_sizLogPaper.cx = pDC->GetDeviceCaps (HORZSIZE) * 10; // [*0.1mm]
+ m_sizLogPaper.cy = pDC->GetDeviceCaps (VERTSIZE) * 10; // [*0.1mm]
+ m_sizLogPrinterDPI.cx = pDC->GetDeviceCaps (LOGPIXELSX); // [dpi]
+ m_sizLogPrinterDPI.cy = pDC->GetDeviceCaps (LOGPIXELSY); // [dpi]
+
+ // MIDIデータの性質を取得
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+
+ // トラック情報配列と小節情報配列の印刷用部分計算
+ this->CalcTrackInfoArray ();
+ this->CalcMeasureInfoArray ();
+
+ // ロール部の幅と横方向ページ数を計算
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+ long lLastTime = 0;
+ MIDIData_MakeTime (pMIDIData, lEndMeasure + 1, 0, 0, &lLastTime);
+ long lRollWidth = this->TimetoX (lLastTime);
+ long lLeftMargin = MUSICALSCOREPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = MUSICALSCOREPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = MUSICALSCOREPRINTVIEW_SCALEWIDTH;
+ long lTimeWidth = m_sizLogPaper.cx - lScaleWidth - lLeftMargin - lRightMargin;
+ if (lRollWidth % MAX (lTimeWidth, 1) == 0) {
+ m_lMaxRollPage = lRollWidth / MAX (lTimeWidth, 1);
+ }
+ else {
+ m_lMaxRollPage = lRollWidth / MAX (lTimeWidth, 1) + 1;
+ }
+
+ // 縦方向ページ数を計算
+ long lTopMargin = MUSICALSCOREPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = MUSICALSCOREPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = MUSICALSCOREPRINTVIEW_SCALEHEIGHT;
+ long lTrackHeight = m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin;
+ long lTrackInfoCount = pMusicalScoreFrame->GetTrackInfoCount ();
+ ASSERT (1 <= lTrackInfoCount && lTrackInfoCount <= MAXMIDITRACKNUM);
+ MusicalScoreTrackInfo* pLastTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackInfoCount - 1);
+ long lTrackBottom = (pLastTrackInfo->m_lTopPrint + pLastTrackInfo->m_lHeightPrint);
+ if (lTrackBottom % MAX (lTrackHeight, 1) == 0) {
+ m_lMaxRowPage = lTrackBottom / MAX (lTrackHeight, 1);
+ }
+ else {
+ m_lMaxRowPage = lTrackBottom / MAX (lTrackHeight, 1) + 1;
+ }
+
+ // 印刷ページ数の設定
+ m_lMaxPage = m_lMaxRowPage * m_lMaxRollPage;
+ pInfo->SetMaxPage (m_lMaxPage);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 印刷終了時
+void CMusicalScorePrintView::OnEndPrinting (CDC* pDC, CPrintInfo* pInfo) {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
diff --git a/src/MusicalScorePrintView.h b/src/MusicalScorePrintView.h
new file mode 100644
index 0000000..0f02f4f
--- /dev/null
+++ b/src/MusicalScorePrintView.h
@@ -0,0 +1,108 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロール印刷ビュークラス
+// (C)2002-2011 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MUSICALSCOREPRINTVIEW_H_
+#define _MUSICALSCOREPRINTVIEW_H_
+
+class CMusicalScorePrintView : public CSekaijuView {
+ DECLARE_DYNCREATE (CMusicalScorePrintView)
+
+ // CMusicalScoreFrameからCMusicalScorePrintView::OnCmdMsgの呼び出しを許可する。
+ friend class CMusicalScoreFrame;
+
+ // 印刷関係
+ CSize m_sizDevPaper; // 物理紙サイズ[ドット]
+ CSize m_sizLogPaper; // 論理紙サイズ[*1/10mm]
+ CSize m_sizLogPrinterDPI; // プリンタのDPI
+ CFont m_theFont; // 印刷用フォント
+ long m_lMaxRowPage; // 最大ページ数(縦方向)
+ long m_lMaxRollPage; // 最大ページ数(譜面ロール方向)
+ long m_lMaxPage; // 最大ページ数(縦方向*譜面ロール方向)
+ CUIntArray m_theRowPageInfoArray; // 縦方向のページ情報配列(先頭小節番号)
+ CUIntArray m_theRollPageInfoArray; // 譜面ロール方向のページ情報配列(先頭トラック番号)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMusicalScorePrintView (); // コンストラクタ
+ virtual ~CMusicalScorePrintView (); // デストラクタ
+
+ //------------------------------------------------------------------------------
+ // オペレーション
+ //------------------------------------------------------------------------------
+
+protected:
+
+ long GetRowPageInfoCount () {return m_theRowPageInfoArray.GetSize ();};
+ long GetRollPageInfoCount () {return m_theRollPageInfoArray.GetSize ();};
+
+ void CalcMeasureInfoArray ();
+ void CalcTrackInfoArray ();
+
+ long TrackIndexLineNotoY (long lTrackIndex, long lLineNo);
+ long TrackIndexKeytoY (long lTrackIndex, long lKey, long lKeySignature);
+ long TimetoX (long lTime);
+ long MeasuretoX (long lMeasure);
+ long MeasuretoX2 (long lMeasure);
+
+ void DrawTadpole (CDC* pDC, long x, long y, long rx, long ry, long lFlags);
+ void DrawGClef (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawFClef (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawFlat (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawSharp (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawNatural (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawTimeAndKeySignature (CDC* pDC, long lTrackIndex, long lTime);
+ void DrawHorzAuxiliaryLine (CDC* pDC, long x, long y, long r, long lFlags);
+ void DrawDot (CDC* pDC, long x, long y, long rx, long ry, long lFlags);
+ void DrawTieHalf (CDC* pDC, long x1, long x2, long y, long rx, long ry, long lFlags);
+ void DrawPole (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawSingleFlag (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawChainedFlag (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawTripletSign (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawNote (CDC* pDC, long lTrackIndex, MusicalScoreNoteInfo* pNoteInfo, long lFlags);
+ void DrawFlagAndText (CDC* pDC, long lTime, LPCTSTR lpszText, long lColor);
+
+ void DrawTrackScaleView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawTrackTimeView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawScaleView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawTimeScaleView (CDC* pDC, CPrintInfo* pInfo);
+
+ CString GetCellString (long lTrack);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrint (CDC* pDC, CPrintInfo* pInfo);
+ virtual BOOL OnPreparePrinting (CPrintInfo* pInfo);
+ virtual void OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting (CDC* pDC, CPrintInfo* pInfo);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
+
diff --git a/src/MusicalScoreScaleView.cpp b/src/MusicalScoreScaleView.cpp
new file mode 100644
index 0000000..ed2ed04
--- /dev/null
+++ b/src/MusicalScoreScaleView.cpp
@@ -0,0 +1,155 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面スケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "ColorfulCheckListBox.h"
+#include "ColorfulComboBox.h"
+#include "MusicalScoreFrame.h"
+#include "MusicalScoreScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CMusicalScoreScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CMusicalScoreScaleView, CSekaijuView)
+ ON_WM_KEYDOWN ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//-----------------------------------------------------------------------------
+// 構築と破壊
+//-----------------------------------------------------------------------------
+
+// コンストラクタ
+CMusicalScoreScaleView::CMusicalScoreScaleView () {
+}
+
+// デストラクタ
+CMusicalScoreScaleView::~CMusicalScoreScaleView () {
+}
+
+//-----------------------------------------------------------------------------
+// オーバーライド
+//-----------------------------------------------------------------------------
+
+// 描画
+void CMusicalScoreScaleView::OnDraw (CDC* pDC) {
+ CSekaijuDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+}
+
+// ビューの更新
+void CMusicalScoreScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // 演奏開始した場合、リアルタイム入力開始した場合、位置移動した場合
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) { // 20091224追加
+ pMusicalScoreFrame->m_bAutoPageUpdate = TRUE;
+ }
+ }
+ // MIDIトラックが変更された場合
+ if (lHint & SEKAIJUDOC_MIDITRACKCHANGED) {
+ pMusicalScoreFrame->UpdateTrackList ();
+ pMusicalScoreFrame->UpdateTrackCombo ();
+ }
+ // MIDIデータ又はMIDIトラック又はMIDIイベントが変更された場合
+ if ((lHint & SEKAIJUDOC_MIDIDATACHANGED) ||
+ (lHint & SEKAIJUDOC_MIDITRACKCHANGED) ||
+ (lHint & SEKAIJUDOC_MIDIEVENTCHANGED)) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ pMainFrame->SetPositionScrollRange (0, lEndTime, TRUE);
+ VERIFY (pMusicalScoreFrame->UpdateMeasureInfoArray ());
+ VERIFY (pMusicalScoreFrame->UpdateTrackInfoArray ());
+ pMusicalScoreFrame->RecalcTrackScrollInfo ();
+ pMusicalScoreFrame->RecalcTimeScrollInfo ();
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+
+//-----------------------------------------------------------------------------
+// メッセージマップ
+//-----------------------------------------------------------------------------
+
+// キーが押された時
+void CMusicalScoreScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ pMusicalScoreFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+}
+
+// マウスホイールが回された時
+void CMusicalScoreScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lTrackScrollPos = pMusicalScoreFrame->GetTrackScrollPos ();
+ long ry = 4;
+ lTrackScrollPos -= ry * 2 * lDelta / WHEELDELTA;
+ pMusicalScoreFrame->SetTrackScrollPos (lTrackScrollPos);
+ }
+}
diff --git a/src/MusicalScoreScaleView.h b/src/MusicalScoreScaleView.h
new file mode 100644
index 0000000..0ef7306
--- /dev/null
+++ b/src/MusicalScoreScaleView.h
@@ -0,0 +1,51 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面スケールウィンドウクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MUSICALSCORESCALEVIEW_H_
+#define _MUSICALSCORESCALEVIEW_H_
+
+class CMusicalScoreScaleView : public CSekaijuView {
+ DECLARE_DYNCREATE (CMusicalScoreScaleView)
+
+ //-------------------------------------------------------------------------
+ // 構築と破壊
+ //-------------------------------------------------------------------------
+public:
+ CMusicalScoreScaleView (); // コンストラクタ
+ virtual ~CMusicalScoreScaleView (); // デストラクタ
+
+ //-------------------------------------------------------------------------
+ // オーバーライド
+ //-------------------------------------------------------------------------
+public:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //-------------------------------------------------------------------------
+ // メッセージマップ
+ //-------------------------------------------------------------------------
+protected:
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+
+#endif
diff --git a/src/MusicalScoreTimeScaleView.cpp b/src/MusicalScoreTimeScaleView.cpp
new file mode 100644
index 0000000..7bbb471
--- /dev/null
+++ b/src/MusicalScoreTimeScaleView.cpp
@@ -0,0 +1,628 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面タイムスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "ColorfulCheckListBox.h"
+#include "ColorfulComboBox.h"
+#include "MusicalScoreFrame.h"
+#include "MusicalScoreTimeScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CMusicalScoreTimeScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CMusicalScoreTimeScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//-----------------------------------------------------------------------------
+// 構築と破壊
+//-----------------------------------------------------------------------------
+
+// コンストラクタ
+CMusicalScoreTimeScaleView::CMusicalScoreTimeScaleView () {
+}
+
+// デストラクタ
+CMusicalScoreTimeScaleView::~CMusicalScoreTimeScaleView () {
+}
+
+//-----------------------------------------------------------------------------
+// オペレーション
+//-----------------------------------------------------------------------------
+
+// 指定時刻にフラグとテキストを描画
+void CMusicalScoreTimeScaleView::DrawFlagAndText
+(CDC* pDC, long lTime, LPCTSTR lpszText, long lColor) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ long x = pMusicalScoreFrame->TimetoX (lTime);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CRect rcBack (x, 0, x + 1024, 16);
+ CRect rcFlag (x, 3, x + 3, 12);
+ CRect rcText (x + 5, 0, x + 1024, 16);
+ CPen pen;
+ pen.CreatePen (PS_SOLID, 1, lColor);
+ CPen* pOldPen = pDC->SelectObject (&pen);
+ pDC->FillSolidRect (&rcBack, ::GetSysColor (COLOR_BTNFACE));
+ pDC->FillSolidRect (&rcFlag, lColor);
+ pDC->MoveTo (x, 3);
+ pDC->LineTo (x, 16);
+ pDC->SetBkMode (TRANSPARENT);
+ pDC->SetTextColor (lColor);
+ pDC->DrawText (lpszText, rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ pDC->SelectObject (pOldPen);
+}
+
+
+// オーバーライド
+
+// 原点の移動をオーバーライド
+void CMusicalScoreTimeScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ pDC->SetWindowOrg (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+}
+
+// 描画
+void CMusicalScoreTimeScaleView::OnDraw (CDC* pDC) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+ CFont* pOldFont = pDC->SelectObject (&(pMusicalScoreFrame->m_theFont));
+
+ long x, xold;
+ long lVisibleLeftTime = pMusicalScoreFrame->GetVisibleLeftTime ();
+ long lVisibleRightTime = pMusicalScoreFrame->GetVisibleRightTime ();
+ TCHAR szBuf[256];
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+
+ // 上段に拍子記号・調性記号・マーカーの描画
+ long lTime = 0;
+ long lOldTime = 0;
+ CString strText1;
+ CString strText2;
+ pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ if (pMIDITrack) {
+ long lColorTrack1 = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (0 <= lTime && lTime <= lVisibleRightTime) {
+ // テンポ
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo;
+ lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ strText1.Format (_T("%1.2lf"), (double)60000000 / (double)lTempo);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 拍子記号
+ else if (MIDIEvent_IsTimeSignature (pMIDIEvent)) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ strText1.Format (_T("%d/%d"), lnn, 1 << ldd);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 調性記号
+ else if (MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ strText1.Format (_T("%d%s"), labs (lsf), lsf >= 0 ? _T("#") : _T("b"));
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // マーカー
+ else if (MIDIEvent_IsMarker (pMIDIEvent)) {
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIEvent_GetText (pMIDIEvent, szBuf, TSIZEOF (szBuf) - 1);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += szBuf;
+ lOldTime = lTime;
+ }
+ }
+ }
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ }
+
+ // 下段に小節ボタン描画
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lLeftMeasure, lLeftBeat, lLeftTick;
+ long lRightMeasure, lRightBeat, lRightTick;
+ MIDIData_BreakTime (pMIDIData, lVisibleLeftTime, &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_BreakTime (pMIDIData, lVisibleRightTime, &lRightMeasure, &lRightBeat, &lRightTick);
+ //xold = pMusicalScoreFrame->TimetoXM (lVisibleLeftTime) - 1;
+ xold = pMusicalScoreFrame->MeasuretoX (lLeftMeasure) - 1;
+ CRect theRect;
+ pDC->SetBkMode (TRANSPARENT);
+ for (long i = lLeftMeasure; i <= lRightMeasure + 1; i++) {
+ //MIDIData_MakeTime (pMIDIData, i, 0, 0, &lTime);
+ //x = pMusicalScoreFrame->TimetoXM (lTime);
+ x = pMusicalScoreFrame->MeasuretoX (i);
+ pDC->MoveTo (x, 16);
+ pDC->LineTo (x, 32);
+ theRect = CRect (xold, 16, x, 32);
+ pDC->Draw3dRect (xold, 16, x - xold, 16, lColorBtnHighlight, lColorBtnShadow);
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i);
+ pDC->SetTextColor (lColorBtnText);
+ pDC->DrawText (szBuf, -1, &theRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ xold = x;
+ }
+ }
+ else {
+ long lLeftFrameNumber = lVisibleLeftTime / lTimeResolution;
+ long lRightFrameNumber = lVisibleRightTime / lTimeResolution;
+ xold = pMusicalScoreFrame->TimetoX (lVisibleLeftTime) - 1;
+ CRect theRect;
+ pDC->SetBkMode (TRANSPARENT);
+ for (long i = lLeftFrameNumber; i <= lRightFrameNumber + 1; i++) {
+ lTime = i * lTimeResolution;
+ x = pMusicalScoreFrame->TimetoX (lTime);
+ pDC->MoveTo (x, 16);
+ pDC->LineTo (x, 32);
+ theRect = CRect (xold, 16, x, 32);
+ pDC->Draw3dRect (xold, 16, x - xold, 16, lColorBtnHighlight, lColorBtnShadow);
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i);
+ pDC->DrawText (szBuf, -1, &theRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ xold = x;
+ }
+ }
+ pDC->SelectObject (pOldFont);
+
+ if (GetCapture () == this) {
+ long lDownX = pMusicalScoreFrame->TimetoX (m_lDownTime);
+ long lCurX = pMusicalScoreFrame->TimetoX (m_lCurTime);
+ long lTop = rcClient.top;
+ long lBottom = rcClient.bottom;
+ CRect rect (lDownX, lTop, lCurX, lBottom);
+ pDC->SetROP2 (R2_NOT);
+ pDC->Rectangle (&rect);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// ビューの更新
+void CMusicalScoreTimeScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// メッセージマップ
+//-----------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CMusicalScoreTimeScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キーが押された時
+void CMusicalScoreTimeScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ pMusicalScoreFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+}
+
+// マウス左ボタン押された時
+void CMusicalScoreTimeScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+ point += CSize (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+
+ // 上半分をクリックしたとき(演奏位置移動)
+ if (point.y < rcClient.Height () / 2) { // 20100103追加
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTime = pMusicalScoreFrame->XtoTime (point.x);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+ // 下半分(小節番号部)をクリックしたとき(小節選択)
+ else {
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ // 履歴の記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName; // 20110103追加
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT)); // 20110103追加
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName)); // 20110103修正
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+
+ m_lTempSnap = pMusicalScoreFrame->GetCurSnap ();
+ m_lTempSnap = CLIP (1, m_lTempSnap, MIDIData_GetTimeResolution (pMIDIData));
+ m_lOldTime = pMusicalScoreFrame->XtoTime (m_ptMouseDown.x) / m_lTempSnap * m_lTempSnap;
+ m_lDownTime = pMusicalScoreFrame->XtoTime (point.x) / m_lTempSnap * m_lTempSnap;
+ m_lCurTime = pMusicalScoreFrame->XtoTime (point.x) / m_lTempSnap * m_lTempSnap;
+
+ SetCapture ();
+ SetTimer (0x21, 55, NULL);
+ pMusicalScoreFrame->m_bAutoPageUpdate = FALSE;
+ VERIFY (pMusicalScoreFrame->UpdateTrackInfoArray ());
+ Invalidate ();
+
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// マウス右ボタン押された時
+void CMusicalScoreTimeScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+ CSize sizWndOrg (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+ point += sizWndOrg;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ if (point.y > rcClient.bottom / 2) {
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ long lTime = pMusicalScoreFrame->XtoTime (point.x);
+ //long lMeasure, lBeat, lTick;
+ //MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ //MIDIData_MakeTime (pMIDIData, lMeasure, 0, 0, &lTime);
+ pSekaijuDoc->m_lTempTime = lTime;
+ pSekaijuDoc->m_lTempTrackIndex = 0;
+ pSekaijuDoc->m_pTempTrack = pSekaijuDoc->GetTrack (0);
+ pSekaijuDoc->m_pTempEvent = NULL;
+ pSekaijuDoc->m_pTempTempoEvent = NULL;
+ pSekaijuDoc->m_pTempTimeSignatureEvent = NULL;
+ pSekaijuDoc->m_pTempKeySignatureEvent = NULL;
+ pSekaijuDoc->m_pTempMarkerEvent = NULL;
+ MIDIEvent* pTempEvent;
+ forEachEvent (pSekaijuDoc->m_pTempTrack, pTempEvent) {
+ if (MIDIEvent_GetTime (pTempEvent) > lTime) {
+ break;
+ }
+ if (MIDIEvent_IsTempo (pTempEvent)) {
+ pSekaijuDoc->m_pTempTempoEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsTimeSignature (pTempEvent)) {
+ pSekaijuDoc->m_pTempTimeSignatureEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsKeySignature (pTempEvent)) {
+ pSekaijuDoc->m_pTempKeySignatureEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsMarker (pTempEvent)) {
+ pSekaijuDoc->m_pTempMarkerEvent = pTempEvent;
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU10));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pMusicalScoreFrame);
+}
+
+// マウス左ボタン離されたとき
+void CMusicalScoreTimeScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+ point += CSize (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+ // キャプタ−中の場合
+ if (GetCapture () == this) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ KillTimer (0x21);
+ ReleaseCapture ();
+
+ long lMinTime = __min (m_lDownTime, m_lCurTime);
+ long lMaxTime = __max (m_lDownTime, m_lCurTime);
+
+ // 該当範囲にあるノートイベントの選択
+ long i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ VERIFY (pTempEvent = pNoteInfo->m_pNoteOnEvent);
+ // この音符に対応するノートオンイベントがまだ選択されていない場合のみ
+ if (MIDIEvent_GetParent (pTempEvent) == pTempTrack) {
+ // 時刻が選択範囲内にある場合
+ long lTime = pNoteInfo->m_lNoteOnTime;
+ if (lMinTime <= lTime && lTime < lMaxTime) {
+ // イベントを履歴置き場に移し、新しいイベントを選択する。
+ MIDIEvent* pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+
+ }
+ }
+ }
+ }
+ i++;
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CMusicalScoreTimeScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CMusicalScoreTimeScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+ point += CSize (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+
+ // キャプタ−中の場合
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ m_lCurTime = pMusicalScoreFrame->XtoTime (point.x) / m_lTempSnap * m_lTempSnap;
+ m_lDownTime = pMusicalScoreFrame->XtoTime (m_ptMouseDown.x) / m_lTempSnap * m_lTempSnap;
+ m_lOldTime = pMusicalScoreFrame->XtoTime (m_ptMouseMove.x) / m_lTempSnap * m_lTempSnap;
+ // 前回のタイムと今回のタイムが異なる場合のみ
+ if (m_lOldTime != m_lCurTime) {
+ // 目盛り再描画
+ Invalidate (TRUE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CMusicalScoreTimeScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CMusicalScoreTimeScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CMusicalScoreTimeScaleView::OnTimer (UINT nIDEvent) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理
+ if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), 0);
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldTimeScrollPos = pMusicalScoreFrame->GetTimeScrollPos ();
+ if (m_ptMouseMove.x < rcClient.left) {
+ pMusicalScoreFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pMusicalScoreFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.x >= rcClient.right) {
+ pMusicalScoreFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pMusicalScoreFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x - lOldTimeScrollPos);
+ WORD wY = (WORD)(m_ptMouseMove.y);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+// マウスホイールが回された時
+void CMusicalScoreTimeScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lTrackScrollPos = pMusicalScoreFrame->GetTrackScrollPos ();
+ long ry = 4;
+ lTrackScrollPos -= ry * 2 * lDelta / WHEELDELTA;
+ pMusicalScoreFrame->SetTrackScrollPos (lTrackScrollPos);
+ }
+}
+
diff --git a/src/MusicalScoreTimeScaleView.h b/src/MusicalScoreTimeScaleView.h
new file mode 100644
index 0000000..d17fbc6
--- /dev/null
+++ b/src/MusicalScoreTimeScaleView.h
@@ -0,0 +1,76 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面タイムスケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+class CMusicalScoreTimeScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CMusicalScoreTimeScaleView)
+
+ //-------------------------------------------------------------------------
+ // アトリビュート
+ //-------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときのフラグ
+ long m_lDownTime; // マウスが押されたときの指す時刻[tick]又は[サブフレーム]
+ long m_lOldTime; // マウスが動かされたとの前回の指す時刻[tick]又は[サブフレーム]
+ long m_lCurTime; // マウスが動かされたとの現在の指す時刻[tick]又は[サブフレーム]
+ long m_lTempSnap; // 一時的なスナップ
+
+ //-------------------------------------------------------------------------
+ // 構築と破壊
+ //-------------------------------------------------------------------------
+public:
+ CMusicalScoreTimeScaleView(); // コンストラクタ
+ virtual ~CMusicalScoreTimeScaleView(); // デストラクタ
+
+
+ //-------------------------------------------------------------------------
+ // オペレーション
+ //-------------------------------------------------------------------------
+protected:
+ virtual void DrawFlagAndText (CDC* pDC, long lTime, LPCTSTR lpszText, long lColor);
+
+ //-------------------------------------------------------------------------
+ // オーバーライド
+ //-------------------------------------------------------------------------
+public:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //-------------------------------------------------------------------------
+ // メッセージマップ
+ //-------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/src/MusicalScoreTrackScaleView.cpp b/src/MusicalScoreTrackScaleView.cpp
new file mode 100644
index 0000000..fd33b0f
--- /dev/null
+++ b/src/MusicalScoreTrackScaleView.cpp
@@ -0,0 +1,1200 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面トラックスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "common.h"
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "ColorfulCheckListBox.h"
+#include "ColorfulComboBox.h"
+#include "MusicalScoreFrame.h"
+#include "MusicalScoreTrackScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define IDC_TEXTBOX 3955
+
+IMPLEMENT_DYNCREATE (CMusicalScoreTrackScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CMusicalScoreTrackScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_KILLFOCUS ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//-----------------------------------------------------------------------------
+// 構築と破壊
+//-----------------------------------------------------------------------------
+
+// コンストラクタ
+CMusicalScoreTrackScaleView::CMusicalScoreTrackScaleView () {
+ m_lDownTrack = -1;
+ m_lOldTrack = -1;
+ m_lCurTrack = -1;
+ m_lOldTime = 0;
+ m_bSettingCellString = 0;
+}
+
+// デストラクタ
+CMusicalScoreTrackScaleView::~CMusicalScoreTrackScaleView () {
+}
+
+//-----------------------------------------------------------------------------
+// オペレーション
+//-----------------------------------------------------------------------------
+
+// ト音記号を描画する
+void CMusicalScoreTrackScaleView::DrawGClef
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[21];
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y + ry;
+ pt[1].x = ptCenter.x - rx;
+ pt[1].y = ptCenter.y;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x + rx;
+ pt[3].y = ptCenter.y - ry;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y + ry;
+ pt[6].x = ptCenter.x + rx;
+ pt[6].y = ptCenter.y + ry * 2;
+ pt[7].x = ptCenter.x - rx * 1;
+ pt[7].y = ptCenter.y + ry * 2;
+ pt[8].x = ptCenter.x - rx * 2;
+ pt[8].y = ptCenter.y + ry;
+ pt[9].x = ptCenter.x - rx * 2;
+ pt[9].y = ptCenter.y - ry;
+ pt[10].x = ptCenter.x;
+ pt[10].y = ptCenter.y - ry * 4;
+ pt[11].x = ptCenter.x + rx * 1;
+ pt[11].y = ptCenter.y - ry * 5;
+ pt[12].x = ptCenter.x + rx * 1;
+ pt[12].y = ptCenter.y - ry * 8;
+ pt[13].x = ptCenter.x;
+ pt[13].y = ptCenter.y - ry * 6;
+ pt[14].x = ptCenter.x;
+ pt[14].y = ptCenter.y - ry * 4;
+ pt[15].x = ptCenter.x + rx;
+ pt[15].y = ptCenter.y + ry * 4;
+ pt[16].x = ptCenter.x;
+ pt[16].y = ptCenter.y + ry * 5;
+ pt[17].x = ptCenter.x - rx * 1 / 2;
+ pt[17].y = ptCenter.y + ry * 5;
+ pDC->Polyline (pt, 18);
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y - ry;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x + rx * 2;
+ pt[3].y = ptCenter.y;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y - ry;
+ pt[5].x = ptCenter.x + rx;
+ pt[5].y = ptCenter.y - ry * 2;
+ pt[6].x = ptCenter.x;
+ pt[6].y = ptCenter.y - ry * 2;
+ pt[7].x = ptCenter.x - rx;
+ pt[7].y = ptCenter.y - ry;
+ pDC->Polygon (pt, 8);
+ pt[0].x = ptCenter.x - rx * 2;
+ pt[0].y = ptCenter.y - ry * 1;
+ pt[1].x = ptCenter.x - rx * 2;
+ pt[1].y = ptCenter.y - ry * 2;
+ pt[2].x = ptCenter.x + rx * 1;
+ pt[2].y = ptCenter.y - ry * 6;
+ pt[3].x = ptCenter.x + rx * 1;
+ pt[3].y = ptCenter.y - ry * 5;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y - ry * 6;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y - ry * 7;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y - ry * 8;
+ pt[3].x = ptCenter.x + rx;
+ pt[3].y = ptCenter.y - ry * 7;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x - rx * 1;
+ pt[0].y = ptCenter.y + ry * 9 / 2;
+ pt[1].x = ptCenter.x - rx * 1 / 2;
+ pt[1].y = ptCenter.y + ry * 4;
+ pt[2].x = ptCenter.x;
+ pt[2].y = ptCenter.y + ry * 9 / 2;
+ pt[3].x = ptCenter.x - rx * 1 / 2;
+ pt[3].y = ptCenter.y + ry * 5;
+ pDC->Polygon (pt, 4);
+}
+
+// ヘ音記号を描画する
+void CMusicalScoreTrackScaleView::DrawFClef
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x - rx * 2;
+ pt[1].y = ptCenter.y;
+ pt[2].x = ptCenter.x - rx * 2;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x - rx;
+ pt[3].y = ptCenter.y - ry * 2;
+ pt[4].x = ptCenter.x + rx;
+ pt[4].y = ptCenter.y - ry * 2;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y - ry;
+ pt[6].x = ptCenter.x + rx * 2;
+ pt[6].y = ptCenter.y + ry;
+ pt[7].x = ptCenter.x;
+ pt[7].y = ptCenter.y + ry * 4;
+ pt[8].x = ptCenter.x - rx * 2;
+ pt[8].y = ptCenter.y + ry * 6;
+ pDC->Polyline (pt, 9);
+ pt[0].x = ptCenter.x - rx * 2;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x - rx * 3 / 2;
+ pt[1].y = ptCenter.y - ry * 1 / 2;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y;
+ pt[3].x = ptCenter.x - rx * 3 / 2;
+ pt[3].y = ptCenter.y + ry * 1 / 2;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y - ry * 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry * 1;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y + ry * 1;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y + ry * 4;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y + ry * 1;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y - ry * 1;
+ pt[6].x = ptCenter.x + rx * 1;
+ pt[6].y = ptCenter.y - ry * 2;
+ pDC->Polygon (pt, 7);
+ pt[0].x = ptCenter.x + rx * 3 + rx / 2;
+ pt[0].y = ptCenter.y - ry * 1;
+ pt[1].x = ptCenter.x + rx * 3;
+ pt[1].y = ptCenter.y - ry * 1 - ry / 2;
+ pt[2].x = ptCenter.x + rx * 3 - rx / 2;
+ pt[2].y = ptCenter.y - ry * 1;
+ pt[3].x = ptCenter.x + rx * 3;
+ pt[3].y = ptCenter.y - ry * 1 + ry / 2;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x + rx * 3 + rx / 2;
+ pt[0].y = ptCenter.y + ry * 1;
+ pt[1].x = ptCenter.x + rx * 3;
+ pt[1].y = ptCenter.y + ry * 1 - ry / 2;
+ pt[2].x = ptCenter.x + rx * 3 - ry / 2;
+ pt[2].y = ptCenter.y + ry * 1;
+ pt[3].x = ptCenter.x + rx * 3;
+ pt[3].y = ptCenter.y + ry * 1 + ry / 2;
+ pDC->Polygon (pt, 4);
+}
+
+// ♭の描画
+void CMusicalScoreTrackScaleView::DrawFlat
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y - ry;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x + rx / 2;
+ pt[3].y = ptCenter.y;
+ pt[4].x = ptCenter.x - rx / 2;
+ pt[4].y = ptCenter.y + ry;
+ pt[5].x = ptCenter.x - rx / 2;
+ pt[5].y = ptCenter.y - ry * 4;
+ pDC->Polyline (pt, 6);
+}
+
+// #の描画
+void CMusicalScoreTrackScaleView::DrawSharp
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y + ry + ry / 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y + ry - ry / 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y - ry + ry / 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry - ry / 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y - ry * 2;
+ pt[1].x = ptCenter.x - rx / 2;
+ pt[1].y = ptCenter.y + ry * 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x + rx / 2;
+ pt[0].y = ptCenter.y - ry * 2;
+ pt[1].x = ptCenter.x + rx / 2;
+ pt[1].y = ptCenter.y + ry * 2;
+ pDC->Polyline (pt, 2);
+};
+
+// 拍子記号・調性記号の描画
+void CMusicalScoreTrackScaleView::DrawTimeAndKeySignature
+ (CDC* pDC, long lTrackIndex, long lTime) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackIndex));
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long x = 40;
+ long y = 0;
+ long rx = 4;
+ long ry = 4;
+ long lGCrefSharpLineNo[7] = {45, 42, 46, 43, 40, 44, 41};
+ long lFCrefSharpLineNo[7] = {31, 28, 32, 29, 33, 30, 34};
+ long lGCrefFlatLineNo[7] = {41, 44, 40, 43, 39, 42, 38};
+ long lFCrefFlatLineNo[7] = {27, 30, 26, 29, 25, 28, 24};
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lTime, &lsf, &lmi);
+ long lnn, ldd, lcc, lbb;
+ MIDIData_FindTimeSignature (pMIDIData, lTime, &lnn, &ldd, &lcc, &lbb);
+ CString strText1;
+ CString strText2;
+ strText1.Format (_T("%d"), lnn);
+ strText2.Format (_T("%d"), (1 << ldd));
+ CRect rcText1 (x + rx * 10 + rx * 2 * abs(lsf), 0, x + rx * 10 + rx * 2 * abs(lsf) + 24, 0);
+ CRect rcText2 (x + rx * 10 + rx * 2 * abs(lsf), 0, x + rx * 10 + rx * 2 * abs(lsf) + 24, 0);
+ long j;
+ switch (lTrackFlags & 0x0000000F) {
+ case 1: // ト音記号
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 39);
+ DrawGClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 41);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ case 2: // ヘ音記号
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 31);
+ DrawFClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 29);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ case 3: // 大譜表
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 39);
+ DrawGClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 41);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 31);
+ DrawFClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 29);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ }
+
+}
+
+
+// セルの文字列を取得(トラック名限定)
+CString CMusicalScoreTrackScaleView::GetCellString (long lTrack) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ ASSERT (0 <= lTrack && lTrack < MAXMIDITRACKNUM);
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrack);
+ MIDIEvent* pMIDIEvent = NULL;
+ CString strText;
+ strText = pSekaijuDoc->GetTrackName (pMIDITrack);
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ codestr2str ((LPTSTR)(LPCTSTR)strText, strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ strText = szBuf2;
+ return strText;
+}
+
+// セルの文字列を設定(トラック名限定)
+BOOL CMusicalScoreTrackScaleView::SetCellString (long lTrack, CString strText) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ ASSERT (0 <= lTrack && lTrack < MAXMIDITRACKNUM);
+ m_bSettingCellString = 1;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ long lValue = 0;
+ long lNumber = 0;
+ ASSERT (0 <= lTrack && lTrack < MAXMIDITRACKNUM);
+ // トラック名
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_TRACKNAME));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pMIDITrack = pSekaijuDoc->GetTrack (lTrack);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 最初のトラック名イベントを探索
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_GetKind (pTempEvent) == MIDIEVENT_TRACKNAME) {
+ break;
+ }
+ }
+ // 最初のトラック名イベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)(strText), strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ VERIFY (pTempEvent = MIDIEvent_CreateTrackName (0, szBuf2));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 最初のトラック名が見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)(strText), strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ MIDIEvent_SetText (pCloneEvent, szBuf2);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+}
+
+
+// 現在テキストボックスで編集中かどうか返す。
+BOOL CMusicalScoreTrackScaleView::IsTextEditing () {
+ return (m_theTextBox.GetStyle () & WS_VISIBLE) ? TRUE : FALSE;
+}
+
+// テキストボックスでの編集を開始する。
+BOOL CMusicalScoreTrackScaleView::BeginTextEditing () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ pSekaijuApp->m_bInplaceEditing = 1;
+ ASSERT (0 <= m_lCurTrack && m_lCurTrack < MAXMIDITRACKNUM);
+ CString strCellString = GetCellString (m_lCurTrack);
+ m_theTextBox.SetWindowText (strCellString);
+ m_theTextBox.SetSel (0, -1, TRUE);
+ m_theTextBox.EmptyUndoBuffer ();
+ m_theTextBox.ShowWindow (SW_SHOW);
+ m_theTextBox.SetFocus ();
+ m_theTextBox.UpdateWindow ();
+ return TRUE;
+}
+
+// テキストボックスでの編集を終了し、新しい値を格納する。
+BOOL CMusicalScoreTrackScaleView::EndTextEditingOK () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 新しい履歴の作成・不足トラックの追加・値の設定はSetCellStringがやる。
+
+ // 現在のセルの編集テキストを反映
+ CString strText;
+ m_theTextBox.GetWindowText (strText);
+ if (SetCellString (m_lCurTrack, strText)) {
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+
+ // 編集終了
+ m_theTextBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+// テキストボックスでの編集を終了し、新しい値を格納しない。
+BOOL CMusicalScoreTrackScaleView::EndTextEditingCancel () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_theTextBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+// テキストボックスの移動(VISIBLE==FALSE時含む)
+BOOL CMusicalScoreTrackScaleView::MoveTextBox (long lTrackIndex) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*) GetParent ();
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackIndex);
+ long lTrackZoom = pMusicalScoreFrame->GetTrackZoom ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CRect rcNewCell (40, pTrackInfo->m_lTop * lTrackZoom,
+ rcClient.right, pTrackInfo->m_lTop * lTrackZoom + 13);
+ rcNewCell -= CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+ m_theTextBox.MoveWindow
+ (rcNewCell.left, rcNewCell.top, rcNewCell.Width (), 13);
+ return TRUE;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// オーバーライド
+//-----------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CMusicalScoreTrackScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ pDC->SetWindowOrg (0, pMusicalScoreFrame->GetTrackScrollPos ());
+}
+
+// 描画
+void CMusicalScoreTrackScaleView::OnDraw (CDC* pDC) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument();
+ ASSERT_VALID (pSekaijuDoc);
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+ CFont* pOldFont = NULL;
+ pDC->SetBkMode (TRANSPARENT);
+ long lTrackZoom = pMusicalScoreFrame->GetTrackZoom ();
+ long lVisibleTopTrack = pMusicalScoreFrame->GetVisibleTopTrack ();
+ long lVisibleBottomTrack = pMusicalScoreFrame->GetVisibleBottomTrack ();
+ long rx = 4;
+ long ry = 4;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ long i = 0;
+ MIDITrack* pTempTrack = NULL;
+
+ // ボタン部描画
+ i = 0;
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ pOldFont = pDC->SelectObject (&(pMusicalScoreFrame->m_theFont));
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i + (bTrackZeroOrigin ? 0 : 1));
+ BOOL bSelectTrack = TRUE;
+ long lCount = 0;
+ MIDIEvent* pTempEvent = NULL;
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent)) {
+ if (!pSekaijuDoc->IsEventSelected (pTempEvent)) {
+ bSelectTrack = FALSE;
+ }
+ lCount++;
+ }
+ }
+ if (GetCapture () == this) {
+ long lMinTrack = __min (m_lDownTrack, m_lCurTrack);
+ long lMaxTrack = __max (m_lDownTrack, m_lCurTrack);
+ if (lMinTrack <= i && i <= lMaxTrack) {
+ bSelectTrack = TRUE;
+ }
+ }
+ CRect theRect (0, pTrackInfo->m_lTop * lTrackZoom,
+ 32, (pTrackInfo->m_lTop + pTrackInfo->m_lHeight) * lTrackZoom);
+ if (bSelectTrack && lCount > 0) {
+ pDC->FillSolidRect (&theRect, lColorBlack);
+ pDC->Draw3dRect (&theRect, lColorBlack, lColorBtnShadow);
+ pDC->SetTextColor (lColorWhite);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ else {
+ pDC->FillSolidRect (&theRect, lColorBtnFace);
+ pDC->Draw3dRect (&theRect, lColorBtnHighlight, lColorBtnShadow);
+ pDC->SetTextColor (lColorBtnText);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldFont);
+
+ // 背景の描画
+ CRect rcTemp = rcClient;
+ rcTemp.left += 32;
+ pDC->FillSolidRect (rcTemp, pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+
+ // トラック名描画
+ i = 0;
+ pOldFont = pDC->SelectObject (&pMusicalScoreFrame->m_theFont);
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lTrackTop = pTrackInfo->m_lTop;
+ long lTrackHeight = pTrackInfo->m_lHeight;
+ long lColor = MIDITrack_GetForeColor (pTempTrack);
+ pDC->SetTextColor (lColor);
+ CString strTrackName;
+ strTrackName = GetCellString (i);
+ CRect rcTrackName (40, lTrackTop * lTrackZoom, rcClient.right,
+ (lTrackTop + lTrackHeight) * lTrackZoom);
+ pDC->DrawText (strTrackName, rcTrackName, DT_TOP | DT_LEFT);
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldFont);
+
+ // 五線描画
+ i = 0;
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen* pOldPen = pDC->SelectObject (&penKey);
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lTrackTop = pTrackInfo->m_lTop;
+ long lTrackHeight = pTrackInfo->m_lHeight;
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long yc = (lTrackTop + lTrackHeight / 2) * lTrackZoom;
+ long ii;
+ long y;
+ switch (lTrackFlags & 0x0000000F) {
+ case 0:
+ break;
+ case 1: // ト音記号
+ case 2: // ヘ音記号
+ for (ii = -2; ii <= 2; ii++) {
+ y = yc + ii * 2 * ry;
+ pDC->MoveTo (40, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ break;
+ case 3: // 大譜表
+ for (ii = -5; ii <= -1; ii++) {
+ y = yc + ii * 2 * ry;
+ pDC->MoveTo (40, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ for (ii = 1; ii <= 5; ii++) {
+ y = yc + ii * 2 * ry;
+ pDC->MoveTo (40, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ break;
+ }
+ // 大譜表縦線描画
+ long y1, y2;
+ switch (lTrackFlags & 0x0000000F) {
+ case 3:
+ y1 = yc - 10 * ry;
+ y2 = yc + 10 * ry;
+ pDC->FillSolidRect
+ (40 - 1, y1, 1, y2 - y1 + 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ pDC->FillSolidRect
+ (40 - 5, y1, 2, y2 - y1 + 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ }
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldPen);
+
+ // 拍子記号・調性記号の描画
+ i = 0;
+ pOldFont = pDC->SelectObject (&(pMusicalScoreFrame->m_theTimeMeasureFont));
+ long lTimeScrollPos = pMusicalScoreFrame->GetTimeScrollPos ();
+ long lTime = pMusicalScoreFrame->XtoTime (lTimeScrollPos);
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ long lColor = MIDITrack_GetForeColor (pTempTrack);
+ pDC->SetTextColor (lColor);
+ CPen theTrackPen;
+ CBrush theTrackBrush;
+ theTrackPen.CreatePen (PS_SOLID, 1, lColor);
+ theTrackBrush.CreateSolidBrush (lColor);
+ CPen* pOldPen = pDC->SelectObject (&theTrackPen);
+ CBrush* pOldBrush = pDC->SelectObject (&theTrackBrush);
+ DrawTimeAndKeySignature (pDC, i, lTime);
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+ theTrackPen.DeleteObject ();
+ theTrackBrush.DeleteObject ();
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldFont);
+
+
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// メッセージマップ
+//-----------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CMusicalScoreTrackScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ // インプレースエディットの作成
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ m_theTextBox.Create (WS_CHILD /*| WS_VISIBLE | WS_BORDER*/ | ES_AUTOHSCROLL,
+ CRect (40, 0, 80, 12), this, IDC_TEXTBOX);
+ m_theTextBox.SetFont (&(pMusicalScoreFrame->m_theFont));
+
+ SetTimer (0x13, 55, NULL);
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// ウィンドウ破壊時
+void CMusicalScoreTrackScaleView::OnDestroy () {
+ KillTimer (0x13);
+}
+
+// フォーカスを失ったとき
+void CMusicalScoreTrackScaleView::OnKillFocus (CWnd* pNewWnd) {
+ _RPTF1 (_CRT_WARN, "CMusicalScoreTrackScaleView::OnKillFocus (pNewWnd=0x%08x)\n", (long)pNewWnd);
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ // インプレーステキストボックスにフォーカスが移った場合を除き
+ if (pNewWnd != &m_theTextBox && !m_bSettingCellString) {
+ // テキスト編集中の場合はその内容を確定
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CView::OnKillFocus (pNewWnd);
+}
+
+// キーが押された時
+void CMusicalScoreTrackScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ switch (nChar) {
+ // 改行(Enter)キー
+ case VK_RETURN:
+ // テキスト編集中でない場合
+ if (IsTextEditing () == FALSE) {
+ }
+ // テキスト編集中の場合(CInplaceEditクラスからPostMessageされる。)
+ else {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ break;
+ // エスケープ(Esc)キー(CInplaceEditクラスからPostMessageされる。)
+ case VK_ESCAPE:
+ EndTextEditingCancel ();
+ break;
+ // default
+ default:
+ pMusicalScoreFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+
+// マウス左ボタン押された時
+void CMusicalScoreTrackScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+ point += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+
+ // テキスト編集の終了
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ }
+
+ // ボタン部でマウスを押し下げた場合
+ if (0 <= point.x && point.x < 32) {
+ long i = 0;
+
+ // 履歴の記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+
+ m_lOldTrack = pMusicalScoreFrame->YtoTrackIndex (m_ptMouseDown.y);
+ m_lDownTrack = pMusicalScoreFrame->YtoTrackIndex (point.y);
+ m_lCurTrack = pMusicalScoreFrame->YtoTrackIndex (point.y);
+
+ // 該当トラックの全ノートイベントを選択
+ if (nFlags & MK_SHIFT) {
+ long lNumTrack = MIDIData_CountTrack (pMIDIData);
+ if (0 <= m_lCurTrack && m_lCurTrack < lNumTrack) {
+ long lMinTrack = __min (m_lOldTrack, m_lCurTrack);
+ long lMaxTrack = __max (m_lOldTrack, m_lCurTrack);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lMinTrack <= i && i <= lMaxTrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if ((MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent)) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+ }
+ }
+ else {
+ long lNumTrack = MIDIData_CountTrack (pMIDIData);
+ if (0 <= m_lCurTrack && m_lCurTrack < lNumTrack) {
+ pMIDITrack = pSekaijuDoc->GetTrack (m_lCurTrack);
+ }
+ if (pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if ((MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent)) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ Invalidate ();
+ }
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CMusicalScoreTrackScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+
+}
+
+// マウス左ボタン離されたとき
+void CMusicalScoreTrackScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+ point += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+
+ if (GetCapture () == this) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ KillTimer (0x21);
+ ReleaseCapture ();
+
+ long lMinTrack = __min (m_lDownTrack, m_lCurTrack);
+ long lMaxTrack = __max (m_lDownTrack, m_lCurTrack);
+
+ // 該当範囲にあるノートイベントの選択
+ long i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lMinTrack <= i && i <= lMaxTrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if ((MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent)) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CMusicalScoreTrackScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CMusicalScoreTrackScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+ point += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ m_lOldTrack = pMusicalScoreFrame->YtoTrackIndex (m_ptMouseMove.y);
+ m_lCurTrack = pMusicalScoreFrame->YtoTrackIndex (point.y);
+ long lNumTrack = MIDIData_GetNumTrack (pMIDIData);
+ if (0 <= m_lCurTrack && m_lCurTrack < lNumTrack) {
+ // 前回のトラックと今回のトラックが異なる場合のみ
+ if (m_lOldTrack != m_lCurTrack) {
+ // セル再描画
+ Invalidate (FALSE);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CMusicalScoreTrackScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*) GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+
+ // OnLButtonDownを実行し、現在編集中のセルを取りやめ、新しいフォーカスにセルを移動
+ SendMessage (WM_LBUTTONDOWN, nFlags, ((point.y & 0x0000FFFF) << 16) | (point.x & 0x0000FFFF));
+ if (IsTextEditing () == TRUE) {
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+ point += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+
+ if (40 <= point.x && point.x < rcClient.right) {
+ long lCurTrack = pMusicalScoreFrame->YtoTrackIndex (point.y);
+ long lNumTrack = MIDIData_CountTrack (pMIDIData);
+ if (0 <= lCurTrack && lCurTrack < lNumTrack) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lCurTrack);
+ MoveTextBox (lCurTrack);
+ // テキスト編集モードに突入
+ m_lCurTrack = lCurTrack;
+ BeginTextEditing ();
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CMusicalScoreTrackScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CMusicalScoreTrackScaleView::OnTimer (UINT nIDEvent) {
+
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (nIDEvent == 0x13) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeScrollPos = pMusicalScoreFrame->GetTimeScrollPos ();
+ long lTime = pMusicalScoreFrame->XtoTime (lTimeScrollPos);
+ if (lTime != m_lOldTime) {
+ Invalidate ();
+ m_lOldTime = lTime;
+ }
+ }
+ else if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pMusicalScoreFrame->GetTrackScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldTrackScrollPos = pMusicalScoreFrame->GetTrackScrollPos ();
+ if (m_ptMouseMove.y < rcClient.top) {
+ pMusicalScoreFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pMusicalScoreFrame->m_wndTrackScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y >= rcClient.bottom) {
+ pMusicalScoreFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pMusicalScoreFrame->m_wndTrackScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldTrackScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+// マウスホイールが回された時
+void CMusicalScoreTrackScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lTrackScrollPos = pMusicalScoreFrame->GetTrackScrollPos ();
+ long ry = 4;
+ lTrackScrollPos -= ry * 2 * lDelta / WHEELDELTA;
+ pMusicalScoreFrame->SetTrackScrollPos (lTrackScrollPos);
+ }
+}
diff --git a/src/MusicalScoreTrackScaleView.h b/src/MusicalScoreTrackScaleView.h
new file mode 100644
index 0000000..4b74589
--- /dev/null
+++ b/src/MusicalScoreTrackScaleView.h
@@ -0,0 +1,105 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面トラックスケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MUSICALSCORETRACKSCALEVIEW_H_
+#define _MUSICALSCORETRACKSCALEVIEW_H_
+
+#include "InplaceEdit.h"
+
+class CMusicalScoreTrackScaleView : public CSekaijuView {
+protected:
+ DECLARE_DYNCREATE (CMusicalScoreTrackScaleView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたとき前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたとき前回のフラグ
+ long m_lDownTrack; // マウスが押されたときの指すトラック(0〜MAXMIDITRACKNUM-1)
+ long m_lCurTrack; // マウスが動かされたときの現在の指すトラック(0〜MAXMIDITRACKNUM-1)
+ long m_lOldTrack; // マウスが動かされたときの前回の指すトラック(0〜MAXMIDITRACKNUM-1)
+ long m_lOldTime; // 前回のタイム[tick]
+ BOOL m_bSettingCellString; // セルの文字列を編集中であるか
+
+ // テキストボックス
+ CInplaceEdit m_theTextBox;
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMusicalScoreTrackScaleView (); // コンストラクタ
+ virtual ~CMusicalScoreTrackScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+protected:
+ void DrawGClef
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawFClef
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawFlat
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawSharp
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawTimeAndKeySignature
+ (CDC* pDC, long lTrackIndex, long lTime);
+
+ CString GetCellString (long lTrack);
+ BOOL SetCellString (long lTrack, CString strText);
+ BOOL IsTextEditing ();
+ BOOL BeginTextEditing ();
+ BOOL EndTextEditingOK ();
+ BOOL EndTextEditingCancel ();
+ BOOL MoveTextBox (long lTrackIndex);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo = NULL);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnDestroy ();
+ afx_msg void OnKillFocus (CWnd* pNewWnd);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
+
diff --git a/src/MusicalScoreTrackTimeView.cpp b/src/MusicalScoreTrackTimeView.cpp
new file mode 100644
index 0000000..ff63872
--- /dev/null
+++ b/src/MusicalScoreTrackTimeView.cpp
@@ -0,0 +1,3025 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面トラックタイムビュークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "ChildFrame.h"
+#include "ColorfulCheckListBox.h"
+#include "ColorfulComboBox.h"
+#include "MusicalScoreFrame.h"
+#include "MusicalScoreTrackTimeView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CMusicalScoreTrackTimeView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CMusicalScoreTrackTimeView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_TIMER ()
+ ON_WM_KEYDOWN ()
+ ON_WM_KEYUP ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP()
+
+//-----------------------------------------------------------------------------
+// 構築と破壊
+//-----------------------------------------------------------------------------
+
+// コンストラクタ
+CMusicalScoreTrackTimeView::CMusicalScoreTrackTimeView () {
+ m_lCurTime = 0;
+ m_lOldTime = 0;
+ m_lOldY1 = 0;
+ m_lOldY2 = 0;
+ m_bOldDraw = TRUE;
+ m_pTempEvent = NULL;
+ m_lTempMode = 0;
+// m_lMouseDownTime = 0;
+// m_lMouseMoveTime = 0;
+// m_lMouseDownKey = 0;
+// m_lMouseMoveKey = 0;
+ m_pLastEvent = NULL;
+}
+
+// デストラクタ
+CMusicalScoreTrackTimeView::~CMusicalScoreTrackTimeView () {
+}
+
+//-----------------------------------------------------------------------------
+// オペレーション
+//-----------------------------------------------------------------------------
+
+// ノート矩形を取得する(近々廃止予定)
+CRect CMusicalScoreTrackTimeView::GetNoteRect (MIDIEvent* pNoteOnEvent) {
+ ASSERT (pNoteOnEvent);
+ ASSERT (FALSE);
+ // この関数は使わないでください。
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ if (!MIDIEvent_IsNoteOn (pNoteOnEvent)) {
+ return CRect (0,0,0,0);
+ }
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTime = MIDIEvent_GetTime (pNoteOnEvent);
+ long lKey = MIDIEvent_GetKey (pNoteOnEvent);
+ long lDuration = MIDIEvent_GetDuration (pNoteOnEvent);
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lTime, &lsf, &lmi);
+ long lKeySignature = lsf | (lmi << 8);
+ long lTrackIndex = 2; // 仮
+ long x = pMusicalScoreFrame->TimetoX (lTime);
+ long w = pMusicalScoreFrame->TimetoX (lDuration);
+ long y = pMusicalScoreFrame->TrackIndexKeytoY (lTrackIndex, lKey, lKeySignature);
+ long h = pMusicalScoreFrame->GetTrackZoom ();
+ return CRect (x, y - h, x + w, y);
+}
+
+// 音符矩形を取得する(おたまじゃくし部分)
+// 使用前に必ずMIDIData_CountTrackを呼び出すこと。
+CRect CMusicalScoreTrackTimeView::GetNoteRect (MusicalScoreNoteInfo* pNoteInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ long lNoteOnTime = pNoteInfo->m_lNoteOnTime;
+ long lNoteOnMeasure = pNoteInfo->m_lNoteOnMeasure;
+ MusicalScoreMeasureInfo* pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lNoteOnMeasure);
+ long lKeySignature = pMeasureInfo->m_lKeySignature;
+ MIDIEvent* pNoteOnEvent = pNoteInfo->m_pNoteOnEvent;
+ MIDITrack* pTrack = MIDIEvent_GetParent (pNoteOnEvent);
+ long lKey = MIDIEvent_GetKey (pNoteOnEvent);
+ long lNoteX = pMusicalScoreFrame->TimetoX (lNoteOnTime);
+ long lNoteY = pMusicalScoreFrame->TrackIndexKeytoY (pTrack->m_lTempIndex, lKey, lKeySignature);
+ long rx = 4;
+ long ry = 4;
+ return CRect (lNoteX - rx, lNoteY - ry, lNoteX + rx, lNoteY + ry);
+}
+
+// 旧位置の縦線消去
+void CMusicalScoreTrackTimeView::EraseOldLine (CDC* pDC) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ if (rcClient.left <= m_lOldX && m_lOldX <= rcClient.right && m_bOldDraw == TRUE) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_lOldX, m_lOldY1);
+ pDC->LineTo (m_lOldX, m_lOldY2);
+ }
+}
+
+// 現在位置の縦線描画
+void CMusicalScoreTrackTimeView::DrawCurLine (CDC* pDC) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ long x = pMusicalScoreFrame->TimetoX (m_lCurTime);
+ if (rcClient.left <= x && x <= rcClient.right) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ m_bOldDraw = TRUE;
+ m_lOldTime = m_lCurTime;
+ m_lOldX = x;
+ m_lOldY1 = rcClient.top;
+ m_lOldY2 = rcClient.bottom;
+ }
+ else {
+ m_bOldDraw = FALSE;
+ }
+}
+
+// ポップアップメニューの表示
+BOOL CMusicalScoreTrackTimeView::ShowPopupMenu (CPoint ptMenu) {
+
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (m_lTempMode == 0x1001);
+
+ if (m_pTempEvent) {
+ pSekaijuDoc->m_lTempTime = MIDIEvent_GetTime (m_pTempEvent);
+ pSekaijuDoc->m_pTempTrack = m_pTempTrack; // 20110103修正
+ pSekaijuDoc->m_pTempEvent = m_pTempEvent;
+ }
+ else {
+ pSekaijuDoc->m_lTempTime = pSekaijuDoc->m_lNewTime;
+ pSekaijuDoc->m_pTempTrack = m_pTempTrack; // 20110103修正
+ pSekaijuDoc->m_pTempEvent = NULL;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU31));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pMusicalScoreFrame);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lTempMode = 0x0000;
+
+ return TRUE;
+}
+
+// おたまじゃくしを描画する
+void CMusicalScoreTrackTimeView::DrawTadpole
+ (CDC* pDC, long x, long y, long rx, long ry, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ if (lFlags & 0x00010000) {
+ pt[0].x = ptCenter.x + rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry / 2;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y - ry;
+ pt[4].x = ptCenter.x - rx;
+ pt[4].y = ptCenter.y;
+ pt[5].x = ptCenter.x - rx;
+ pt[5].y = ptCenter.y + ry / 2;
+ pt[6].x = ptCenter.x - rx / 2;
+ pt[6].y = ptCenter.y + ry;
+ pt[7].x = ptCenter.x;
+ pt[7].y = ptCenter.y + ry;
+ pt[8].x = ptCenter.x + rx;
+ pt[8].y = ptCenter.y;
+ pDC->Polyline (pt, 9); // 白玉
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y - ry;
+ pt[1].x = ptCenter.x - rx / 2;
+ pt[1].y = ptCenter.y - ry;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y - ry / 2;
+ pt[3].x = ptCenter.x - rx;
+ pt[3].y = ptCenter.y;
+ pDC->Polygon (pt, 4); // 黒縁
+ pt[0].x = ptCenter.x + rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y + ry / 2;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y + ry;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y + ry;
+ pDC->Polygon (pt, 4); // 黒縁
+ }
+ else {
+ pt[0].x = ptCenter.x + rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry / 2;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y - ry;
+ pt[4].x = ptCenter.x - rx;
+ pt[4].y = ptCenter.y;
+ pt[5].x = ptCenter.x - rx;
+ pt[5].y = ptCenter.y + ry / 2;
+ pt[6].x = ptCenter.x - rx / 2;
+ pt[6].y = ptCenter.y + ry;
+ pt[7].x = ptCenter.x;
+ pt[7].y = ptCenter.y + ry;
+ pt[8].x = ptCenter.x + rx;
+ pt[8].y = ptCenter.y;
+ pDC->Polygon (pt, 8); // 黒玉
+ }
+
+}
+
+
+// ト音記号を描画する
+void CMusicalScoreTrackTimeView::DrawGClef
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[21];
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y + ry;
+ pt[1].x = ptCenter.x - rx;
+ pt[1].y = ptCenter.y;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x + rx;
+ pt[3].y = ptCenter.y - ry;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y + ry;
+ pt[6].x = ptCenter.x + rx;
+ pt[6].y = ptCenter.y + ry * 2;
+ pt[7].x = ptCenter.x - rx * 1;
+ pt[7].y = ptCenter.y + ry * 2;
+ pt[8].x = ptCenter.x - rx * 2;
+ pt[8].y = ptCenter.y + ry;
+ pt[9].x = ptCenter.x - rx * 2;
+ pt[9].y = ptCenter.y - ry;
+ pt[10].x = ptCenter.x;
+ pt[10].y = ptCenter.y - ry * 4;
+ pt[11].x = ptCenter.x + rx * 1;
+ pt[11].y = ptCenter.y - ry * 5;
+ pt[12].x = ptCenter.x + rx * 1;
+ pt[12].y = ptCenter.y - ry * 8;
+ pt[13].x = ptCenter.x;
+ pt[13].y = ptCenter.y - ry * 6;
+ pt[14].x = ptCenter.x;
+ pt[14].y = ptCenter.y - ry * 4;
+ pt[15].x = ptCenter.x + rx;
+ pt[15].y = ptCenter.y + ry * 4;
+ pt[16].x = ptCenter.x;
+ pt[16].y = ptCenter.y + ry * 5;
+ pt[17].x = ptCenter.x - rx * 1 / 2;
+ pt[17].y = ptCenter.y + ry * 5;
+ pDC->Polyline (pt, 18);
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y - ry;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x + rx * 2;
+ pt[3].y = ptCenter.y;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y - ry;
+ pt[5].x = ptCenter.x + rx;
+ pt[5].y = ptCenter.y - ry * 2;
+ pt[6].x = ptCenter.x;
+ pt[6].y = ptCenter.y - ry * 2;
+ pt[7].x = ptCenter.x - rx;
+ pt[7].y = ptCenter.y - ry;
+ pDC->Polygon (pt, 8);
+ pt[0].x = ptCenter.x - rx * 2;
+ pt[0].y = ptCenter.y - ry * 1;
+ pt[1].x = ptCenter.x - rx * 2;
+ pt[1].y = ptCenter.y - ry * 2;
+ pt[2].x = ptCenter.x + rx * 1;
+ pt[2].y = ptCenter.y - ry * 6;
+ pt[3].x = ptCenter.x + rx * 1;
+ pt[3].y = ptCenter.y - ry * 5;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y - ry * 6;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y - ry * 7;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y - ry * 8;
+ pt[3].x = ptCenter.x + rx;
+ pt[3].y = ptCenter.y - ry * 7;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x - rx * 1;
+ pt[0].y = ptCenter.y + ry * 9 / 2;
+ pt[1].x = ptCenter.x - rx * 1 / 2;
+ pt[1].y = ptCenter.y + ry * 4;
+ pt[2].x = ptCenter.x;
+ pt[2].y = ptCenter.y + ry * 9 / 2;
+ pt[3].x = ptCenter.x - rx * 1 / 2;
+ pt[3].y = ptCenter.y + ry * 5;
+ pDC->Polygon (pt, 4);
+}
+
+// ヘ音記号を描画する
+void CMusicalScoreTrackTimeView::DrawFClef
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x - rx * 2;
+ pt[1].y = ptCenter.y;
+ pt[2].x = ptCenter.x - rx * 2;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x - rx;
+ pt[3].y = ptCenter.y - ry * 2;
+ pt[4].x = ptCenter.x + rx;
+ pt[4].y = ptCenter.y - ry * 2;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y - ry;
+ pt[6].x = ptCenter.x + rx * 2;
+ pt[6].y = ptCenter.y + ry;
+ pt[7].x = ptCenter.x;
+ pt[7].y = ptCenter.y + ry * 4;
+ pt[8].x = ptCenter.x - rx * 2;
+ pt[8].y = ptCenter.y + ry * 6;
+ pDC->Polyline (pt, 9);
+ pt[0].x = ptCenter.x - rx * 2;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x - rx * 3 / 2;
+ pt[1].y = ptCenter.y - ry * 1 / 2;
+ pt[2].x = ptCenter.x - rx;
+ pt[2].y = ptCenter.y;
+ pt[3].x = ptCenter.x - rx * 3 / 2;
+ pt[3].y = ptCenter.y + ry * 1 / 2;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x;
+ pt[0].y = ptCenter.y - ry * 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry * 1;
+ pt[2].x = ptCenter.x + rx;
+ pt[2].y = ptCenter.y + ry * 1;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y + ry * 4;
+ pt[4].x = ptCenter.x + rx * 2;
+ pt[4].y = ptCenter.y + ry * 1;
+ pt[5].x = ptCenter.x + rx * 2;
+ pt[5].y = ptCenter.y - ry * 1;
+ pt[6].x = ptCenter.x + rx * 1;
+ pt[6].y = ptCenter.y - ry * 2;
+ pDC->Polygon (pt, 7);
+ pt[0].x = ptCenter.x + rx * 3 + rx / 2;
+ pt[0].y = ptCenter.y - ry * 1;
+ pt[1].x = ptCenter.x + rx * 3;
+ pt[1].y = ptCenter.y - ry * 1 - ry / 2;
+ pt[2].x = ptCenter.x + rx * 3 - rx / 2;
+ pt[2].y = ptCenter.y - ry * 1;
+ pt[3].x = ptCenter.x + rx * 3;
+ pt[3].y = ptCenter.y - ry * 1 + ry / 2;
+ pDC->Polygon (pt, 4);
+ pt[0].x = ptCenter.x + rx * 3 + rx / 2;
+ pt[0].y = ptCenter.y + ry * 1;
+ pt[1].x = ptCenter.x + rx * 3;
+ pt[1].y = ptCenter.y + ry * 1 - ry / 2;
+ pt[2].x = ptCenter.x + rx * 3 - ry / 2;
+ pt[2].y = ptCenter.y + ry * 1;
+ pt[3].x = ptCenter.x + rx * 3;
+ pt[3].y = ptCenter.y + ry * 1 + ry / 2;
+ pDC->Polygon (pt, 4);
+}
+
+// ♭の描画
+void CMusicalScoreTrackTimeView::DrawFlat
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y - ry;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y - ry;
+ pt[3].x = ptCenter.x + rx / 2;
+ pt[3].y = ptCenter.y;
+ pt[4].x = ptCenter.x - rx / 2;
+ pt[4].y = ptCenter.y + ry;
+ pt[5].x = ptCenter.x - rx / 2;
+ pt[5].y = ptCenter.y - ry * 4;
+ pDC->Polyline (pt, 6);
+}
+
+// ナチュラルの描画
+void CMusicalScoreTrackTimeView::DrawNatural
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y - ry * 2;
+ pt[1].x = ptCenter.x - rx / 2;
+ pt[1].y = ptCenter.y + ry;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y + ry * 3 / 4;
+ pDC->Polyline (pt, 3);
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y - ry * 3 / 4;
+ pt[1].x = ptCenter.x + rx / 2;
+ pt[1].y = ptCenter.y - ry;
+ pt[2].x = ptCenter.x + rx / 2;
+ pt[2].y = ptCenter.y + ry * 2;
+ pDC->Polyline (pt, 3);
+};
+
+
+// #の描画
+void CMusicalScoreTrackTimeView::DrawSharp
+ (CDC* pDC, long x, long y, long rx, long ry) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[9];
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y + ry + ry / 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y + ry - ry / 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x - rx;
+ pt[0].y = ptCenter.y - ry + ry / 2;
+ pt[1].x = ptCenter.x + rx;
+ pt[1].y = ptCenter.y - ry - ry / 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x - rx / 2;
+ pt[0].y = ptCenter.y - ry * 2;
+ pt[1].x = ptCenter.x - rx / 2;
+ pt[1].y = ptCenter.y + ry * 2;
+ pDC->Polyline (pt, 2);
+ pt[0].x = ptCenter.x + rx / 2;
+ pt[0].y = ptCenter.y - ry * 2;
+ pt[1].x = ptCenter.x + rx / 2;
+ pt[1].y = ptCenter.y + ry * 2;
+ pDC->Polyline (pt, 2);
+};
+
+// 水平補助線を描画する
+void CMusicalScoreTrackTimeView::DrawHorzAuxiliaryLine
+ (CDC* pDC, long x, long y, long r, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x = x;
+ ptCenter.y = y;
+ POINT pt[2];
+ pt[0].x = ptCenter.x - r;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x + r;
+ pt[1].y = ptCenter.y;
+ pDC->Polyline (pt, 2);
+}
+
+// 付点を描画する
+void CMusicalScoreTrackTimeView::DrawDot
+ (CDC* pDC, long x, long y, long rx, long ry, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x = x + rx * 2;
+ ptCenter.y = y - ry / 2;
+ POINT pt[4];
+ pt[0].x = ptCenter.x - 1;
+ pt[0].y = ptCenter.y;
+ pt[1].x = ptCenter.x;
+ pt[1].y = ptCenter.y - 1;
+ pt[2].x = ptCenter.x + 1;
+ pt[2].y = ptCenter.y;
+ pt[3].x = ptCenter.x;
+ pt[3].y = ptCenter.y + 1;
+ pDC->Polygon (pt, 4);
+
+}
+
+// 半タイを描画する
+void CMusicalScoreTrackTimeView::DrawTieHalf
+ (CDC* pDC, long x1, long x2, long y, long rx, long ry, long lFlags) {
+ POINT ptCenter;
+ ptCenter.x;
+ ptCenter.y;
+ POINT pt[3];
+ pt[0].x = (x2 > x1 ? x1 + rx * 1 : x1 - rx * 1);
+ pt[0].y = y + ry * 1;
+ pt[1].x = (x2 > x1 ? x1 + rx * 2 : x1 - rx * 2);
+ pt[1].y = y + ry * 2;
+ pt[2].x = x2;
+ pt[2].y = y + ry * 2;
+ pDC->Polyline (pt, 3);
+
+}
+
+// 縦棒を描画する
+void CMusicalScoreTrackTimeView::DrawPole (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[2];
+ pt[0].x = x1 + rx;
+ pt[0].y = y1;
+ pt[1].x = x1 + rx;
+ pt[1].y = y2;
+ pDC->Polyline (pt, 2);
+}
+
+// 単一旗を描画する
+void CMusicalScoreTrackTimeView::DrawSingleFlag (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[4];
+ pt[0].x = x1 + rx;
+ pt[0].y = y2;
+ pt[1].x = x1 + rx * 3;
+ pt[1].y = y2 + ry * 2;
+ pt[2].x = x1 + rx * 3;
+ pt[2].y = y2 + ry * 3;
+ pt[3].x = x1 + rx;
+ pt[3].y = y2 + ry;
+ pDC->Polygon (pt, 4);
+ pt[0].x = x1 + rx * 3;
+ pt[0].y = y2 + ry * 3;
+ pt[1].x = x1 + rx;
+ pt[1].y = y2 + ry * 5;
+ pDC->Polyline (pt, 2);
+}
+
+// 連続旗を描画する
+void CMusicalScoreTrackTimeView::DrawChainedFlag (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[4];
+ pt[0].x = x1 + rx;
+ pt[0].y = y2;
+ pt[1].x = x2 + rx;
+ pt[1].y = y2;
+ pt[2].x = x2 + rx;
+ pt[2].y = y2 + ry;
+ pt[3].x = x1 + rx;
+ pt[3].y = y2 + ry;
+ pDC->Polygon (pt, 4);
+}
+
+// 3連符号を描画する(20110905追加)
+void CMusicalScoreTrackTimeView::DrawTripletSign (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags) {
+ POINT pt[3];
+ pt[0].x = x1;
+ pt[0].y = y2;
+ pt[1].x = x1;
+ pt[1].y = y1;
+ pt[2].x = (x1 + x2) / 2 - 6;
+ pt[2].y = y1;
+ pDC->Polyline (pt, 3);
+ pt[0].x = (x1 + x2) / 2 + 6;
+ pt[0].y = y1;
+ pt[1].x = x2;
+ pt[1].y = y1;
+ pt[2].x = x2;
+ pt[2].y = y2;
+ pDC->Polyline (pt, 3);
+ CRect rcText ((x1 + x2) / 2 - 6, y1 - 6, (x1 + x2) / 2 + 6, y1 + 6);
+ CString strText;
+ strText.Format (_T("%d"), (lFlags & 0x000000FF));
+ pDC->DrawText (strText, &rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+}
+
+
+// 音符を描画する
+void CMusicalScoreTrackTimeView::DrawNote
+ (CDC* pDC, long lTrackIndex, MusicalScoreNoteInfo* pNoteInfo, long lFlags) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDIEvent* pNoteEvent = pNoteInfo->m_pNoteOnEvent;
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ ASSERT (0 <= lTrackIndex && lTrackIndex < pMusicalScoreFrame->GetTrackInfoCount ());
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackIndex));
+ long lTrackFlags = pTrackInfo->m_lFlags; //pMusicalScoreFrame->GetTrackFlags (lTrackIndex);
+ long lKey = MIDIEvent_GetKey (pNoteEvent);
+ long lDuration = pNoteInfo->m_lNoteOffTime - pNoteInfo->m_lNoteOnTime;
+ long lNoteOnMeasure = pNoteInfo->m_lNoteOnMeasure;
+ MusicalScoreMeasureInfo* pMeasureInfo = NULL;
+ ASSERT (0 <= lNoteOnMeasure && lNoteOnMeasure < pMusicalScoreFrame->GetMeasureInfoCount ());
+ VERIFY (pMeasureInfo = pMusicalScoreFrame->GetMeasureInfo (lNoteOnMeasure));
+ long lKeySignature = pMeasureInfo->m_lKeySignature; // この小節の調性記号
+ long lTimeSignature = pMeasureInfo->m_lTimeSignature; // この小節の拍子記号
+ long lLineNo = pMusicalScoreFrame->KeytoLineNo (lKey, lKeySignature);
+ long lSF = pMusicalScoreFrame->KeytoSF (lKey, lKeySignature);
+ long lnn = lTimeSignature & 0xFF;
+ long ldd = (lTimeSignature & 0xFF00) >> 8;
+
+ long x = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOnTime);
+ long y = 0;
+ long rx = 4;
+ long ry = 4;
+ long i = 0;
+
+ // 水平補助線の描画
+ switch (lTrackFlags & 0x0000000F) {
+ case 1: // ト音記号
+ if (lLineNo >= 47) {
+ for (i = 47; i <= lLineNo; i += 2) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ else if (lLineNo <= 35) {
+ for (i = 35; i >= lLineNo; i -= 2) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ break;
+ case 2: // ヘ音記号
+ if (lLineNo >= 35) {
+ for (i = 35; i <= lLineNo; i += 2) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ else if (lLineNo <= 23) {
+ for (i = 23; i >= lLineNo; i -= 2) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ break;
+ case 3: // 大譜表
+ if (lLineNo >= 47) {
+ for (i = 47; i <= lLineNo; i += 2) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ else if (lLineNo == 35) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 35);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ else if (lLineNo <= 23) {
+ for (i = 23; i >= lLineNo; i -= 2) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, i);
+ pDC->MoveTo (x - rx * 2, y);
+ pDC->LineTo (x + rx * 2, y);
+ }
+ }
+ break;
+ }
+ // 臨時記号の描画
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lLineNo);
+ switch (lSF) {
+ case 0:
+ break;
+ case 2:
+ DrawFlat (pDC, x - 4 * rx, y, rx, ry);
+ DrawFlat (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 3:
+ DrawFlat (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 4:
+ DrawNatural (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 5:
+ DrawSharp (pDC, x - 2 * rx, y, rx, ry);
+ break;
+ case 6:
+ DrawSharp (pDC, x - 2 * rx, y, rx, ry);
+ DrawSharp (pDC, x - 4 * rx, y, rx, ry);
+ break;
+ }
+
+
+ // おたまじゃくしの描画
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lLineNo);
+ long lFlags2 = 0;
+ if (lDuration >= lTimeResolution * 2) {
+ lFlags2 |= 0x00010000; // 白丸
+ }
+ if (lDuration < lTimeResolution * lnn * 4 / ldd) {
+ lFlags2 |= 0x00100000; // 縦線あり
+ }
+ DrawTadpole (pDC, x, y, rx, ry, lFlags2);
+
+ // 付点の描画
+ if (lDuration == lTimeResolution * 3 ||
+ lDuration == lTimeResolution * 3 / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution * 3 / 8) {
+ DrawDot (pDC, x, y, rx, ry, lFlags2);
+ }
+
+ // 半タイの描画
+ long x2 = 0;
+ long lPreWidth = 0;
+ long lPostWidth = 0;
+ switch (pNoteInfo->m_lFlags & 0x0000000F) {
+ case 1: // ♪_
+ x2 = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOffTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 2: // _♪
+ x2 = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOnTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 3: // _♪_
+ x2 = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOffTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOnTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 4: // ♪_|
+ x2 = pMusicalScoreFrame->MeasuretoX (pNoteInfo->m_lNoteOffMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 5: // |_♪
+ x2 = pMusicalScoreFrame->MeasuretoX (pNoteInfo->m_lNoteOnMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 6: // _♪_|
+ x2 = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOnTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = pMusicalScoreFrame->MeasuretoX (pNoteInfo->m_lNoteOffMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 7: // |_♪_
+ x2 = pMusicalScoreFrame->MeasuretoX (pNoteInfo->m_lNoteOnMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOffTime - 15);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ case 8: // |_全音符_|
+ x2 = pMusicalScoreFrame->MeasuretoX (pNoteInfo->m_lNoteOnMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ x2 = pMusicalScoreFrame->MeasuretoX (pNoteInfo->m_lNoteOffMeasure);
+ DrawTieHalf (pDC, x, x2, y, rx, ry, lFlags2);
+ break;
+ }
+
+ // 棒の描画(20110905修正)
+ long lPoleKey = lKey;
+ MusicalScoreNoteGroupInfo* pNoteGroupInfo = (MusicalScoreNoteGroupInfo*)(pNoteInfo->m_pNoteGroupInfo);
+ if (pNoteGroupInfo) { // 旗つきの場合
+ lPoleKey = pNoteGroupInfo->m_lMaxKey;
+ }
+ long lLineNo2 = pMusicalScoreFrame->KeytoLineNo (lPoleKey, lKeySignature);
+ long y2 = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lLineNo2);
+ if (lDuration < lTimeResolution * 4) {
+ DrawPole (pDC, x, x2, y, y2 - ry * 7, rx, ry, lFlags2);
+ }
+
+ // 旗の描画
+ if (lDuration < lTimeResolution && lDuration != lTimeResolution * 2 / 3) {
+ // グループ内の音符の時刻が単一の場合
+ if (pNoteGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime == pNoteGroupInfo->m_pLastNoteInfo->m_lNoteOnTime) {
+ // 8分音符、付点8分音符、3連8分音符、16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution / 3 ||
+ lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawSingleFlag (pDC, x, x2, y, y2 - ry * 7, rx, ry, lFlags2);
+ }
+ // 16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawSingleFlag (pDC, x, x2, y, y2 - ry * 5, rx, ry, lFlags2);
+ }
+ // 32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawSingleFlag (pDC, x, x2, y, y2 - ry * 3, rx, ry, lFlags2);
+ }
+ }
+ // グループ内の音符が複数の時刻にまたがる場合
+ else {
+ long x1[3]; // 連旗左座標[1段目,2段目,3段目]
+ long x2[3]; // 連旗右座標[1段目,2段目,3段目]
+ // グループ内の最初の時刻の音符である場合
+ if (pNoteGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime == pNoteInfo->m_lNoteOnTime) {
+ x1[0] = x1[1] = x1[2] = x;
+ x2[0] = x2[1] = x2[2] = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOffTime - lTimeResolution / 8);
+ }
+ // グループ内の最後の時刻の音符である場合
+ else if (pNoteGroupInfo->m_pLastNoteInfo->m_lNoteOnTime == pNoteInfo->m_lNoteOnTime) {
+ x1[0] = x1[1] = x1[2] = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOnTime - lTimeResolution / 8);
+ x2[0] = x2[1] = x2[2] = x;
+ }
+ // グループ内の途中の時刻の音符である場合
+ else {
+ x1[0] = x1[1] = x1[2] = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOnTime - lTimeResolution / 8);
+ x2[0] = x2[1] = x2[2] = pMusicalScoreFrame->TimetoX (pNoteInfo->m_lNoteOffTime - lTimeResolution / 8);
+ // 前の時刻の音符を取得
+ MusicalScoreNoteInfo* pPrevNoteInfo = pNoteInfo;
+ long lPrevDuration = 0;
+ while (pPrevNoteInfo) {
+ if (pPrevNoteInfo->m_lNoteOnTime < pNoteInfo->m_lNoteOnTime) {
+ break;
+ }
+ pPrevNoteInfo = pPrevNoteInfo->m_pPrevNoteInfo;
+ }
+ if (pPrevNoteInfo && pPrevNoteInfo->m_pNoteGroupInfo == pNoteGroupInfo) {
+ lPrevDuration = pPrevNoteInfo->m_lNoteOffTime - pPrevNoteInfo->m_lNoteOnTime;
+ }
+ // 次の時刻の音符を取得
+ MusicalScoreNoteInfo* pNextNoteInfo = pNoteInfo;
+ long lNextDuration = 0;
+ while (pNextNoteInfo) {
+ if (pNextNoteInfo->m_lNoteOnTime > pNoteInfo->m_lNoteOnTime) {
+ break;
+ }
+ pNextNoteInfo = pNextNoteInfo->m_pNextNoteInfo;
+ }
+ if (pNextNoteInfo && pNextNoteInfo->m_pNoteGroupInfo == pNoteGroupInfo) {
+ lNextDuration = pNextNoteInfo->m_lNoteOffTime - pNextNoteInfo->m_lNoteOnTime;
+ }
+ // 1段目の連旗取り消し
+ if (lDuration == lTimeResolution / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution / 3 ||
+ lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ if (lNextDuration == 0) {
+ x2[0] = x;
+ }
+ else if (lPrevDuration == 0) {
+ x1[0] = x;
+ }
+ }
+ // 2段目の連旗取り消し
+ if (lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ if (lNextDuration >= lDuration * 2 || lNextDuration == 0) {
+ x2[1] = x;
+ }
+ else if (lPrevDuration >= lDuration * 2 || lPrevDuration == 0) {
+ x1[1] = x;
+ }
+ }
+ // 3段目の連旗取り消し
+ if (lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ if (lNextDuration >= lDuration * 2 || lNextDuration == 0) {
+ x2[2] = x;
+ }
+ else if (lPrevDuration >= lDuration * 2 || lPrevDuration == 0) {
+ x1[2] = x;
+ }
+ }
+ }
+ // 連旗1段目
+ // 8分音符、付点8分音符、3連8分音符、16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 2 ||
+ lDuration == lTimeResolution * 3 / 4 ||
+ lDuration == lTimeResolution / 3 ||
+ lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawChainedFlag (pDC, x1[0], x2[0], y, y2 - ry * 7, rx, ry, lFlags2);
+ }
+ // 連旗2段目描画
+ // 16分音符、付点16分音符、3連16分音符、32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 4 ||
+ lDuration == lTimeResolution * 3 / 8 ||
+ lDuration == lTimeResolution / 6 ||
+ lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawChainedFlag (pDC, x1[1], x2[1], y, y2 - ry * 5, rx, ry, lFlags2);
+ }
+ // 連旗3段目描画
+ // 32分音符、3連32分音符
+ if (lDuration == lTimeResolution / 8 ||
+ lDuration == lTimeResolution / 12) {
+ DrawChainedFlag (pDC, x1[2], x2[2], y, y2 - ry * 3, rx, ry, lFlags2);
+ }
+ }
+ }
+
+ // 3連符号の描画(20110905追加)
+ if (pNoteInfo->m_pTripletGroupInfo) {
+ MusicalScoreTripletGroupInfo* pTripletGroupInfo =
+ (MusicalScoreTripletGroupInfo*)(pNoteInfo->m_pTripletGroupInfo);
+ if (pTripletGroupInfo->m_pFirstNoteInfo == pNoteInfo) {
+ long x1 = pMusicalScoreFrame->TimetoX (pTripletGroupInfo->m_pFirstNoteInfo->m_lNoteOnTime);
+ long x2 = pMusicalScoreFrame->TimetoX (pTripletGroupInfo->m_pLastNoteInfo->m_lNoteOnTime);
+ long lMinLineNo = pMusicalScoreFrame->KeytoLineNo (pTripletGroupInfo->m_lMinKey, lKeySignature);
+ long y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lMinLineNo);
+ long n12 = 12 * lTimeResolution / pTripletGroupInfo->m_lMinDur; // 12 * 3 or 12 * 6 or 12 * 12
+ long lSpan = pTripletGroupInfo->m_lEndTime - pTripletGroupInfo->m_lBeginTime;
+ if (lSpan >= 1) {
+ if (12 * lTimeResolution / lSpan >= 1) {
+ n12 /= (12 * lTimeResolution / lSpan);
+ }
+ else {
+ n12 /= 12;
+ }
+ }
+ else {
+ n12 /= 12;
+ }
+ DrawTripletSign (pDC, x1, x2, y + 4 * ry, y + 3 * ry, rx, ry, n12);
+ }
+ }
+
+}
+
+// 拍子記号・調性記号の描画
+void CMusicalScoreTrackTimeView::DrawTimeAndKeySignature
+ (CDC* pDC, long lTrackIndex, long lTime) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (0 <= lTrackIndex && lTrackIndex < pMusicalScoreFrame->GetTrackInfoCount ());
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (lTrackIndex));
+ long lTrackFlags = pTrackInfo->m_lFlags;//pMusicalScoreFrame->GetTrackFlags (lTrackIndex);
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ long x = pMusicalScoreFrame->MeasuretoX (lMeasure);
+ long y;// = pMusicalScoreFrame->TrackIndexKeytoY (lTrackIndex, lKey, lKeySignature);
+ long rx = 4; //pMusicalScoreFrame->GetTrackZoom ();
+ long ry = 4;
+ long lGCrefSharpLineNo[7] = {45, 42, 46, 43, 40, 44, 41};
+ long lFCrefSharpLineNo[7] = {31, 28, 32, 29, 33, 30, 34};
+ long lGCrefFlatLineNo[7] = {41, 44, 40, 43, 39, 42, 38};
+ long lFCrefFlatLineNo[7] = {27, 30, 26, 29, 25, 28, 24};
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lTime, &lsf, &lmi);
+ long lnn, ldd, lcc, lbb;
+ MIDIData_FindTimeSignature (pMIDIData, lTime, &lnn, &ldd, &lcc, &lbb);
+ CString strText1;
+ CString strText2;
+ strText1.Format (_T("%d"), lnn);
+ strText2.Format (_T("%d"), (1 << ldd));
+ CRect rcText1 (x + rx * 10 + rx * 2 * abs(lsf), 0, x + rx * 10 + rx * 2 * abs(lsf) + 24, 0);
+ CRect rcText2 (x + rx * 10 + rx * 2 * abs(lsf), 0, x + rx * 10 + rx * 2 * abs(lsf) + 24, 0);
+ long j;
+ switch (lTrackFlags & 0x0000000F) {
+ case 1: // ト音記号
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 39);
+ DrawGClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 41);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ case 2: // ヘ音記号
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 31);
+ DrawFClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 29);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ case 3: // 大譜表
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 39);
+ DrawGClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lGCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 41);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 31);
+ DrawFClef (pDC, x + rx * 4, y, rx, ry);
+ if (lsf > 0) {
+ for (j = 1; j <= lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefSharpLineNo[j - 1]);
+ DrawSharp (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ else if (lsf < 0) {
+ for (j = 1; j <= -lsf; j++) {
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, lFCrefFlatLineNo[j - 1]);
+ DrawFlat (pDC, x + rx * 8 + rx * 2 * j, y, rx, ry);
+ }
+ }
+ y = pMusicalScoreFrame->TrackIndexLineNotoY (lTrackIndex, 29);
+ rcText1.top = y - ry * 4;
+ rcText1.bottom = y;
+ pDC->DrawText (strText1, &rcText1, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ rcText2.top = y;
+ rcText2.bottom = y + ry * 4;
+ pDC->DrawText (strText2, &rcText2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ break;
+ }
+
+}
+
+
+
+//-----------------------------------------------------------------------------
+// オーバーライド
+//-----------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CMusicalScoreTrackTimeView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ pDC->SetWindowOrg (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+}
+
+// 描画
+void CMusicalScoreTrackTimeView::OnDraw (CDC* pDC) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[1]);
+ CPen penBeat (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen penOctave (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[1]);
+ CFont* pOldFont = NULL;
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ pDC->SetBkMode (TRANSPARENT);
+ long x, y, lTime;
+ long lVisibleLeftTime = pMusicalScoreFrame->GetVisibleLeftTime ();
+ long lVisibleRightTime = pMusicalScoreFrame->GetVisibleRightTime ();
+ long lVisibleTopTrack = pMusicalScoreFrame->GetVisibleTopTrack ();
+ long lVisibleBottomTrack = pMusicalScoreFrame->GetVisibleBottomTrack ();
+ long lLeftMeasure, lLeftBeat, lLeftTick;
+ long lRightMeasure, lRightBeat, lRightTick;
+ long lnn, ldd, lcc, lbb;
+ long lUnitTick;
+
+ // 背景の描画
+ pDC->FillSolidRect (rcClient, pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+
+ // 五線の描画
+ CPen* pOldPen = pDC->SelectObject (&penKey);
+ long lTrackZoom = pMusicalScoreFrame->GetTrackZoom ();
+ long rx = 4;
+ long ry = 4;
+ long i, j;
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ ASSERT (0 <= i && i < pMusicalScoreFrame->GetTrackInfoCount ());
+ MusicalScoreTrackInfo* pTrackInfo = NULL;
+ VERIFY (pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i));
+ long lTrackTop = pTrackInfo->m_lTop;
+ long lTrackHeight = pTrackInfo->m_lHeight;
+ long lTrackFlags = pTrackInfo->m_lFlags;
+ long yc = (lTrackTop + lTrackHeight / 2) * lTrackZoom;
+ long ii;
+ switch (lTrackFlags & 0x0000000F) {
+ case 0: // 表示しない
+ break;
+ case 1: // ト音記号
+ case 2: // ヘ音記号
+ for (ii = -2; ii <= 2; ii++) {
+ y = yc + ii * 2 * ry;
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ break;
+ case 3: // 大譜表
+ for (ii = -5; ii <= -1; ii++) {
+ y = yc + ii * 2 * ry;
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ for (ii = 1; ii <= 5; ii++) {
+ y = yc + ii * 2 * ry;
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ // 縦線の描画
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ MIDIData_BreakTime (pMIDIData, lVisibleLeftTime, &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_BreakTime (pMIDIData, lVisibleRightTime, &lRightMeasure, &lRightBeat, &lRightTick);
+ for (i = lLeftMeasure; i <= lRightMeasure; i++) {
+ // 小節線の描画
+ MIDIData_MakeTimeEx (pMIDIData, i, 0, 0, &lTime, &lnn, &ldd, &lcc, &lbb);
+ x = pMusicalScoreFrame->MeasuretoX (i);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ // 拍線の描画
+ pDC->SelectObject (&penBeat);
+ lUnitTick = lTimeResolution * 4 / (1 << ldd);
+ for (long j = 0; j < lnn; j++) {
+ x = pMusicalScoreFrame->TimetoX (lTime + j * lUnitTick);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ }
+ }
+ }
+ else {
+ long lLeftFrameNumber = lVisibleLeftTime / lTimeResolution;
+ long lRightFrameNumber = lVisibleRightTime / lTimeResolution;
+ for (i = lLeftFrameNumber; i <= lRightFrameNumber; i++) {
+ // フレーム境界線の描画
+ lTime = i * lTimeResolution;
+ x = pMusicalScoreFrame->TimetoX (lTime);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+
+ // 拍子記号・調整記号の描画
+ CPen theTrackPen;
+ CBrush theTrackBrush;
+ pOldFont = pDC->SelectObject (&(pMusicalScoreFrame->m_theTimeMeasureFont));
+ pMIDITrack = pMIDIData->m_pFirstTrack;
+ if (pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (MIDIEvent_IsTimeSignature (pMIDIEvent) ||
+ MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ if (lVisibleLeftTime <= lTime && lTime <= lVisibleRightTime) {
+ i = 0;
+ MIDITrack* pTempTrack;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ long lColor = MIDITrack_GetForeColor (pTempTrack);
+ pDC->SetTextColor (lColor);
+ theTrackPen.CreatePen (PS_SOLID, 1, lColor);
+ theTrackBrush.CreateSolidBrush (lColor);
+ CPen* pOldPen = pDC->SelectObject (&theTrackPen);
+ CBrush* pOldBrush = pDC->SelectObject (&theTrackBrush);
+ DrawTimeAndKeySignature (pDC, i, lTime);
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+ theTrackPen.DeleteObject ();
+ theTrackBrush.DeleteObject ();
+ }
+ i++;
+ }
+ }
+ }
+ }
+ }
+ pDC->SelectObject (pOldFont);
+
+ // 音符の描画(pNoteEventは失効していることがあるのでpNoteInfoのみを参照すること)
+ CPen penBar (PS_SOLID, 1, RGB (0, 0, 0));
+ pDC->SelectObject (&penBar);
+ pOldFont = pDC->SelectObject (&(pMusicalScoreFrame->m_theFont));
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ if (lVisibleTopTrack <= i && i <= lVisibleBottomTrack) {
+ long lColor = MIDITrack_GetForeColor (pMIDITrack);
+ pDC->SetTextColor (lColor);
+ CPen theSelectedPen;
+ CBrush theSelectedBrush;
+ theTrackPen.CreatePen (PS_SOLID, 1, lColor);
+ theTrackBrush.CreateSolidBrush (lColor);
+ theSelectedPen.CreatePen (PS_SOLID, 1, RGB (0, 0, 0));
+ theSelectedBrush.CreateSolidBrush (RGB (0, 0, 0));
+ MusicalScoreTrackInfo* pTrackInfo = (MusicalScoreTrackInfo*)(pMusicalScoreFrame->m_theTrackInfoArray.GetAt (i));
+ long jMax = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ for (j = 0; j < jMax; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ if (lVisibleLeftTime <= pNoteInfo->m_lNoteOnTime && pNoteInfo->m_lNoteOnTime <= lVisibleRightTime ||
+ lVisibleRightTime <= pNoteInfo->m_lNoteOffTime && pNoteInfo->m_lNoteOffTime < lVisibleRightTime ||
+ pNoteInfo->m_lNoteOnTime <= lVisibleLeftTime && lVisibleRightTime < pNoteInfo->m_lNoteOffTime) {
+ CPen* pOldPen = pDC->SelectObject (pNoteInfo->m_lSelected ? &theSelectedPen : &theTrackPen);
+ CBrush* pOldBrush = pDC->SelectObject (pNoteInfo->m_lSelected ? & theSelectedBrush : &theTrackBrush);
+ DrawNote (pDC, i, pNoteInfo, 0x00000000);
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+ }
+ }
+ theTrackPen.DeleteObject ();
+ theTrackBrush.DeleteObject ();
+ }
+ }
+ i++;
+ }
+ pDC->SelectObject (pOldFont);
+ pDC->SelectObject (pOldPen);
+
+ // 現在位置の描画
+ DrawCurLine (pDC);
+
+ // マウストラッカーが必要な場合、マウストラッカーの描画
+ if (GetCapture () == this) {
+ if (m_lTempMode == 0x0401) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseDown.y);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseMove.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseDown.x, m_ptMouseMove.y);
+ pDC->MoveTo (m_ptMouseMove.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ Sleep (0);
+}
+
+// ビューの更新
+void CMusicalScoreTrackTimeView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ PostMessage (WM_TIMER, 0x11, NULL);
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+// ウィンドウクラスの変更
+BOOL CMusicalScoreTrackTimeView::PreCreateWindow (CREATESTRUCT& cs) {
+ CView::PreCreateWindow (cs);
+ cs.lpszClass = AfxRegisterWndClass
+ (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS,
+ NULL, // デフォルトカーソル無し
+ (HBRUSH)::GetStockObject (WHITE_BRUSH), // デフォルト背景ブラシ
+ NULL); // デフォルトアイコン無し
+ return TRUE;
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// メッセージマップ
+//-----------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CMusicalScoreTrackTimeView::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+ SetTimer (0x11, 55, NULL);
+ return CSekaijuView::OnCreate (lpCreateStruct);
+}
+
+// ウィンドウ破棄時
+void CMusicalScoreTrackTimeView::OnDestroy () {
+ KillTimer (0x11);
+ CSekaijuView::OnDestroy ();
+}
+
+// タイマー呼び出し時
+void CMusicalScoreTrackTimeView::OnTimer (UINT nIDEvent) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 演奏・記録中のカレントバー移動処理
+ if (nIDEvent == 0x11) {
+ if (pSekaijuDoc->m_pMIDIData && pSekaijuDoc->m_pMIDIClock) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CDC* pDC = GetDC ();
+ OnPrepareDC (pDC, NULL);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ m_lCurTime = MIDIClock_GetTickCount (GetDocument ()->m_pMIDIClock);
+ // 前回の時刻と現在の時刻が違っている場合のみ
+ if (m_lOldTime != m_lCurTime) {
+ EraseOldLine (pDC);
+ DrawCurLine (pDC);
+ }
+ // ページの更新およびオートスクロール(手動スクロール時はしない)
+ if (pMusicalScoreFrame->m_bAutoPageUpdate == TRUE) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ // 現在位置が右側へはみ出した場合
+ long lRightMeasure; long lRightBeat; long lRightTick; long lTempRightTime;
+ MIDIData_BreakTime (GetDocument()->m_pMIDIData, pMusicalScoreFrame->GetVisibleRightTime (),
+ &lRightMeasure, &lRightBeat, &lRightTick);
+ MIDIData_MakeTime (GetDocument()->m_pMIDIData, lRightMeasure, 0, 0, &lTempRightTime);
+ if (m_lCurTime >= lTempRightTime) {
+ long lNewMeasure; long lNewBeat; long lNewTick;
+ MIDIData_BreakTime (pMIDIData, m_lCurTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ //MIDIData_MakeTime (pMIDIData, lNewMeasure, 0, 0, &lTempRightTime);
+ //int x = pMusicalScoreFrame->TimetoXMM (lTempRightTime) + 1;
+ int x = pMusicalScoreFrame->MeasuretoX2 (lNewMeasure) + 1;
+ pMusicalScoreFrame->SetTimeScrollPos (x);
+ }
+ // 現在位置が左側へはみ出した場合
+ long lLeftMeasure; long lLeftBeat; long lLeftTick; long lTempLeftTime;
+ MIDIData_BreakTime (GetDocument()->m_pMIDIData, pMusicalScoreFrame->GetVisibleLeftTime (),
+ &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_MakeTime (GetDocument()->m_pMIDIData, lLeftMeasure, 0, 0, &lTempLeftTime);
+ if (m_lCurTime < lTempLeftTime) {
+ long lNewMeasure; long lNewBeat; long lNewTick;
+ MIDIData_BreakTime (GetDocument()->m_pMIDIData, m_lCurTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ //MIDIData_MakeTime (GetDocument()->m_pMIDIData, lNewMeasure, 0, 0, &lTempLeftTime);
+ //int x = pMusicalScoreFrame->TimetoXMM (lTempLeftTime) + 1;
+ int x = pMusicalScoreFrame->MeasuretoX2 (lNewMeasure) + 1;
+ pMusicalScoreFrame->SetTimeScrollPos (x);
+ }
+ }
+ else {
+ // 現在位置が右側へはみ出した場合
+ long lRightFrameNumber = pMusicalScoreFrame->GetVisibleRightTime () / lTimeResolution;
+ long lTempRightTime = lRightFrameNumber * lTimeResolution;
+ if (m_lCurTime >= lTempRightTime) {
+ //lTempRightTime = (m_lCurTime / lTimeResolution) * lTimeResolution;
+ //long x = pMusicalScoreFrame->TimetoXMM (lTempRightTime) + 1;
+ long lNewFrameNumber = m_lCurTime / lTimeResolution;
+ int x = pMusicalScoreFrame->MeasuretoX2 (lNewFrameNumber) + 1;
+ pMusicalScoreFrame->SetTimeScrollPos (x);
+ }
+ // 現在位置が左側へはみ出した場合
+ long lLeftFrameNumber = pMusicalScoreFrame->GetVisibleLeftTime () / lTimeResolution;
+ long lTempLeftTime = lLeftFrameNumber * lTimeResolution;
+ if (m_lCurTime < lTempLeftTime) {
+ //lTempLeftTime = (m_lCurTime / lTimeResolution) * lTimeResolution;
+ //long x = pMusicalScoreFrame->TimetoXMM (lTempLeftTime) + 1;
+ long lNewFrameNumber = m_lCurTime / lTimeResolution;
+ int x = pMusicalScoreFrame->MeasuretoX2 (lNewFrameNumber) + 1;
+ pMusicalScoreFrame->SetTimeScrollPos (x);
+ }
+ }
+ }
+ ReleaseDC (pDC);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理
+ else if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ long lOldTimeScrollPos = pMusicalScoreFrame->GetTimeScrollPos ();
+ long lOldTrackScrollPos = pMusicalScoreFrame->GetTrackScrollPos ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (m_ptMouseMove.x < rcClient.left) {
+ pMusicalScoreFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pMusicalScoreFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.x > rcClient.right) {
+ pMusicalScoreFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pMusicalScoreFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ if (m_ptMouseMove.y < rcClient.top) {
+ pMusicalScoreFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pMusicalScoreFrame->m_wndTrackScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y > rcClient.bottom) {
+ pMusicalScoreFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pMusicalScoreFrame->m_wndTrackScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x - lOldTimeScrollPos);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldTrackScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+
+// キーが押された時
+void CMusicalScoreTrackTimeView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ long lOldKey = m_lMouseMoveKey;
+ switch (nChar) {
+ // DEL
+ case VK_DELETE:
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CHistoryUnit* pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ switch (m_lTempTool) {
+ // ペン
+ case ID_MUSICALSCORE_PEN:
+ if ((m_lTempMode == 0x0101 || m_lTempMode == 0x0103) && m_pTempEvent != NULL) {
+ ASSERT (m_pTempTrack);
+ // 置こうとしているノート又は移動中のノート削除
+ if (m_lTempMode = 0x0101) {
+ MIDIEvent_Delete (m_pTempEvent);
+ m_pTempEvent = NULL;
+ }
+ else if (m_lTempMode = 0x0103) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempEvent);
+ MIDITrack_RemoveEvent (m_pTempTrack, m_pTempEvent);
+ }
+ // 履歴記録
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ // 古いキー消音
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ BYTE byMIDIMessage[3];
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ ReleaseCapture ();
+ KillTimer (0x21);
+ m_lTempMode = 0;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ break;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ break;
+ // ESC
+ case VK_ESCAPE:
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CHistoryUnit* pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ switch (m_lTempTool) {
+ // ペン
+ case ID_MUSICALSCORE_PEN:
+ if (m_lTempMode == 0x0101 && m_pTempEvent != NULL) {
+ ASSERT (m_pTempTrack);
+ // 置こうとしているノート廃止
+ MIDIEvent_Delete (m_pTempEvent);
+ m_pTempEvent = NULL;
+ // 履歴記録
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ // 古いキー消音
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ BYTE byMIDIMessage[3];
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ ReleaseCapture ();
+ KillTimer (0x21);
+ m_lTempMode = 0;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ break;
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ break;
+ // Control
+ case VK_CONTROL:
+ // キャプター中でない場合のみ
+ if (GetCapture () != this) {
+ WORD wX = (WORD)(m_ptMouseMove.x - pMusicalScoreFrame->GetTimeScrollPos ());
+ WORD wY = (WORD)(m_ptMouseMove.y - pMusicalScoreFrame->GetTrackScrollPos ());
+ UINT nFlags = m_nMouseMoveFlags | MK_CONTROL;
+ PostMessage (WM_MOUSEMOVE, (WPARAM)nFlags, (LPARAM)((wY << 16) | wX));
+ }
+ break;
+ // default
+ default:
+ pMusicalScoreFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+
+// キーが離された時
+void CMusicalScoreTrackTimeView::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ switch (nChar) {
+ // Control
+ case VK_CONTROL:
+ // キャプター中でない場合のみ
+ if (GetCapture () != this) {
+ WORD wX = (WORD)(m_ptMouseMove.x - pMusicalScoreFrame->GetTimeScrollPos ());
+ WORD wY = (WORD)(m_ptMouseMove.y - pMusicalScoreFrame->GetTrackScrollPos ());
+ UINT nFlags = m_nMouseMoveFlags & (~MK_CONTROL);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)nFlags, (LPARAM)((wY << 16) | wX));
+ }
+ break;
+ }
+ return;
+}
+
+// マウス左ボタン押された時
+void CMusicalScoreTrackTimeView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ point += sizWndOrg;
+ ASSERT (m_pTempEvent == NULL);
+ ASSERT (m_lTempMode == 0);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lsf, lmi;
+ m_lTempTime = pMusicalScoreFrame->XtoTime (point.x);
+ m_lMouseDownTime = m_lTempTime;
+ m_lMouseMoveTime = m_lTempTime;
+ MIDIData_FindKeySignature (pMIDIData, m_lTempTime, &lsf, &lmi);
+ long lKeySignature = lsf | (lmi << 8);
+ m_lTempTool = pMusicalScoreFrame->m_lCurTool;
+ m_lTempChannel = pMusicalScoreFrame->GetCurChannel ();
+ m_lTempChannel = CLIP (0, m_lTempChannel, 15);
+ m_lTempVelocity = pMusicalScoreFrame->GetCurVelocity ();
+ m_lTempVelocity = CLIP (1, m_lTempVelocity, 127);
+ m_lTempDuration = pMusicalScoreFrame->GetCurDuration ();
+ m_lTempDuration = CLIP (1, m_lTempDuration, 65535);
+ m_lTempSnap = pMusicalScoreFrame->GetCurSnap ();
+ m_lTempSnap = CLIP (1, m_lTempSnap, MIDIData_GetTimeResolution (pMIDIData));
+ m_pTempEvent = NULL;
+ m_pLastEvent = NULL;
+ BOOL bPtInNote = FALSE;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ CString strHistoryName;
+ BYTE byMIDIMessage[3];
+ long i = 0;
+ switch (m_lTempTool) {
+ // ペン
+ case ID_MUSICALSCORE_PEN:
+ // 既存のノートの上にマウスが置かれた場合
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ long lPort = MIDITrack_GetOutputPort (pTempTrack);
+ if (0 <= lPort && lPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[lPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[lPort];
+ }
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ CRect rcNote = GetNoteRect (pNoteInfo);
+ // 既存の音符上をクリックした場合
+ if (rcNote.top <= point.y && point.y < rcNote.bottom) {
+ if (rcNote.left <= point. x && point.x < rcNote.right) {
+ // フォーマット1のMIDIデータで最初のトラックにノートを置くのを禁止
+ if (lFormat == 1 && i == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ pTempEvent = pNoteInfo->m_pNoteOnEvent;
+ pMusicalScoreFrame->SetCurTrackIndex (i);
+ pMusicalScoreFrame->SetCurVelocity (MIDIEvent_GetVelocity (pTempEvent));
+ pMusicalScoreFrame->SetCurDuration (MIDIEvent_GetDuration (pTempEvent));
+ pMusicalScoreFrame->SetCurChannel (MIDIEvent_GetChannel (pTempEvent));
+ m_lTempTrackIndex = pMusicalScoreFrame->GetCurTrackIndex ();
+ m_pTempTrack = pTempTrack;//pSekaijuDoc->GetTrack (i);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (pTempTrack);
+ m_lTempVelocity = pMusicalScoreFrame->GetCurVelocity ();
+ m_lTempDuration = pMusicalScoreFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (pTempTrack);
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) {
+ m_lTempChannel = pMusicalScoreFrame->GetCurChannel ();
+ }
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (pTempEvent);
+ m_lTempMode = 0x0103;
+ m_lTempKey = MIDIEvent_GetKey (pTempEvent);
+ m_lMouseDownKey = m_lTempKey;
+ m_lMouseMoveKey = m_lTempKey;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ m_pTempEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent));
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, m_lTempKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ pMusicalScoreFrame->UpdateNoteInfoArray (m_lTempTrackIndex, m_pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (m_lTempTrackIndex, m_pTempTrack);
+ Invalidate ();
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ pMusicalScoreFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ }
+ }
+ if (m_pTempEvent) {
+ break;
+ }
+ }
+ i--;
+ }
+ // 何もないところにマウスが置かれた場合
+ if (m_pTempEvent == NULL) {
+ m_lTempTime = (m_lTempTime / m_lTempSnap) * m_lTempSnap;
+ m_lTempTimeNoteOn = m_lTempTime;
+ m_lTempTrackIndex = pMusicalScoreFrame->YtoTrackIndex (point.y);
+ if (m_lTempTrackIndex < 0 || m_lTempTrackIndex >= MIDIData_CountTrack (pMIDIData)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempKey = pMusicalScoreFrame->TrackIndexYtoKey (m_lTempTrackIndex, point.y, lKeySignature);
+ m_lMouseDownKey = m_lTempKey;
+ m_lMouseMoveKey = m_lTempKey;
+ if (lFormat == 1 && m_lTempTrackIndex == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ pMusicalScoreFrame->SetCurTrackIndex (m_lTempTrackIndex);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ pMusicalScoreFrame->SetCurChannel (m_lTempChannel);
+ m_pTempEvent = MIDIEvent_CreateNote
+ (m_lTempTime, m_lTempChannel, m_lTempKey, m_lTempVelocity, m_lTempDuration);
+ if (m_pTempEvent == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_ANY_MORE_BEACUSE_OF_INSUFFICIENT_MEMORY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ MIDITrack_InsertEvent (m_pTempTrack, m_pTempEvent);
+ m_lTempMode = 0x0101;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, m_lTempKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ pMusicalScoreFrame->UpdateNoteInfoArray (m_lTempTrackIndex, m_pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (m_lTempTrackIndex, m_pTempTrack);
+ Invalidate ();
+ pMusicalScoreFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ }
+ break;
+ // 線
+ case ID_MUSICALSCORE_LINE:
+ break;
+
+ // 消しゴム
+ case ID_MUSICALSCORE_ERASER:
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ m_pTempEvent = NULL;
+ m_lTempMode = 0x0301;
+ // 既存のノートの上にマウスが置かれた場合
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ CRect rcNote = GetNoteRect (pNoteInfo);
+ // 既存の音符上をクリックした場合
+ if (rcNote.top <= point.y && point.y < rcNote.bottom) {
+ if (rcNote.left <= point. x && point.x < rcNote.right) {
+ // フォーマット1のMIDIデータで最初のトラックにノートを消すのを禁止
+ if (lFormat == 1 && i == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_DELETE_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ VERIFY (pTempEvent = pNoteInfo->m_pNoteOnEvent);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pMusicalScoreFrame->UpdateNoteInfoArray (i, pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (i, pTempTrack);
+ Invalidate ();
+ bPtInNote = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (bPtInNote) {
+ break;
+ }
+ i--;
+ }
+ pMusicalScoreFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+
+ // 選択
+ case ID_MUSICALSCORE_SELECT:
+ bPtInNote = FALSE;
+ // 既存の選択されているノートの上にマウスが置かれたか調べる
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ long lPort = MIDITrack_GetOutputPort (pTempTrack);
+ if (0 <= lPort && lPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[lPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[lPort];
+ }
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ CRect rcNote = GetNoteRect (pNoteInfo);
+ // 既存の音符上をクリックした場合
+ if (rcNote.top <= point.y && point.y < rcNote.bottom) {
+ if (rcNote.left <= point. x && point.x < rcNote.right) {
+ VERIFY (pTempEvent = pNoteInfo->m_pNoteOnEvent);
+ if (pSekaijuDoc->IsEventSelected (pTempEvent)) {
+ ASSERT (MIDIEvent_IsNoteOn (pTempEvent));
+ ASSERT (MIDIEvent_IsNote (pTempEvent));
+ if (pTempEvent->m_pNextCombinedEvent) {
+ m_pTempEvent = pTempEvent;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (m_pTempEvent) {
+ break;
+ }
+ }
+ i--;
+ }
+ // 既存の選択されているノートの上にマウスが置かれた場合(複写又は移動モード)
+ if (m_pTempEvent) {
+ pMusicalScoreFrame->SetCurTrackIndex (i);
+ pMusicalScoreFrame->SetCurVelocity (MIDIEvent_GetVelocity (m_pTempEvent));
+ pMusicalScoreFrame->SetCurDuration (MIDIEvent_GetDuration (m_pTempEvent));
+ pMusicalScoreFrame->SetCurChannel (MIDIEvent_GetChannel (m_pTempEvent));
+ m_lTempTrackIndex = pMusicalScoreFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempVelocity = pMusicalScoreFrame->GetCurVelocity ();
+ m_lTempDuration = pMusicalScoreFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (m_pTempTrack);
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) {
+ m_lTempChannel = pMusicalScoreFrame->GetCurChannel ();
+ }
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (m_pTempEvent);
+ m_lTempKey = MIDIEvent_GetKey (m_pTempEvent);
+ m_lMouseDownKey = m_lTempKey;
+ m_lMouseMoveKey = m_lTempKey;
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, m_lTempKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ m_theTempSelectedEventArray.RemoveAll ();
+ // 複写の場合(CONTROLが押されている)
+ if (nFlags & MK_CONTROL) {
+ VERIFY (strHistoryName.LoadString (IDS_DUPLICATE_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ i = 0; //20080902追加
+ forEachTrack (pMIDIData, pTempTrack) { //20080902修正
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ // このトラックのEndofTrackイベントを履歴記録
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ // 選択ノートイベントの複写
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ pSekaijuDoc->IsEventSelected (pTempEvent) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ // 選択されたノートオンを非選択状態にする。
+ MIDIEvent* pCloneEvent = NULL;
+ pCloneEvent = pSekaijuDoc->SelectEvent (pTempEvent, 0, pCurHistoryUnit);
+ if (pCloneEvent == NULL) {
+ continue;
+ }
+ // ノートオンを複写し、複写した方を選択状態にする。
+ pCloneEvent = pSekaijuDoc->DuplicateMIDIEvent (pCloneEvent);
+ if (pCloneEvent) {
+ // 対応するノートオフイベントのm_lUser1にマウスが押されたときのキーを、
+ // 対応するノートオフイベントのm_lUser2ニマウスが押されたときのタイムを保持。
+ ASSERT (MIDIEvent_IsNote (pCloneEvent));
+ ASSERT (pCloneEvent->m_pNextCombinedEvent);
+ pCloneEvent->m_pNextCombinedEvent->m_lUser1 = MIDIEvent_GetKey (pCloneEvent);
+ pCloneEvent->m_pNextCombinedEvent->m_lUser2 = MIDIEvent_GetTime (pCloneEvent);
+ pSekaijuDoc->SetEventSelected (pCloneEvent, 1);
+ m_theTempSelectedEventArray.Add (pCloneEvent);
+ if (pTempEvent == m_pTempEvent) {
+ m_pTempEvent = pCloneEvent;
+ }
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ i++;
+ }
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAllCopy);
+ m_lTempMode = 0x0403;
+ }
+ // 移動の場合(CONTROLが押されていない)
+ else {
+ VERIFY (strHistoryName.LoadString (IDS_MOVE_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ i = 0; //20080902追加
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ pSekaijuDoc->IsEventSelected (pTempEvent) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDIEvent* pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ if (pCloneEvent) {
+ // 対応するノートオフイベントのm_lUser1にマウスが押されたときのキーを保持。
+ // 対応するノートオフイベントのm_lUser2ニマウスが押されたときのタイムを保持。
+ ASSERT (MIDIEvent_IsNote (pCloneEvent));
+ ASSERT (pCloneEvent->m_pNextCombinedEvent);
+ pCloneEvent->m_pNextCombinedEvent->m_lUser1 = MIDIEvent_GetKey (pCloneEvent);
+ pCloneEvent->m_pNextCombinedEvent->m_lUser2 = MIDIEvent_GetTime (pCloneEvent);
+ m_theTempSelectedEventArray.Add (pCloneEvent);
+ if (pTempEvent == m_pTempEvent) {
+ m_pTempEvent = pCloneEvent;
+ }
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ i++;
+ }
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ m_lTempMode = 0x0402;
+ }
+ ASSERT (m_pTempEvent);
+ ASSERT (m_pTempTrack);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ // 選択されているイベントがあるトラックだけ再描画
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ pMusicalScoreFrame->UpdateNoteInfoArray (i, pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (i, pTempTrack);
+ }
+ i++;
+ }
+ Invalidate ();
+ pMusicalScoreFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+
+ }
+ // 何もないところにマウスが置かれた場合(選択範囲モード)
+ else {
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+ m_lTempMode = 0x0401;
+ dc.SetROP2 (R2_NOT);
+ dc.SetPixel (point, RGB (0, 0, 0));
+ dc.SetROP2 (R2_COPYPEN);
+ ::SetCursor (pSekaijuApp->m_hCursorSelect);
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ pMusicalScoreFrame->UpdateNoteInfoArray (i, pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (i, pTempTrack);
+ }
+ i++;
+ }
+ Invalidate ();
+ pMusicalScoreFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ }
+ break;
+
+ // スクラブ
+ case ID_MUSICALSCORE_SPEAKER:
+ if (pSekaijuApp->m_bPlaying) {
+ pMusicalScoreFrame->SendMessage (WM_COMMAND, (WPARAM)ID_CONTROL_PLAY, (LPARAM)0);
+ }
+ if (pSekaijuApp->m_theMusicalScoreOption.m_bSpeakerModeVisibleTrack) {
+ long i = 0;
+ long lTempOutputOn[MAXMIDITRACKNUM];
+ forEachTrack (pMIDIData, pTempTrack) {
+ lTempOutputOn[i] = MIDITrack_GetOutputOn (pTempTrack);
+ MIDITrack_SetOutputOn (pTempTrack, pMusicalScoreFrame->IsTrackVisible (i));
+ i++;
+ }
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ MIDITrack_SetOutputOn (pTempTrack, lTempOutputOn[i]);
+ i++;
+ }
+ }
+ else {
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ }
+ m_lTempMode = 0x0501;
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ pMusicalScoreFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CMusicalScoreTrackTimeView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ point += sizWndOrg;
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+
+ BYTE byMIDIMessage[4];
+ memset (byMIDIMessage, 0, sizeof (byMIDIMessage));
+ // マウスキャプター中は臨時記号(半音上げ下げ)を仮付けする。
+ if (GetCapture () == this) {
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ // ツール別の操作
+ switch (m_lTempTool) {
+ // ペン
+ case ID_MUSICALSCORE_PEN:
+ // 音符移動中
+ if (m_lTempMode == 0x0101 || m_lTempMode == 0x0103) {
+ ASSERT (m_pTempEvent != NULL);
+ ASSERT (m_pTempTrack != NULL);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ ASSERT (0 <= m_lTempTrackIndex && m_lTempTrackIndex < MAXMIDITRACKNUM);
+ ASSERT (lFormat != 0 && m_lTempTrackIndex != 0);
+ long lOldTime = m_lMouseMoveTime;
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lOldTime, &lsf, &lmi);
+ long lKeySignature = lsf | (lmi << 8);
+ long lOldKey = m_lMouseMoveKey;
+ long lOldLineNo = pMusicalScoreFrame->KeytoLineNo (lOldKey, lKeySignature);
+ // 半音あげた場合
+ long lNewKeyUp = CLIP (0, lOldKey + 1, 127);
+ long lNewLineNoUp = pMusicalScoreFrame->KeytoLineNo (lNewKeyUp, lKeySignature);
+ // 半音下げた場合
+ long lNewKeyDown = CLIP (0, lOldKey - 1, 127);
+ long lNewLineNoDown = pMusicalScoreFrame->KeytoLineNo (lNewKeyDown, lKeySignature);
+ // 五線譜上の位置が変わらないほうを採用
+ long lNewKey = lOldKey;
+ if (lNewLineNoUp == lOldLineNo) {
+ lNewKey = lNewKeyUp;
+ }
+ else if (lNewLineNoDown == lOldLineNo) {
+ lNewKey = lNewKeyDown;
+ }
+ // キーが変わった場合のみ
+ if (lOldKey != lNewKey) {
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // 新しいキー設定
+ MIDIEvent_SetKey (m_pTempEvent, CLIP (0, lNewKey, 127));
+ // 新しいキー発音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lNewKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ m_lMouseMoveKey = lNewKey;
+ }
+ }
+ break;
+ // 選択
+ case ID_MUSICALSCORE_SELECT:
+ // 移動又は複写中
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ ASSERT (m_pTempEvent != NULL);
+ ASSERT (m_pTempTrack != NULL);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ ASSERT (0 <= m_lTempTrackIndex && m_lTempTrackIndex < MAXMIDITRACKNUM);
+ ASSERT (lFormat != 0 && m_lTempTrackIndex != 0);
+ long lOldTime = m_lMouseMoveTime;
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lOldTime, &lsf, &lmi);
+ long lKeySignature = lsf | (lmi << 8);
+ long lDownKey = m_lMouseDownKey;
+ long lOldKey = m_lMouseMoveKey;
+ long lOldLineNo = pMusicalScoreFrame->KeytoLineNo (lOldKey, lKeySignature);
+ // 半音あげた場合
+ long lNewKeyUp = CLIP (0, lOldKey + 1, 127);
+ long lNewLineNoUp = pMusicalScoreFrame->KeytoLineNo (lNewKeyUp, lKeySignature);
+ // 半音下げた場合
+ long lNewKeyDown = CLIP (0, lOldKey - 1, 127);
+ long lNewLineNoDown = pMusicalScoreFrame->KeytoLineNo (lNewKeyDown, lKeySignature);
+ // 五線譜上の位置が変わらないほうを採用
+ long lNewKey = lOldKey;
+ if (lNewLineNoUp == lOldLineNo) {
+ lNewKey = lNewKeyUp;
+ }
+ else if (lNewLineNoDown == lOldLineNo) {
+ lNewKey = lNewKeyDown;
+ }
+ // キーが変わった場合のみ
+ if (lOldKey != lNewKey) {
+ long lDeltaKey = lNewKey - lDownKey;
+ long lTempSelectedEventArrayCount = m_theTempSelectedEventArray.GetSize ();
+ long j;
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // 新しいキー設定
+ for (j = 0; j < lTempSelectedEventArrayCount; j++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)m_theTempSelectedEventArray.GetAt (j);
+ long lTempKey = pTempEvent->m_pNextCombinedEvent->m_lUser1;
+ long lTargetKey = lTempKey + lDeltaKey;
+ lTargetKey = CLIP (0, lTargetKey, 127);
+ MIDIEvent_SetKey (pTempEvent, lTargetKey);
+ }
+ // 新しいキー発音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lNewKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ m_lMouseMoveKey = lNewKey;
+ }
+ }
+ break;
+ }
+ }
+
+ // マウスキャプター中でない場合
+ else {
+
+ ASSERT (m_pTempEvent == NULL);
+ ASSERT (m_lTempMode == 0);
+
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lsf, lmi;
+ m_lTempTime = pMusicalScoreFrame->XtoTime (point.x);
+ m_lMouseDownTime = m_lTempTime;
+ m_lMouseMoveTime = m_lTempTime;
+ MIDIData_FindKeySignature (pMIDIData, m_lTempTime, &lsf, &lmi);
+ long lKeySignature = lsf | (lmi << 8);
+ m_lTempTool = pMusicalScoreFrame->m_lCurTool;
+ m_lTempChannel = pMusicalScoreFrame->GetCurChannel ();
+ m_lTempChannel = CLIP (0, m_lTempChannel, 15);
+ m_lTempVelocity = pMusicalScoreFrame->GetCurVelocity ();
+ m_lTempVelocity = CLIP (1, m_lTempVelocity, 127);
+ m_lTempDuration = pMusicalScoreFrame->GetCurDuration ();
+ m_lTempDuration = CLIP (1, m_lTempDuration, 65535);
+ m_lTempSnap = pMusicalScoreFrame->GetCurSnap ();
+ m_lTempSnap = CLIP (1, m_lTempSnap, MIDIData_GetTimeResolution (pMIDIData));
+ m_pTempEvent = NULL;
+ m_pTempTrack = NULL;
+ // 既存のノートの上にマウスが置かれた場合
+ MIDITrack* pTempTrack = NULL;
+ long i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j = 0;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt(j));
+ CRect rcNote = GetNoteRect (pNoteInfo);
+ // 既存の音符の上にマウスが置かれた場合
+ if (rcNote.left<= point.x && point.x < rcNote.right) {
+ if (rcNote.top <= point.y && point.y < rcNote.bottom) {
+ m_lTempOutputPort = MIDITrack_GetOutputPort (pTempTrack);
+ m_lTempVelocity = pMusicalScoreFrame->GetCurVelocity ();
+ m_lTempDuration = pMusicalScoreFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (pTempTrack);
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) {
+ m_lTempChannel = pMusicalScoreFrame->GetCurChannel ();
+ }
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (pNoteInfo->m_pNoteOnEvent);
+ m_pTempEvent = pNoteInfo->m_pNoteOnEvent;
+ m_pTempTrack = pTempTrack;
+ ASSERT (m_pTempEvent);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ break;
+ }
+ }
+ }
+ }
+ i++;
+ }
+ // どの音符上にも命中していない場合(20110207追加)
+ if (m_pTempTrack == NULL && m_pTempEvent == NULL) {
+ i = pMusicalScoreFrame->YtoTrackIndex (point.y);
+ if (0 <= i && i < pMusicalScoreFrame->GetTrackInfoCount ()) {
+ m_pTempTrack = pSekaijuDoc->GetTrack (i);
+ }
+ }
+
+ m_lTempMode = 0x1001;
+
+ ShowPopupMenu (ptMenu);
+
+ m_pTempEvent = NULL;
+ m_lTempMode = 0x0000;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ Invalidate ();
+
+
+}
+
+// マウス左ボタン離されたとき
+void CMusicalScoreTrackTimeView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ point += sizWndOrg;
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lDownTime = m_lMouseDownTime;
+ long lOldTime = m_lMouseMoveTime;
+ long lNewTime = lOldTime;
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lNewTime, &lsf, &lmi);
+ long lKeySignature = lsf | (lmi << 8);
+ long lDownKey = m_lMouseDownKey;
+ long lOldKey = m_lMouseMoveKey;
+ long lNewKey = lOldKey;
+ long i = 0;
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ BYTE byMIDIMessage[3];
+ switch (m_lTempTool) {
+ // ペン
+ case ID_MUSICALSCORE_PEN:
+ ASSERT (m_pTempTrack);
+ ASSERT (m_pTempEvent);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ ASSERT (0 <= m_lTempTrackIndex && m_lTempTrackIndex < MAXMIDITRACKNUM);
+ ASSERT (lFormat != 0 && m_lTempTrackIndex != 0);
+ ASSERT (m_lTempMode);
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 音符挿入中又は音符移動中の場合に限り
+ if (m_lTempMode == 0x0101 || m_lTempMode == 0x0103) {
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ // 履歴記録
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pTempEvent);
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ break;
+ // 線
+ case ID_MUSICALSCORE_LINE:
+ break;
+ // 消しゴム
+ case ID_MUSICALSCORE_ERASER:
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ break;
+ // 選択
+ case ID_MUSICALSCORE_SELECT:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 音符移動中又は音符複写中の場合
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ ASSERT (m_pTempTrack);
+ ASSERT (m_pTempEvent);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ ASSERT (0 <= m_lTempTrackIndex && m_lTempTrackIndex < MAXMIDITRACKNUM);
+ ASSERT (lFormat != 0 && m_lTempTrackIndex != 0);
+ // 各選択イベントのマウスダウン時のキー情報とタイム情報を削除
+ long j;
+ long lTempSelectedEventCount = m_theTempSelectedEventArray.GetSize ();
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pTempEvent->m_pNextCombinedEvent->m_lUser1 = 0;
+ pTempEvent->m_pNextCombinedEvent->m_lUser2 = 0;
+ }
+ // 複写の場合
+ if (m_lTempMode == 0x0403) {
+ // 元の位置と同じ場合は複写しない。
+ if ((lDownKey == lNewKey) &&
+ (lDownTime / m_lTempSnap) * m_lTempSnap ==
+ (lNewTime / m_lTempSnap) * m_lTempSnap) {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ MIDIEvent_Delete (pCloneEvent);
+ }
+ }
+ // 元の位置と異なる場所に複写された場合、複写確定、履歴記録。
+ else {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ }
+ }
+ // 移動の場合
+ else if (m_lTempMode == 0x0402) {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ }
+ // EOTの履歴記録
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent);
+ }
+ }
+ }
+ i++;
+ }
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+
+ }
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ }
+ // 選択範囲変更中の場合
+ else if (m_lTempMode == 0x0401) {
+ // 新規選択
+ long lStartTime = __min (lDownTime, lNewTime);
+ long lEndTime = __max (lDownTime, lNewTime);
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long lDownKey = pMusicalScoreFrame->TrackIndexYtoKey (i, m_ptMouseDown.y, lKeySignature);
+ long lNewKey = pMusicalScoreFrame->TrackIndexYtoKey (i, point.y, lKeySignature);
+ long lStartKey = __min (lDownKey, lNewKey);
+ long lEndKey = __max (lDownKey, lNewKey);
+ long j = 0;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt(j));
+ VERIFY (pTempEvent = pNoteInfo->m_pNoteOnEvent);
+ // この音符に対応するノートオンイベントがまだ選択されていない場合のみ
+ if (MIDIEvent_GetParent (pTempEvent) == pTempTrack) {
+ // 時刻が選択範囲内にある場合
+ long lTime = pNoteInfo->m_lNoteOnTime;
+ if (lStartTime <= lTime && lTime <= lEndTime) {
+ // キーが選択範囲内にある場合
+ long lKey = MIDIEvent_GetKey (pTempEvent);
+ if (lStartKey <= lKey && lKey <= lEndKey) {
+ // イベントを履歴置き場に移し、新しいイベントを選択する。
+ MIDIEvent* pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ }
+ }
+ }
+ }
+ }
+ i--;
+ }
+ }
+ break;
+ // スクラブ
+ case ID_MUSICALSCORE_SPEAKER:
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllSoundOff ();
+ break;
+ }
+ m_theTempSelectedEventArray.RemoveAll ();
+ m_pTempEvent = NULL;
+ m_lTempMode = 0;
+ KillTimer (0x21);
+ ReleaseCapture ();
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// マウス右ボタン離されたとき
+void CMusicalScoreTrackTimeView::OnRButtonUp (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+}
+
+// マウスが動かされたとき
+void CMusicalScoreTrackTimeView::OnMouseMove (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pMusicalScoreFrame->GetTimeScrollPos (), pMusicalScoreFrame->GetTrackScrollPos ());
+ point += sizWndOrg;
+ CRect rcClient;
+ GetClientRect (&rcClient);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lDownTime = m_lMouseDownTime;
+ long lOldTime = m_lMouseMoveTime;
+ long lNewTime = pMusicalScoreFrame->XtoTime (point.x);
+ long lsf, lmi;
+ MIDIData_FindKeySignature (pMIDIData, lNewTime, &lsf, &lmi);
+ long lKeySignature = lsf | (lmi << 8);
+ long lDownKey = m_lMouseDownKey;
+ long lOldKey = m_lMouseMoveKey;
+ long lNewKey = pMusicalScoreFrame->TrackIndexYtoKey (m_lTempTrackIndex, point.y, lKeySignature);
+
+ BYTE byMIDIMessage[3];
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ long i = 0;
+ // ツール別の操作
+ switch (m_lTempTool) {
+ case ID_MUSICALSCORE_PEN:
+ ASSERT (m_pTempTrack);
+ ASSERT (m_pTempEvent);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ ASSERT (0 <= m_lTempTrackIndex && m_lTempTrackIndex < MAXMIDITRACKNUM);
+ ASSERT (lFormat != 0 && m_lTempTrackIndex != 0);
+ ASSERT (m_lTempMode);
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 音符移動中
+ if (m_lTempMode == 0x0101 || m_lTempMode == 0x0103) {
+ // キーが変わった場合又は時刻が変わった場合
+ if (lOldKey != lNewKey ||
+ (lOldTime / m_lTempSnap) * m_lTempSnap !=
+ (lNewTime / m_lTempSnap) * m_lTempSnap) {
+ // キーが変わった場合のみ
+ if (lOldKey != lNewKey) {
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // 新しいキー設定
+ MIDIEvent_SetKey (m_pTempEvent, CLIP (0, lNewKey, 127));
+ // 新しいキー発音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lNewKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ // 時刻が変わった場合のみ
+ if ((lOldTime / m_lTempSnap) * m_lTempSnap !=
+ (lNewTime / m_lTempSnap) * m_lTempSnap) {
+ // 新しい時刻設定
+ long lDeltaTime =
+ (lNewTime / m_lTempSnap) * m_lTempSnap -
+ (lOldTime / m_lTempSnap) * m_lTempSnap;
+ long lCurTime = MIDIEvent_GetTime (m_pTempEvent);
+ long lTempTime = CLIP (0, lCurTime + lDeltaTime, 0x7FFF0000);
+ MIDIEvent_SetTime (m_pTempEvent, lTempTime);
+ }
+ pMusicalScoreFrame->UpdateNoteInfoArray (m_lTempTrackIndex, m_pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (m_lTempTrackIndex, m_pTempTrack);
+ Invalidate ();
+ }
+ }
+ break;
+ // 線
+ case ID_MUSICALSCORE_LINE:
+ break;
+ // 消しゴム
+ case ID_MUSICALSCORE_ERASER:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 既存のノートの上にマウスが置かれた場合 */
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ CRect rcNote = GetNoteRect (pNoteInfo);
+ // 既存の音符上をクリックした場合
+ if (rcNote.top <= point.y && point.y < rcNote.bottom) {
+ if (rcNote.left <= point. x && point.x < rcNote.right) {
+ VERIFY (pTempEvent = pNoteInfo->m_pNoteOnEvent);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pMusicalScoreFrame->UpdateNoteInfoArray (i, pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (i, pTempTrack);
+ Invalidate ();
+ break;
+ }
+ }
+ }
+ }
+ i--;
+ }
+ break;
+ // 選択
+ case ID_MUSICALSCORE_SELECT:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 移動又は複写中
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ ASSERT (m_pTempTrack);
+ ASSERT (m_pTempEvent);
+ ASSERT (MIDIEvent_GetParent (m_pTempEvent) == m_pTempTrack);
+ ASSERT (0 <= m_lTempTrackIndex && m_lTempTrackIndex < MAXMIDITRACKNUM);
+ ASSERT (lFormat != 0 && m_lTempTrackIndex != 0);
+ long lTempSelectedEventArrayCount = m_theTempSelectedEventArray.GetSize ();
+ long j;
+ // キーが変わった場合又は時刻が変わった場合
+ if (lOldKey != lNewKey ||
+ (lOldTime / m_lTempSnap) * m_lTempSnap !=
+ (lNewTime / m_lTempSnap) * m_lTempSnap) {
+ // キーが変わった場合
+ if (lOldKey != lNewKey) {
+ long lDeltaKey = lNewKey - lDownKey;
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // 新しいキーを設定
+ for (j = 0; j < lTempSelectedEventArrayCount; j++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)m_theTempSelectedEventArray.GetAt (j);
+ long lTempKey = pTempEvent->m_pNextCombinedEvent->m_lUser1;
+ long lTargetKey = lTempKey + lDeltaKey;
+ lTargetKey = CLIP (0, lTargetKey, 127);
+ MIDIEvent_SetKey (pTempEvent, lTargetKey);
+ }
+ // 新しいキー発音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lNewKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ // 時刻が変わった場合
+ if ((lOldTime / m_lTempSnap) * m_lTempSnap !=
+ (lNewTime / m_lTempSnap) * m_lTempSnap) {
+ long lDeltaTime =
+ (lNewTime / m_lTempSnap) * m_lTempSnap -
+ (lDownTime / m_lTempSnap) * m_lTempSnap;
+ for (j = 0; j < lTempSelectedEventArrayCount; j++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)m_theTempSelectedEventArray.GetAt (j);
+ long lTempTime = pTempEvent->m_pNextCombinedEvent->m_lUser2;
+ long lTargetTime = lTempTime + lDeltaTime;
+ lTargetTime = CLIP (0, lTargetTime, 0x7FFFFFFF);
+ MIDIEvent_SetTime (pTempEvent, lTargetTime);
+ }
+ }
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i)) {
+ pMusicalScoreFrame->UpdateNoteInfoArray (i, pTempTrack);
+ pMusicalScoreFrame->UpdateNoteGroupInfoArray (i, pTempTrack);
+ }
+ i++;
+ }
+ Invalidate ();
+ }
+ }
+ // 選択範囲移動中
+ else if (m_lTempMode = 0x0401) {
+ // 案B(選択矩形はちらつくが内部はちらつかない)
+ CRect rcRegion;
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseMove.x, m_ptMouseDown.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseMove.y, m_ptMouseMove.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseDown.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseMove.x, m_ptMouseDown.y, m_ptMouseMove.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, point.x, m_ptMouseDown.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, point.y, point.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseDown.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (point.x, m_ptMouseDown.y, point.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+ break;
+
+ // スクラブ
+ case ID_MUSICALSCORE_SPEAKER:
+ m_lTempTime = pMusicalScoreFrame->XtoTime (point.x);
+ if (pSekaijuApp->m_theMusicalScoreOption.m_bSpeakerModeVisibleTrack) {
+ long i = 0;
+ long lTempOutputOn[MAXMIDITRACKNUM];
+ forEachTrack (pMIDIData, pTempTrack) {
+ lTempOutputOn[i] = MIDITrack_GetOutputOn (pTempTrack);
+ MIDITrack_SetOutputOn (pTempTrack, pMusicalScoreFrame->IsTrackVisible (i));
+ i++;
+ }
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ MIDITrack_SetOutputOn (pTempTrack, lTempOutputOn[i]);
+ i++;
+ }
+ }
+ else {
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ }
+ break;
+ }
+ }
+ // 非キャプター中(カーソルの種類だけ変更)
+ else {
+ long i = 0;
+ BOOL bChanged = FALSE;
+ MIDITrack* pMIDITrack;
+ switch (pMusicalScoreFrame->m_lCurTool) {
+ // 描画
+ case ID_MUSICALSCORE_PEN:
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ CRect rcNote = GetNoteRect (pNoteInfo);
+ // 既存の音符上を通過した場合
+ if (rcNote.top <= point.y && point.y < rcNote.bottom) {
+ if (rcNote.left <= point. x && point.x < rcNote.right) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ bChanged = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ i--;
+ }
+ if (bChanged == FALSE) {
+ ::SetCursor (pSekaijuApp->m_hCursorDraw);
+ }
+ break;
+ // 線
+ case ID_MUSICALSCORE_LINE:
+ break;
+ // 消しゴム
+ case ID_MUSICALSCORE_ERASER:
+ ::SetCursor (pSekaijuApp->m_hCursorEraser);
+ break;
+ // 選択
+ case ID_MUSICALSCORE_SELECT:
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pMIDITrack) {
+ if (pMusicalScoreFrame->IsTrackVisible (i) && !(lFormat == 0 && i == 0)) {
+ MusicalScoreTrackInfo* pTrackInfo = pMusicalScoreFrame->GetTrackInfo (i);
+ long lNumNoteInfo = pTrackInfo->m_theNoteInfoArray.GetSize ();
+ long j;
+ for (j = 0; j < lNumNoteInfo; j++) {
+ MusicalScoreNoteInfo* pNoteInfo = (MusicalScoreNoteInfo*)(pTrackInfo->m_theNoteInfoArray.GetAt (j));
+ CRect rcNote = GetNoteRect (pNoteInfo);
+ // 既存の音符上を通過した場合
+ if (rcNote.top <= point.y && point.y < rcNote.bottom) {
+ if (rcNote.left <= point. x && point.x < rcNote.right) {
+ VERIFY (pTempEvent = pNoteInfo->m_pNoteOnEvent);
+ if (pSekaijuDoc->IsEventSelected (pTempEvent)) {
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAllCopy);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ bChanged = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ i--;
+ }
+ if (!bChanged) {
+ ::SetCursor (pSekaijuApp->m_hCursorSelect);
+ }
+ break;
+ // スピーカー
+ case ID_MUSICALSCORE_SPEAKER:
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ break;
+ // 不明
+ default:
+ //::SetCursor (pSekaijuApp->m_hCursorArrow);
+ break;
+ }
+ }
+ m_lMouseMoveKey = lNewKey;
+ m_lMouseMoveTime = lNewTime;
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウスホイールが回された時
+void CMusicalScoreTrackTimeView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CMusicalScoreFrame* pMusicalScoreFrame = (CMusicalScoreFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pMusicalScoreFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lTrackScrollPos = pMusicalScoreFrame->GetTrackScrollPos ();
+ long ry = 4;
+ lTrackScrollPos -= ry * 2 * lDelta / WHEELDELTA;
+ pMusicalScoreFrame->SetTrackScrollPos (lTrackScrollPos);
+ }
+}
+
+
diff --git a/src/MusicalScoreTrackTimeView.h b/src/MusicalScoreTrackTimeView.h
new file mode 100644
index 0000000..5bad30f
--- /dev/null
+++ b/src/MusicalScoreTrackTimeView.h
@@ -0,0 +1,137 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 譜面トラックタイムビュークラス
+// (C)2002-2011 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MUSICALSCORETRACKTIMEVIEW_H_
+#define _MUSICALSCORETRACKTIMEVIEW_H_
+
+class CMusicalScoreTrackTimeView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CMusicalScoreTrackTimeView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ long m_lCurTime; // 現在の描画タイム[tick]又は[サブフレーム]
+ long m_lOldTime; // 前回の描画タイム[tick]又は[サブフレーム]
+ long m_lOldX; // 前回の縦線x座標[pixel]
+ long m_lOldY1; // 前回の縦線y上座標[pixel]
+ long m_lOldY2; // 前回の縦線y下座標[pixel]
+ BOOL m_bOldDraw; // 前回縦線を描画したか?
+ long m_lMouseDownTime; // マウスが押されたときの指すタイム[tick]又は[サブフレーム]
+ long m_lMouseMoveTime; // マウスが動かされたときの前回の指すタイム[tick]又は[サブフレーム]
+ long m_lMouseDownKey; // マウスが押されたときの指す音階(0〜127)
+ long m_lMouseMoveKey; // マウスが動かされたときの前回の指す音階(0〜127)
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lTempTool; // 一時的なツール(0〜)
+ long m_lTempTrackIndex; // 一時的なトラック番号(0〜65535)
+ long m_lTempSnap; // 一時的なスナップタイム[tick]
+ long m_lTempVelocity; // 一時的なベロシティ(0〜127)
+ long m_lTempDuration; // 一時的な音長さ(0〜)[tick]
+ long m_lTempOutputPort; // 一時的な出力ポート(0〜15)
+ long m_lTempChannel; // 一時的なチャンネル(0〜15)
+ long m_lTempKey; // 一時的な音階(0〜127)
+ long m_lTempTime; // 一時的なタイム(0〜)[tick]
+ long m_lTempTimeNoteOn; // 一時的なノートオンタイム(0〜)[tick]
+ MIDITrack* m_pTempTrack; // 一時的なトラックへのポインタ
+ MIDIEvent* m_pTempEvent; // 一時的なイベントへのポインタ
+ MIDIEvent* m_pLastEvent; // 一時的な最後のイベントへのポインタ
+ long m_lTempMode; // 一時的なモード
+ CPtrArray m_theTempSelectedEventArray; // 一時的な選択されているイベントの配列
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMusicalScoreTrackTimeView (); // コンストラクタ
+ virtual ~CMusicalScoreTrackTimeView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+protected:
+ virtual CRect GetNoteRect (MIDIEvent* pNoteOnEvent);
+ virtual CRect GetNoteRect (MusicalScoreNoteInfo* pNoteInfo);
+ virtual void EraseOldLine (CDC* pDC);
+ virtual void DrawCurLine (CDC* pDC);
+ virtual BOOL ShowPopupMenu (CPoint ptMenu);
+ virtual void DrawTadpole
+ (CDC* pDC, long x, long y, long rx, long ry, long lFlags);
+ virtual void DrawHorzAuxiliaryLine
+ (CDC* pDC, long x, long y, long r, long lFlags);
+ void DrawDot
+ (CDC* pDC, long x, long y, long rx, long ry, long lFlags);
+ void DrawTieHalf
+ (CDC* pDC, long x1, long x2, long y, long rx, long ry, long lFlags);
+ void DrawPole
+ (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawSingleFlag
+ (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawChainedFlag
+ (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawTripletSign
+ (CDC* pDC, long x1, long x2, long y1, long y2, long rx, long ry, long lFlags);
+ void DrawNote
+ (CDC* pDC, long lTrackIndex, MusicalScoreNoteInfo* pNoteInfo, long lFlags);
+ void DrawGClef
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawFClef
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawFlat
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawNatural
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawSharp
+ (CDC* pDC, long x, long y, long rx, long ry);
+ void DrawTimeAndKeySignature
+ (CDC* pDC, long lTrackIndex, long lTime);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif
+
diff --git a/src/OptionSheet.cpp b/src/OptionSheet.cpp
new file mode 100644
index 0000000..68e78d3
--- /dev/null
+++ b/src/OptionSheet.cpp
@@ -0,0 +1,99 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// オプションプロパティシートクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "GeneralOptionPage.h"
+#include "TrackListOption1Page.h"
+#include "TrackListOption2Page.h"
+#include "PianoRollOptionPage.h"
+#include "EventListOptionPage.h"
+#include "OptionSheet.h"
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+COptionSheet::COptionSheet (CWnd* pParentWnd) :
+CPropertySheet (IDS_OPTIONS, pParentWnd) {
+ AddPage (&m_theGeneralOptionPage);
+ AddPage (&m_theColorOptionPage);
+ AddPage (&m_theTrackListOption1Page);
+ AddPage (&m_theTrackListOption2Page);
+ AddPage (&m_thePianoRollOptionPage);
+ AddPage (&m_theEventListOptionPage);
+ AddPage (&m_theMusicalScoreOptionPage);
+}
+
+// デストラクタ
+COptionSheet::~COptionSheet () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 初期化時
+BOOL COptionSheet::OnInitDialog() {
+ BOOL bResult = CPropertySheet::OnInitDialog();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ SetActivePage (pSekaijuApp->m_theCurrentPage.m_lOption);
+ return bResult;
+}
+
+// コマンド時
+BOOL COptionSheet::OnCommand (WPARAM wParam, LPARAM lParam) {
+ // 『OK』又は『キャンセル』ボタンが押された
+ if (LOWORD (wParam) == IDOK || LOWORD (wParam) == IDCANCEL) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ pSekaijuApp->m_theCurrentPage.m_lOption = GetActiveIndex ();
+ }
+ return CPropertySheet::OnCommand(wParam, lParam);
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (COptionSheet, CPropertySheet)
+ ON_BN_CLICKED (ID_APPLY_NOW, OnApplyNow)
+END_MESSAGE_MAP ()
+
+
+// 『適用』ボタンが押された
+void COptionSheet::OnApplyNow () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ GetActivePage ()->UpdateData (TRUE);
+ pSekaijuApp->ApplyOptionSheet (this);
+ m_theGeneralOptionPage.SetModified (FALSE);
+ m_theColorOptionPage.SetModified (FALSE);
+ m_theTrackListOption1Page.SetModified (FALSE);
+ m_theTrackListOption2Page.SetModified (FALSE);
+ m_thePianoRollOptionPage.SetModified (FALSE);
+ m_theEventListOptionPage.SetModified (FALSE);
+ m_theMusicalScoreOptionPage.SetModified (FALSE);
+}
diff --git a/src/OptionSheet.h b/src/OptionSheet.h
new file mode 100644
index 0000000..dc8d2f6
--- /dev/null
+++ b/src/OptionSheet.h
@@ -0,0 +1,66 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// オプションプロパティシートクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _OPTIONSHEET_H_
+#define _OPTIONSHEET_H_
+
+#include "GeneralOptionPage.h"
+#include "ColorOptionPage.h"
+#include "TrackListOption1Page.h"
+#include "TrackListOption2Page.h"
+#include "PianoRollOptionPage.h"
+#include "EventListOptionPage.h"
+#include "MusicalScoreOptionPage.h"
+
+class COptionSheet : public CPropertySheet {
+ //--------------------------------------------------------------------------
+ // 各ページ
+ //--------------------------------------------------------------------------
+public:
+ CGeneralOptionPage m_theGeneralOptionPage;
+ CColorOptionPage m_theColorOptionPage;
+ CTrackListOption1Page m_theTrackListOption1Page;
+ CTrackListOption2Page m_theTrackListOption2Page;
+ CPianoRollOptionPage m_thePianoRollOptionPage;
+ CEventListOptionPage m_theEventListOptionPage;
+ CMusicalScoreOptionPage m_theMusicalScoreOptionPage;
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ COptionSheet (CWnd* pParentWnd); // コンストラクタ
+ virtual ~COptionSheet (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+ virtual BOOL OnInitDialog ();
+ virtual BOOL OnCommand (WPARAM wParam, LPARAM lParam);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnApplyNow ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/PianoRollFrame.cpp b/src/PianoRollFrame.cpp
new file mode 100644
index 0000000..f766d33
--- /dev/null
+++ b/src/PianoRollFrame.cpp
@@ -0,0 +1,2957 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールフレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "common.h"
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "resource.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "PianoRollPrintView.h"
+#include "PianoRollScaleView.h"
+#include "PianoRollTimeScaleView.h"
+#include "PianoRollKeyScaleView.h"
+#include "PianoRollKeyTimeView.h"
+#include "PianoRollVelScaleView.h"
+#include "PianoRollVelTimeView.h"
+#include "TrackListBox.h"
+#include "GraphKindListBox.h"
+#include "PropertyNoteDlg.h"
+
+// アロケーションの監視
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// 子ウィンドウのサイズ
+#define PIANOROLLFRAME_SCALEHEIGHT 32
+#define PIANOROLLFRAME_SCALEWIDTH 64
+#define PIANOROLLFRAME_TIMEWIDTH 600
+#define PIANOROLLFRAME_KEYHEIGHT 256
+
+
+#define PIANOROLLFRAME_VELHEIGHT 128
+#define PIANOROLLFRAME_SCROLLBARHEIGHT 16
+#define PIANOROLLFRAME_SCROLLBARWIDTH 16
+#define PIANOROLLFRAME_BORDERWIDTH 2
+#define PIANOROLLFRAME_BORDERHEIGHT 2
+#define PIANOROLLFRAME_SPLITTERWIDTH 4
+#define PIANOROLLFRAME_SPLITTERHEIGHT 4
+#define PIANOROLLFRAME_TRACKLISTWIDTH 120
+
+// 子ウィンドウIDを定義
+#define PIANOROLLFRAME_DUMMYVIEW (AFX_IDW_PANE_FIRST + 0)
+#define PIANOROLLFRAME_PRINTVIEW (AFX_IDW_PANE_FIRST + 31)
+#define PIANOROLLFRAME_SCALEVIEW (AFX_IDW_PANE_FIRST + 32)
+#define PIANOROLLFRAME_TIMESCALEVIEW (AFX_IDW_PANE_FIRST + 33)
+#define PIANOROLLFRAME_KEYSCALEVIEW (AFX_IDW_PANE_FIRST + 34)
+#define PIANOROLLFRAME_KEYTIMEVIEW (AFX_IDW_PANE_FIRST + 35)
+#define PIANOROLLFRAME_VELSCALEVIEW (AFX_IDW_PANE_FIRST + 36)
+#define PIANOROLLFRAME_VELTIMEVIEW (AFX_IDW_PANE_FIRST + 37)
+#define PIANOROLLFRAME_TIMESCROLL (AFX_IDW_PANE_FIRST + 48)
+#define PIANOROLLFRAME_KEYSCROLL (AFX_IDW_PANE_FIRST + 49)
+#define PIANOROLLFRAME_VELSCROLL (AFX_IDW_PANE_FIRST + 50)
+#define PIANOROLLFRAME_SIZEBOX (AFX_IDW_PANE_FIRST + 51)
+#define PIANOROLLFRAME_TIMEZOOMDOWN (AFX_IDW_PANE_FIRST + 52)
+#define PIANOROLLFRAME_TIMEZOOMUP (AFX_IDW_PANE_FIRST + 53)
+#define PIANOROLLFRAME_KEYZOOMDOWN (AFX_IDW_PANE_FIRST + 54)
+#define PIANOROLLFRAME_KEYZOOMUP (AFX_IDW_PANE_FIRST + 55)
+#define PIANOROLLFRAME_VELZOOMDOWN (AFX_IDW_PANE_FIRST + 56)
+#define PIANOROLLFRAME_VELZOOMUP (AFX_IDW_PANE_FIRST + 57)
+#define PIANOROLLFRAME_TRACKLIST (AFX_IDW_PANE_FIRST + 58)
+#define PIANOROLLFRAME_GRAPHKINDLIST (AFX_IDW_PANE_FIRST + 59)
+
+//
+// ピアノロールフレームのクライアント領域に配置されたオブジェクト
+//                             m_lScr ┃ m_lTrack
+// ┃←m_lScale→│← m_lTime  →│←ollBar→★← ListWidth →┃
+// Width Width    Width ┃
+// ─
+// ↑ ┏─────────────────────────────────┓
+// m_lToolBar1Height┃CToolBar ┃
+//  ↓ ┃m_wndToolBar1 ┃
+// ━ ┣━━━━━━┯━━━━━━━━━━━━━━┯━┳━━━━━━━┯━┫
+// ↑ ┃CView* │CView*    │↑┃CCheckListBox*│↑┃
+// m_lScaleHeight ┃m_pScaleView│m_pTimeScaleView    ├─┨m_pTrackList ├─┨
+// ↓ ┠──────┼──────────────┤ ┃(With Scroll │ ┃
+// ─ ┃CView*  │CView*      │□★ Bar) │□┃
+// ↑ ┃m_pKeyScale │m_pKeyTimeView    │ ┃ │ ┃
+// ┃View │              ├─┨ │ ┃
+// m_lKeyHeight ┃    │ CScrollBar m_wndKeyScroll│↓┃ │ ┃
+// ┃    │              ├─┨ ├─┨
+// ┃    │  CButton m_wndKeyZoomDown│−┃ │↓┃
+// ┃    │              ├─┨─┬───┬─┼─┨
+// ↓ ┃    │    CButton m_wndKeyZoomUp│+┃←│□  │→│ ┃
+// ━★━ ┣━━━━━━┿━━━━★━━━━━━━━━┿━╋━┷━★━┷━┿━┫
+// ↑ ┃CView*   │CView*           │↑┃CCheckListBox*│↑┃ 
+// ┃m_pVelScale │m_pVelTimeView ├─┨m_pGraphKind ├─┨
+// ┃View │    │□┃List │□┃
+// ┃ │    │ ★(With Scroll │ ┃
+// m_lVelHeight ┃ │              ├─┨ Bar) │ ┃
+// ┃    │  CScrollBar m_wndVelScroll│↓┃ │ ┃
+// ┃    │              ├─┨ │ ┃
+// ┃    │  CButton m_wndVelZoomDown│−┃ │ ┃
+// ↓ ┃    │              ├─┨ ├─┨
+// ─  ┃    │   CButton m_wndVelZoomUp│+┃ │↓┃
+// ↑ ┠─┬────┴────────┬─┬─┬─┼─┨─┬───┬─┼─┨
+//m_lScrollBarHeight┃←│   □         │→│−│+│⊿┃←│□  │→│ ┃  
+// ↓ ┗━┷━━━━━━━━━━━━━┷━┷━┷━┷━┻━┷━━━┷━┷━┛
+// ━ CScrollBar CButton CButton
+// m_wndTimeScroll m_wndTime m_wndTime
+// ZoomDown ZoomDown
+//
+// (あ)———:単純な境界線(0px)。
+// (い)━━━:太く立体的な境界線。BORDERWIDTH(2px)又はBORDERHEIGHT(2px)で示す幅を占領
+// (う)━★━:スプリッター境界線。(い)*2+SPRITTERWIDTH(4px)又はSPRITTERHEIGHT(4px)で示す幅を占領。
+//
+
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE(CPianoRollFrame, CChildFrame)
+
+BEGIN_MESSAGE_MAP(CPianoRollFrame, CChildFrame)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_SIZE ()
+ ON_WM_TIMER ()
+ ON_WM_ERASEBKGND ()
+ ON_WM_MDIACTIVATE ()
+ ON_WM_PAINT ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_HSCROLL ()
+ ON_WM_VSCROLL ()
+ ON_BN_CLICKED (PIANOROLLFRAME_TIMEZOOMDOWN, OnTimeZoomDown)
+ ON_BN_CLICKED (PIANOROLLFRAME_TIMEZOOMUP, OnTimeZoomUp)
+ ON_BN_CLICKED (PIANOROLLFRAME_KEYZOOMDOWN, OnKeyZoomDown)
+ ON_BN_CLICKED (PIANOROLLFRAME_KEYZOOMUP, OnKeyZoomUp)
+ ON_BN_CLICKED (PIANOROLLFRAME_VELZOOMDOWN, OnVelZoomDown)
+ ON_BN_CLICKED (PIANOROLLFRAME_VELZOOMUP, OnVelZoomUp)
+// ON_WM_CHILDACTIVATE ()
+ ON_COMMAND (ID_PIANOROLL_PEN, OnPianoRollPen)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_PEN, OnUpdatePianoRollPenUI)
+ ON_COMMAND (ID_PIANOROLL_LINE, OnPianoRollLine)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_LINE, OnUpdatePianoRollLineUI)
+ ON_COMMAND (ID_PIANOROLL_ERASER, OnPianoRollEraser)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_ERASER, OnUpdatePianoRollEraserUI)
+ ON_COMMAND (ID_PIANOROLL_SELECT, OnPianoRollSelect)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_SELECT, OnUpdatePianoRollSelectUI)
+ ON_COMMAND (ID_PIANOROLL_SPEAKER, OnPianoRollSpeaker)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_SPEAKER, OnUpdatePianoRollSpeakerUI)
+ ON_COMMAND (ID_PIANOROLL_ONLYCURTRACK, OnPianoRollOnlyCurTrack)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_ONLYCURTRACK, OnUpdatePianoRollOnlyCurTrackUI)
+ ON_COMMAND (ID_PIANOROLL_SHOWALLTRACK, OnPianoRollShowAllTrack)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_SHOWALLTRACK, OnUpdatePianoRollShowAllTrackUI)
+ ON_COMMAND (ID_PIANOROLL_ONLYCURGRAPH, OnPianoRollOnlyCurGraph)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_ONLYCURGRAPH, OnUpdatePianoRollOnlyCurGraphUI)
+ ON_COMMAND (ID_PIANOROLL_SHOWALLGRAPH, OnPianoRollShowAllGraph)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_SHOWALLGRAPH, OnUpdatePianoRollShowAllGraphUI)
+ ON_COMMAND (ID_PIANOROLL_AUTOPAGEUPDATE, OnPianoRollAutoPageUpdate)
+ ON_UPDATE_COMMAND_UI (ID_PIANOROLL_AUTOPAGEUPDATE, OnUpdatePianoRollAutoPageUpdateUI)
+
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEON, OnPopupTrackVisibleOn)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEON, OnUpdatePopupTrackVisibleOnUI)
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEOFF, OnPopupTrackVisibleOff)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEOFF, OnUpdatePopupTrackVisibleOffUI)
+ ON_COMMAND (ID_POPUP_TRACKVISIBLEALL, OnPopupTrackVisibleAll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEALL, OnUpdatePopupTrackVisibleAllUI)
+ ON_COMMAND (ID_POPUP_EVENTPROPERTY, OnPopupEventProperty)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_EVENTPROPERTY, OnUpdatePopupEventPropertyUI)
+ ON_COMMAND (ID_POPUP_GRAPHKINDVISIBLEON, OnPopupGraphKindVisibleOn)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEON, OnUpdatePopupGraphKindVisibleOnUI)
+ ON_COMMAND (ID_POPUP_GRAPHKINDVISIBLEOFF, OnPopupGraphKindVisibleOff)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEOFF, OnUpdatePopupGraphKindVisibleOffUI)
+ ON_COMMAND (ID_POPUP_GRAPHKINDVISIBLEALL, OnPopupGraphKindVisibleAll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKVISIBLEALL, OnUpdatePopupGraphKindVisibleAllUI)
+
+
+ ON_CBN_SELENDOK (IDC_TRACKCOMBO, OnTrackComboSelEndOK)
+ ON_CLBN_CHKCHANGE (PIANOROLLFRAME_TRACKLIST, OnTrackListChkChange)
+ ON_LBN_SELCHANGE (PIANOROLLFRAME_TRACKLIST, OnTrackListSelChange)
+
+ ON_CBN_SELENDOK (IDC_GRAPHKINDCOMBO, OnGraphKindComboSelEndOK)
+ ON_CLBN_CHKCHANGE (PIANOROLLFRAME_GRAPHKINDLIST, OnGraphKindListChkChange)
+ ON_LBN_SELCHANGE (PIANOROLLFRAME_GRAPHKINDLIST, OnGraphKindListSelChange)
+
+END_MESSAGE_MAP()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollFrame::CPianoRollFrame () {
+ long i;
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_lKeyHeight = PIANOROLLFRAME_KEYHEIGHT;
+ m_lScaleHeight = PIANOROLLFRAME_SCALEHEIGHT;
+ m_lVelHeight = PIANOROLLFRAME_VELHEIGHT + 16;
+ m_lScaleWidth = PIANOROLLFRAME_SCALEWIDTH;
+ m_lTimeWidth = PIANOROLLFRAME_TIMEWIDTH;
+ //m_lSplitterHeight = PIANOROLLFRAME_SPLITTERHEIGHT;
+ //m_lSplitterWidth = PIANOROLLFRAME_SPLITTERWIDTH;
+ m_lHScrollBarHeight = ::GetSystemMetrics (SM_CYHSCROLL);
+ m_lVScrollBarWidth = ::GetSystemMetrics (SM_CXVSCROLL);
+ m_lTrackListWidth = PIANOROLLFRAME_TRACKLISTWIDTH;
+ m_lVelZoom = pSekaijuApp->m_thePianoRollOption.m_lDefVelZoom;
+ m_lKeyZoom = pSekaijuApp->m_thePianoRollOption.m_lDefKeyZoom;
+ m_lTimeZoom = pSekaijuApp->m_thePianoRollOption.m_lDefTimeZoom;
+ m_lTimeScrollPos = 0;
+ CString strDefaultFontName;
+ VERIFY (strDefaultFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (12, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strDefaultFontName);
+ m_lCurTool = ID_PIANOROLL_PEN; // デフォルトのツール=ペン
+ m_bAutoPageUpdate = FALSE; // 自動ページ更新=ON
+ m_bOnlyCurTrack = FALSE; // 現在のトラックのみ表示=OFF
+ m_bShowAllTrack = FALSE; // すべてのトラックを表示=OFF
+ for (i = 0; i < MAXMIDITRACKNUM; i++) {
+ m_bTrackVisible[i] = TRUE; // すべてのトラックを可視にする。
+ }
+ m_bOnlyCurGraph = FALSE; // 現在のトラックのグラフのみ表示=OFF
+ m_bShowAllGraph = FALSE; // すべてのトラックのグラフを表示=OFF
+ for (i = 0; i < 256; i++) {
+ m_bGraphVisible[i] = FALSE; // 全グラフを不可視にする。
+ }
+ m_bGraphVisible[1] = TRUE; // ベロシティのグラフだけ可視にする。
+}
+
+// デストラクタ
+CPianoRollFrame::~CPianoRollFrame () {
+ m_theFont.DeleteObject ();
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// ドキュメントの取得
+CSekaijuDoc* CPianoRollFrame::GetDocument () {
+ ASSERT (m_pDummyView);
+ return (CSekaijuDoc*)m_pDummyView->GetDocument ();
+}
+
+// 時間方向のズーム倍率取得
+long CPianoRollFrame::GetTimeZoom () {
+ return m_lTimeZoom;
+}
+
+// キー方向のズーム倍率取得
+long CPianoRollFrame::GetKeyZoom () {
+ return m_lKeyZoom;
+}
+
+// ベロシティ方向のズーム倍率取得
+long CPianoRollFrame::GetVelZoom () {
+ return m_lVelZoom;
+}
+
+// y座標をノートキーに変換
+long CPianoRollFrame::YtoKey (long y) {
+ return 127 - (y / GetKeyZoom ());
+}
+
+// ノートキーをy座標に変換
+long CPianoRollFrame::KeytoY (long lKey) {
+ return (128 - lKey) * GetKeyZoom ();
+}
+
+// y座標をベロシティに変換
+long CPianoRollFrame::YtoVel (long y) {
+ return (128 * m_lVelZoom + 8 - y) / m_lVelZoom;
+}
+
+// y座標をピッチベンドに変換
+long CPianoRollFrame::YtoPitchBend (long y) {
+ return (128 * m_lVelZoom + 8 - y) * 128 / m_lVelZoom;
+}
+
+// y座標をテンポ[BPM]に変換
+long CPianoRollFrame::YtoTempoBPM (long y) {
+ return (128 * m_lVelZoom + 8 - y) * 2 / m_lVelZoom;
+}
+
+// ベロシティをy座標に変換
+long CPianoRollFrame::VeltoY (long lVel) {
+ return (128 - lVel) * m_lVelZoom + 8;
+}
+
+// ピッチベンドをy座標に変換
+long CPianoRollFrame::PitchBendtoY (long lPitchBend) {
+ return (16384 - lPitchBend) * m_lVelZoom / 128 + 8;
+}
+
+// テンポ[BPM]をy座標に変換
+long CPianoRollFrame::TempoBPMtoY (long lTempoBPM) {
+ return (256 - lTempoBPM) * m_lVelZoom / 2 + 8;
+}
+
+// x座標からタイムを取得
+long CPianoRollFrame::XtoTime (long x) {
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return x * lTimeResolution / 4 / m_lTimeZoom;
+ // 注:ズーム倍率1倍のとき4分音符の長さを4ピクセルと定義している。
+}
+
+// タイムをx座標に変換
+long CPianoRollFrame::TimetoX (long lTime) {
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return lTime * 4 * m_lTimeZoom / lTimeResolution;
+ // 注:ズーム倍率1倍のとき4分音符の長さを4ピクセルと定義している。
+}
+
+
+
+// 時間方向のスクロールポジション取得
+long CPianoRollFrame::GetTimeScrollPos () {
+ return m_lTimeScrollPos;
+}
+
+// キー方向のスクロールポジション取得
+long CPianoRollFrame::GetKeyScrollPos () {
+ return m_lKeyScrollPos;
+}
+
+// ベロシティ方向のスクロールポジション取得
+long CPianoRollFrame::GetVelScrollPos () {
+ return m_lVelScrollPos;
+}
+
+// 時間方向のスクロールポジション設定
+long CPianoRollFrame::SetTimeScrollPos (long lTimeScrollPos) {
+ long lOldTimeScrollPos = m_lTimeScrollPos;
+ m_wndTimeScroll.SetScrollPos (lTimeScrollPos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ long lDeltaTimeScrollPos = m_lTimeScrollPos - lOldTimeScrollPos;
+ m_pTimeScaleView->ScrollWindow (-lDeltaTimeScrollPos, 0);
+ m_pKeyTimeView->ScrollWindow (-lDeltaTimeScrollPos, 0);
+ m_pVelTimeView->ScrollWindow (-lDeltaTimeScrollPos, 0);
+ m_pTimeScaleView->UpdateWindow ();
+ m_pKeyTimeView->UpdateWindow ();
+ m_pVelTimeView->UpdateWindow ();
+ return m_lTimeScrollPos;
+}
+
+// キー方向のスクロールポジション設定
+long CPianoRollFrame::SetKeyScrollPos (long lKeyScrollPos) {
+ long lOldKeyScrollPos = m_lKeyScrollPos;
+ m_wndKeyScroll.SetScrollPos (lKeyScrollPos);
+ m_lKeyScrollPos = m_wndKeyScroll.GetScrollPos ();
+ long lDeltaKeyScrollPos = m_lKeyScrollPos - lOldKeyScrollPos;
+ m_pKeyScaleView->ScrollWindow (0, -lDeltaKeyScrollPos);
+ m_pKeyTimeView->ScrollWindow (0, -lDeltaKeyScrollPos);
+ m_pKeyScaleView->UpdateWindow ();
+ m_pKeyTimeView->UpdateWindow ();
+ return m_lKeyScrollPos;
+}
+
+// ベロシティ方向のスクロールポジション設定
+long CPianoRollFrame::SetVelScrollPos (long lVelScrollPos) {
+ long lOldVelScrollPos = m_lVelScrollPos;
+ m_wndVelScroll.SetScrollPos (lVelScrollPos);
+ m_lVelScrollPos = m_wndVelScroll.GetScrollPos ();
+ long lDeltaVelScrollPos = m_lVelScrollPos - lOldVelScrollPos;
+ m_pVelScaleView->ScrollWindow (0, -lDeltaVelScrollPos);
+ m_pVelTimeView->ScrollWindow (0, -lDeltaVelScrollPos);
+ m_pVelScaleView->UpdateWindow ();
+ m_pVelTimeView->UpdateWindow ();
+ return m_lVelScrollPos;
+}
+
+
+
+// 表示されているタイムの左端を求める
+long CPianoRollFrame::GetVisibleLeftTime () {
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return m_lTimeScrollPos * lTimeResolution / 4 / m_lTimeZoom;
+ // 注:ズーム倍率1倍のとき4分音符の長さを4ピクセルと定義している。
+}
+
+// 表示されているタイムの右端を求める
+long CPianoRollFrame::GetVisibleRightTime () {
+ CRect rcClient;
+ m_pTimeScaleView->GetClientRect (&rcClient);
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return (m_lTimeScrollPos + rcClient.Width ()) * lTimeResolution / 4 / m_lTimeZoom;
+ // 注:ズーム倍率1倍のとき4分音符の長さを4ピクセルと定義している。
+}
+
+// 表示されているキーの上限を計算
+long CPianoRollFrame::GetVisibleTopKey () {
+ return 127 - (m_lKeyScrollPos / m_lKeyZoom);
+}
+
+// 表示されているキーの下限を計算
+long CPianoRollFrame::GetVisibleBottomKey () {
+ CRect rcClient;
+ m_pKeyScaleView->GetClientRect (&rcClient);
+ return 127 - (m_lKeyScrollPos + rcClient.Height ()) / m_lKeyZoom;
+}
+
+// 表示されているベロシティの上限を計算
+long CPianoRollFrame::GetVisibleTopVel() {
+ return 127 - (m_lVelScrollPos / m_lVelZoom);
+}
+
+// 表示されているベロシティの下限を計算
+long CPianoRollFrame::GetVisibleBottomVel () {
+ CRect rcClient;
+ m_pVelScaleView->GetClientRect (&rcClient);
+ return 127 - (m_lVelScrollPos + rcClient.Height ()) / m_lVelZoom;
+}
+
+
+
+// スプリッターキャプターの描画
+void CPianoRollFrame::DrawSplitterCaptor (CDC* pDC, CPoint pt) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CPen pen;
+ CPen* pOldPen;
+ pen.CreatePen (PS_SOLID, 4, ::GetSysColor(COLOR_BTNSHADOW));
+ pDC->SetROP2 (R2_XORPEN);
+ pOldPen = pDC->SelectObject (&pen);
+ if (m_bSplitterMovingH) {
+ pDC->MoveTo (0, pt.y);
+ pDC->LineTo (rcClient.Width (), pt.y);
+ }
+ if (m_bSplitterMovingV) {
+ pDC->MoveTo (pt.x, 0);
+ pDC->LineTo (pt.x, rcClient.Height ());
+ }
+ pDC->SelectObject (pOldPen);
+}
+
+
+
+
+// 現在のトラックのインデックスを取得
+long CPianoRollFrame::GetCurTrackIndex () {
+ return m_pTrackListBox->GetCurSel ();
+}
+
+// 現在のチャンネルを取得
+long CPianoRollFrame::GetCurChannel () {
+ return m_wndChannelCombo.GetCurSel ();
+}
+
+// 現在のスナップ[ティック]を取得
+long CPianoRollFrame::GetCurSnap () {
+ CString strText;
+ m_wndSnapCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在のベロシティを取得
+long CPianoRollFrame::GetCurVelocity () {
+ CString strText;
+ m_wndVelocityCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在の(音符の)長さ[ティック]を取得
+long CPianoRollFrame::GetCurDuration () {
+ CString strText;
+ m_wndDurationCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在のグラフの種類を取得
+long CPianoRollFrame::GetCurGraphKind () {
+ return m_pGraphKindListBox->GetCurSel ();
+}
+
+// 現在のグラフのスナップ[ティック]を取得
+long CPianoRollFrame::GetCurGraphSnap () {
+ CString strText;
+ m_wndGraphSnapCombo.GetWindowText (strText);
+ return _ttol (strText);
+}
+
+// 現在のトラックのインデックスを設定
+BOOL CPianoRollFrame::SetCurTrackIndex (long lCurTrackIndex) {
+ ASSERT (0 <= lCurTrackIndex && lCurTrackIndex < MAXMIDITRACKNUM);
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ m_wndTrackCombo.SetCurSel (lCurTrackIndex);
+ m_pTrackListBox->SetCurSel (lCurTrackIndex);
+ //m_pCurTrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (m_bOnlyCurTrack) {
+ long lCount = m_pTrackListBox->GetCount ();
+ for (long i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, (i == lCurTrackIndex ? 1 : 0));
+ }
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ }
+ return TRUE;
+}
+
+// 現在のチャンネルを設定
+BOOL CPianoRollFrame::SetCurChannel (long lCurChannel) {
+ ASSERT (0 <= lCurChannel && lCurChannel < 16);
+ m_wndChannelCombo.SetCurSel (lCurChannel);
+ return TRUE;
+}
+
+// 現在のスナップ[ティック]を設定
+BOOL CPianoRollFrame::SetCurSnap (long lCurSnap) {
+ ASSERT (1 <= lCurSnap);
+ CString strText;
+ strText.Format (_T("%d"), lCurSnap);
+ m_wndSnapCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 現在のベロシティを設定
+BOOL CPianoRollFrame::SetCurVelocity (long lCurVelocity) {
+ ASSERT (0 <= lCurVelocity && lCurVelocity <= 127);
+ CString strText;
+ strText.Format (_T("%d"), lCurVelocity);
+ m_wndVelocityCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 現在の(音符の)長さ[ティック]を設定
+BOOL CPianoRollFrame::SetCurDuration (long lCurDuration) {
+ ASSERT (0 <= lCurDuration);
+ CString strText;
+ strText.Format (_T("%d"), lCurDuration);
+ m_wndDurationCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 現在のグラフの種類を設定
+BOOL CPianoRollFrame::SetCurGraphKind (long lCurGraphKind) {
+ ASSERT (0 <= lCurGraphKind && lCurGraphKind < 256);
+ m_wndGraphKindCombo.SetCurSel (lCurGraphKind);
+ m_pGraphKindListBox->SetCurSel (lCurGraphKind);
+ if (m_bOnlyCurGraph) {
+ long lCount = m_pGraphKindListBox->GetCount ();
+ for (long i = 0; i < lCount; i++) {
+ m_pGraphKindListBox->SetCheck (i, (i == lCurGraphKind ? 1 : 0));
+ }
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ }
+ return TRUE;
+}
+
+// 現在のグラフスナップ[ティック]を設定
+BOOL CPianoRollFrame::SetCurGraphSnap (long lCurSnap) {
+ ASSERT (1 <= lCurSnap);
+ CString strText;
+ strText.Format (_T("%d"), lCurSnap);
+ m_wndGraphSnapCombo.SetWindowText (strText);
+ return TRUE;
+}
+
+// 指定インデックスのトラックが表示状態か調べる
+BOOL CPianoRollFrame::IsTrackVisible (long lTrackIndex) {
+ // (1)現在のトラックのみ表示がONのときは、現在のトラックのみがVisible、他はUnVisible。
+ // (2)すべてのトラックを表示がONのときは、全てのトラックがVisible。
+ // (3)その他の場合(通常時)は、m_bTrackVisible[MAXMIDITRACKNUM]の値に従う。
+ ASSERT (0 <= lTrackIndex && lTrackIndex < MAXMIDITRACKNUM);
+ if (m_bOnlyCurTrack == TRUE &&
+ GetCurTrackIndex () == lTrackIndex ||
+ m_bShowAllTrack == TRUE ||
+ m_bShowAllTrack == FALSE &&
+ m_bOnlyCurTrack == FALSE &&
+ m_bTrackVisible[lTrackIndex] == TRUE) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// 指定インデックスのトラックを表示状態にする
+BOOL CPianoRollFrame::SetTrackVisible (long lTrackIndex) {
+ // (1)現在のトラックのみ表示がONのときは、現在のトラックを指定トラックに変更する
+ // (2)すべてのトラックを表示がONのときは、何もしない。
+ // (3)その他の場合(通常時)は、m_bTrackVisible[lTrackIndex]をチェック・可視化する。
+ ASSERT (0 <= lTrackIndex && lTrackIndex < MAXMIDITRACKNUM);
+ if (m_bOnlyCurTrack == TRUE) {
+ m_wndTrackCombo.SetCurSel (lTrackIndex);
+ m_pTrackListBox->SetCurSel (lTrackIndex);
+ }
+ else if (m_bShowAllTrack == TRUE) {
+ ;
+ }
+ else {
+ m_pTrackListBox->SetCheck (lTrackIndex, TRUE);
+ m_bTrackVisible[lTrackIndex] = TRUE;
+ }
+ return TRUE;
+}
+
+// 指定種類のグラフが表示状態か調べる
+BOOL CPianoRollFrame::IsGraphVisible (long lGraphKind) {
+ // (1)現在のグラフのみ表示がONのときは、現在のグラフのみがVisible、他はUnVisible。
+ // (2)すべてのグラフを表示がONのときは、全てのグラフがVisible。
+ // (3)その他の場合(通常時)は、m_bGraphVisible[MAXMIDITRACKNUM]の値に従う。
+ ASSERT (0 <= lGraphKind && lGraphKind < 256);
+ if (m_bOnlyCurGraph == TRUE &&
+ GetCurGraphKind () == lGraphKind ||
+ m_bShowAllGraph == TRUE ||
+ m_bShowAllGraph == FALSE &&
+ m_bOnlyCurGraph == FALSE &&
+ m_bGraphVisible[lGraphKind] == TRUE) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// 指定種類のグラフを表示状態にする
+BOOL CPianoRollFrame::SetGraphVisible (long lGraphKind) {
+ // (1)現在のグラフのみ表示がONのときは、現在のトラックを指定トラックに変更する
+ // (2)すべてのグラフを表示がONのときは、何もしない。
+ // (3)その他の場合(通常時)は、m_bGraphKindVisible[lGraphKind]をチェック・可視化する。
+ ASSERT (0 <= lGraphKind && lGraphKind < m_pGraphKindListBox->GetCount ());
+ if (m_bOnlyCurGraph == TRUE) {
+ m_wndGraphKindCombo.SetCurSel (lGraphKind);
+ m_pGraphKindListBox->SetCurSel (lGraphKind);
+ }
+ else if (m_bShowAllGraph == TRUE) {
+ ;
+ }
+ else {
+ m_pGraphKindListBox->SetCheck (lGraphKind, TRUE);
+ m_bGraphVisible[lGraphKind] = TRUE;
+ }
+ return TRUE;
+}
+
+// トラックコンボの更新
+BOOL CPianoRollFrame::UpdateTrackCombo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ //pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ // 旧状態の保持
+ static MIDITrack* pOldMIDITrack[MAXMIDITRACKNUM];
+ BOOL bOldTrackVisible[MAXMIDITRACKNUM];
+ memcpy (bOldTrackVisible, m_bTrackVisible, sizeof (BOOL) * MAXMIDITRACKNUM);
+ long lOldCurSel = m_wndTrackCombo.GetCurSel ();
+ long lOldCount = m_wndTrackCombo.GetCount ();
+ MIDITrack* pOldCurTrack = NULL;
+ if (0 <= lOldCurSel && lOldCurSel < __min (lOldCount, MAXMIDITRACKNUM)) {
+ pOldCurTrack = pOldMIDITrack[lOldCurSel];
+ }
+
+ // コンボの初期化
+ m_wndTrackCombo.RemoveAllItem ();
+
+ // コンボに項目を追加
+ long i = 0;
+ long j = 0;
+ TCHAR szTrackName1[1024];
+ TCHAR szTrackName2[1024];
+ CString strText;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ memset (szTrackName1, 0, sizeof (szTrackName1));
+ memset (szTrackName2, 0, sizeof (szTrackName2));
+ MIDITrack_GetName (pMIDITrack, szTrackName1, sizeof (szTrackName1) - 1);
+ codestr2str (szTrackName1, TCSLEN (szTrackName1), szTrackName2, TSIZEOF (szTrackName2) - 1);
+ strText.Format (_T("%d-%s"), i + (bTrackZeroOrigin ? 0 : 1), szTrackName2);
+ long lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ m_wndTrackCombo.AddItem (strText, lForeColor, lBackColor);
+
+ // 現在のトラックである場合選択
+ if (pMIDITrack == pOldCurTrack) {
+ m_wndTrackCombo.SetCurSel (i);
+ }
+ i++;
+ }
+
+ // 現在選択しているものがない場合は強制選択
+ long lNewCount = m_wndTrackCombo.GetCount ();
+ long lNewCurSel = m_wndTrackCombo.GetCurSel ();
+ if (m_wndTrackCombo.GetCurSel () == CB_ERR) {
+ if (0 <= lOldCurSel && lOldCurSel < lNewCount) {
+ m_wndTrackCombo.SetCurSel (lOldCurSel);
+ }
+ else if (lNewCount >= 2) {
+ m_wndTrackCombo.SetCurSel (1);
+ }
+ else {
+ m_wndTrackCombo.SetCurSel (0);
+ }
+ }
+
+ // 次回のアップデート呼び出しに備えて現状を保持する。
+ i = 0;
+ memset (pOldMIDITrack, 0, sizeof (MIDITrack*) * MAXMIDITRACKNUM);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ pOldMIDITrack[i] = pMIDITrack;
+ i++;
+ }
+
+ //pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+// グラフの種類コンボの更新
+BOOL CPianoRollFrame::UpdateGraphKindCombo () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CString strText;
+ m_wndGraphKindCombo.ResetContent ();
+ VERIFY (strText.LoadString (IDS_TEMPO));
+ m_wndGraphKindCombo.AddString (strText);
+ VERIFY (strText.LoadString (IDS_VELOCITY));
+ m_wndGraphKindCombo.AddString (strText);
+ VERIFY (strText.LoadString (IDS_CHANNELAFTERTOUCH));
+ m_wndGraphKindCombo.AddString (strText);
+ VERIFY (strText.LoadString (IDS_PITCHBEND));
+ m_wndGraphKindCombo.AddString (strText);
+ TCHAR szName[1024];
+ long lTrackIndex = GetCurTrackIndex ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ long lPortNumber = MIDITrack_GetOutputPort (pMIDITrack);
+ MIDIInstrumentDefinition* pMIDIInstDefNorm = NULL;
+ MIDIControllerNameTable* pMIDIControllerNameTable = NULL;
+ if (0 <= lPortNumber && lPortNumber < MAXMIDIOUTDEVICENUM) {
+ pMIDIInstDefNorm = ((CSekaijuApp*)AfxGetApp())->m_pMIDIInstDefNorm[lPortNumber];
+ if (pMIDIInstDefNorm) {
+ pMIDIControllerNameTable = MIDIInstrumentDefinition_GetControllerNameTable (pMIDIInstDefNorm);
+ }
+ }
+ for (long i = 0; i < 128; i++) {
+ memset (szName, 0, sizeof (szName));
+ if (pMIDIControllerNameTable) {
+ MIDIControllerNameTable_GetName (pMIDIControllerNameTable, i, szName, TSIZEOF (szName) - 1);
+ }
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_CC_D_S));
+ strText.Format (strFormat, i, szName);
+ m_wndGraphKindCombo.AddString (strText);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+// トラックリストボックスの更新
+BOOL CPianoRollFrame::UpdateTrackList () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ //pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ // 旧状態の保持
+ static MIDITrack* pOldMIDITrack[MAXMIDITRACKNUM];
+ BOOL bOldTrackVisible[MAXMIDITRACKNUM];
+ memcpy (bOldTrackVisible, m_bTrackVisible, sizeof (BOOL) * MAXMIDITRACKNUM);
+ long lOldCurSel = m_pTrackListBox->GetCurSel ();
+ long lOldCount = m_pTrackListBox->GetCount ();
+ MIDITrack* pOldCurTrack = NULL;
+ if (0 <= lOldCurSel && lOldCurSel < __min (lOldCount, MAXMIDITRACKNUM)) {
+ pOldCurTrack = pOldMIDITrack[lOldCurSel];
+ }
+
+ // リストの初期化
+ ((CColorfulCheckListBox*)m_pTrackListBox)->RemoveAllItem ();
+
+ // リストの更新
+ long i = 0;
+ long j = 0;
+ TCHAR szTrackName1[1024];
+ TCHAR szTrackName2[1024];
+ CString strText;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ memset (szTrackName1, 0, sizeof (szTrackName1));
+ memset (szTrackName2, 0, sizeof (szTrackName2));
+ MIDITrack_GetName (pMIDITrack, szTrackName1, sizeof (szTrackName1) - 1);
+ codestr2str (szTrackName1, TCSLEN (szTrackName1), szTrackName2, TSIZEOF (szTrackName2) - 1);
+ strText.Format (_T("%d-%s"), i + (bTrackZeroOrigin ? 0 : 1), szTrackName2);
+ long lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lBackColor = ::GetSysColor (COLOR_WINDOW);
+ ((CColorfulCheckListBox*)m_pTrackListBox)->AddItem (strText, lForeColor, lBackColor);
+ // チェック状態変数の更新
+ m_bTrackVisible[i] = 1;
+ for (j = 0; j < MAXMIDITRACKNUM; j++) {
+ if (pOldMIDITrack[j] == NULL) {
+ break;
+ }
+ if (pOldMIDITrack[j] == pMIDITrack) {
+ m_bTrackVisible[i] = bOldTrackVisible[j];
+ break;
+ }
+ }
+ // 現在のトラックである場合選択
+ if (pMIDITrack == pOldCurTrack) {
+ m_pTrackListBox->SetCurSel (i);
+ }
+ i++;
+ }
+
+ // 現在選択しているものがない場合は強制選択
+ long lNewCount = m_pTrackListBox->GetCount ();
+ long lNewCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_pTrackListBox->GetCurSel () == LB_ERR) {
+ if (0 <= lOldCurSel && lOldCurSel < lNewCount) {
+ m_pTrackListBox->SetCurSel (lOldCurSel);
+ }
+ else if (lNewCount >= 2) {
+ m_pTrackListBox->SetCurSel (1);
+ }
+ else {
+ m_pTrackListBox->SetCurSel (0);
+ }
+ lNewCurSel = m_pTrackListBox->GetCurSel ();
+ }
+
+ // チェックボックスの完全更新
+ if (m_bShowAllTrack) {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, 1);
+ }
+ }
+ else if (m_bOnlyCurTrack) {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, 0);
+ }
+ if (0 <= lNewCurSel && lNewCurSel < lNewCount) {
+ m_pTrackListBox->SetCheck (lNewCurSel, 1);
+ }
+ }
+ else {
+ for (i = 0; i < lNewCount; i++) {
+ m_pTrackListBox->SetCheck (i, m_bTrackVisible[i]);
+ }
+ }
+
+
+ // 次回のアップデート呼び出しに備えて現状を保持する。
+ i = 0;
+ memset (pOldMIDITrack, 0, sizeof (MIDITrack*) * MAXMIDITRACKNUM);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (i >= MAXMIDITRACKNUM) {
+ break;
+ }
+ pOldMIDITrack[i] = pMIDITrack;
+ i++;
+ }
+
+ //pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+// グラフの種類リストの更新
+BOOL CPianoRollFrame::UpdateGraphKindList () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CString strText;
+ m_pGraphKindListBox->ResetContent ();
+ VERIFY (strText.LoadString (IDS_TEMPO));
+ m_pGraphKindListBox->AddString (strText);
+ VERIFY (strText.LoadString (IDS_VELOCITY));
+ m_pGraphKindListBox->AddString (strText);
+ VERIFY (strText.LoadString (IDS_CHANNELAFTERTOUCH));
+ m_pGraphKindListBox->AddString (strText);
+ VERIFY (strText.LoadString (IDS_PITCHBEND));
+ m_pGraphKindListBox->AddString (strText);
+ TCHAR szName[1024];
+ long lTrackIndex = GetCurTrackIndex ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ long lPortNumber = MIDITrack_GetOutputPort (pMIDITrack);
+ MIDIInstrumentDefinition* pMIDIInstDefNorm = NULL;
+ MIDIControllerNameTable* pMIDIControllerNameTable = NULL;
+ if (0 <= lPortNumber && lPortNumber < MAXMIDIOUTDEVICENUM) {
+ pMIDIInstDefNorm = ((CSekaijuApp*)AfxGetApp())->m_pMIDIInstDefNorm[lPortNumber];
+ if (pMIDIInstDefNorm) {
+ pMIDIControllerNameTable = MIDIInstrumentDefinition_GetControllerNameTable (pMIDIInstDefNorm);
+ }
+ }
+ for (long i = 0; i < 128; i++) {
+ memset (szName, 0, sizeof (szName));
+ if (pMIDIControllerNameTable) {
+ MIDIControllerNameTable_GetName (pMIDIControllerNameTable, i, szName, TSIZEOF (szName) - 1);
+ }
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_CC_D_S));
+ strText.Format (strFormat, i, szName);
+ m_pGraphKindListBox->AddString (strText);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+// スナップコンボボックスの更新
+BOOL CPianoRollFrame::UpdateSnapCombo () {
+ CString strText;
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)GetDocument ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ long lCurSel = m_wndSnapCombo.GetCurSel ();
+ m_wndSnapCombo.ResetContent ();
+ // スナップコンボボックスの充満
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_4DIVNOTE)); // %d-4分音符
+ strText.Format (strFormat, lTimeResolution * 1);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVNOTE)); // %d-8分音符
+ strText.Format (strFormat, lTimeResolution / 2);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVNOTE)); // %d-3連8分音符
+ strText.Format (strFormat, lTimeResolution / 3);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_16DIVNOTE)); // %d-16分音符
+ strText.Format (strFormat, lTimeResolution / 4);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_24DIVNOTE)); // %d-3連16分音符
+ strText.Format (strFormat, lTimeResolution / 6);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_32DIVNOTE)); // %d-32分音符
+ strText.Format (strFormat, lTimeResolution / 8);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_48DIVNOTE)); // %d-3連32分音符
+ strText.Format (strFormat, lTimeResolution / 12);
+ m_wndSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_FREE)); // %d-自由
+ strText.Format (strFormat, 1);
+ m_wndSnapCombo.AddString (strText);
+ // カレントセル設定
+ if (lCurSel >= 0) {
+ m_wndSnapCombo.SetCurSel (lCurSel);
+ }
+ return TRUE;
+}
+
+// ベロシティコンボボックスの更新
+BOOL CPianoRollFrame::UpdateVelocityCombo () {
+ long i;
+ CString strText;
+ long lCurSel = m_wndVelocityCombo.GetCurSel ();
+ m_wndVelocityCombo.ResetContent ();
+ // ベロシティコンボボックスの充満
+ for (i = 127; i >= 1; i--) {
+ if (i == 127 || (i % 5) == 0) {
+ strText.Format (_T("%d"), i);
+ m_wndVelocityCombo.AddString (strText);
+ }
+ }
+ // カレントセル設定
+ if (lCurSel >= 0) {
+ m_wndVelocityCombo.SetCurSel (lCurSel);
+ }
+ return TRUE;
+}
+
+// 長さコンボボックスの更新
+BOOL CPianoRollFrame::UpdateDurationCombo () {
+ CString strText;
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)GetDocument ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ //long lCurSel = m_wndDurationCombo.GetCurSel (); // 20100328廃止
+ CString strCurText;
+ m_wndDurationCombo.GetWindowText (strCurText); // 20100328追加
+ long i = 0;
+ long lCurSel = -1; // 20100328追加
+ for (i = 0; i < m_wndDurationCombo.GetCount (); i++) { // 20100328追加
+ CString strLBText; // 20100328追加
+ m_wndDurationCombo.GetLBText (i, strLBText); // 20100328追加
+ if (strLBText == strCurText) { // 20100328追加
+ lCurSel = i; // 20100328追加
+ break; // 20100328追加
+ } // 20100328追加
+ } // 20100328追加
+ m_wndDurationCombo.ResetContent ();
+ // 長さコンボボックスの充満
+ strText.Format (_T("%d"), lTimeResolution * 4);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution * 3);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution * 2);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution * 1);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 2);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 3);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 4);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 6);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 8);
+ m_wndDurationCombo.AddString (strText);
+ strText.Format (_T("%d"), lTimeResolution / 12);
+ m_wndDurationCombo.AddString (strText);
+ // カレントセルの設定
+ if (lCurSel >= 0) {
+ m_wndDurationCombo.SetCurSel (lCurSel);
+ }
+ else { // 20100328追加
+ m_wndDurationCombo.SetWindowText (strCurText); // 20100328追加
+ }
+ return TRUE;
+}
+
+// グラフスナップコンボボックスの更新
+BOOL CPianoRollFrame::UpdateGraphSnapCombo () {
+ CString strText;
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)GetDocument ();
+ long lTimeResolution = MIDIData_GetTimeResolution (pSekaijuDoc->m_pMIDIData);
+ long lCurSel = m_wndGraphSnapCombo.GetCurSel ();
+ m_wndGraphSnapCombo.ResetContent ();
+ // スナップコンボボックスの充満
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_4DIVNOTE)); // %d-4分音符
+ strText.Format (strFormat, lTimeResolution * 1);
+ m_wndGraphSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_8DIVNOTE)); // %d-8分音符
+ strText.Format (strFormat, lTimeResolution / 2);
+ m_wndGraphSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_12DIVNOTE)); // %d-3連8分音符
+ strText.Format (strFormat, lTimeResolution / 3);
+ m_wndGraphSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_16DIVNOTE)); // %d-16分音符
+ strText.Format (strFormat, lTimeResolution / 4);
+ m_wndGraphSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_24DIVNOTE)); // %d-3連16分音符
+ strText.Format (strFormat, lTimeResolution / 6);
+ m_wndGraphSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_32DIVNOTE)); // %d-32分音符
+ strText.Format (strFormat, lTimeResolution / 8);
+ m_wndGraphSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_48DIVNOTE)); // %d-3連32分音符
+ strText.Format (strFormat, lTimeResolution / 12);
+ m_wndGraphSnapCombo.AddString (strText);
+ VERIFY (strFormat.LoadString (IDS_D_FREE)); // %d-自由
+ strText.Format (strFormat, 1);
+ m_wndGraphSnapCombo.AddString (strText);
+ // カレントセル設定
+ if (lCurSel >= 0) {
+ m_wndGraphSnapCombo.SetCurSel (lCurSel);
+ }
+ return TRUE;
+}
+
+
+// キースクロールバー(縦)のデザイン設定
+void CPianoRollFrame::RecalcKeyScrollInfo () {
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = 128 * m_lKeyZoom;
+ si.nPage = m_lKeyHeight;
+ m_wndKeyScroll.SetScrollInfo (&si, TRUE);
+ m_lKeyScrollPos = m_wndKeyScroll.GetScrollPos ();
+}
+
+// ヴェロシティスクロールバー(縦)のデザイン設定
+void CPianoRollFrame::RecalcVelScrollInfo () {
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = PIANOROLLFRAME_VELHEIGHT * m_lVelZoom + 16;
+ si.nPage = m_lVelHeight;
+ m_wndVelScroll.SetScrollInfo (&si, TRUE);
+ m_lVelScrollPos = m_wndVelScroll.GetScrollPos ();
+}
+
+// タイムスクロールバー(横)のデザイン設定
+void CPianoRollFrame::RecalcTimeScrollInfo () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeResolution = 120;
+ long lEndTime = 0;
+ if (pMIDIData) {
+ lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ lEndTime = MIDIData_GetEndTime (pMIDIData);
+ }
+ long lFeedTime = lTimeResolution * 4 * 120;
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = (lEndTime + lFeedTime) * m_lTimeZoom * 4 / lTimeResolution;
+ si.nPage = m_lTimeWidth;
+ m_wndTimeScroll.SetScrollInfo (&si, TRUE);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ // 注:ズーム倍率1倍のとき4分音符の長さを4ピクセルと定義している。
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成直前の構造体設定
+BOOL CPianoRollFrame::PreCreateWindow (CREATESTRUCT& cs) {
+ return (CWnd::PreCreateWindow(cs));
+}
+
+// ウィンドウタイトルの自動設定(CMDIChildWnd::OnUpdateFrameTitleのオーバーライド)
+void CPianoRollFrame::OnUpdateFrameTitle (BOOL bAddToTitle) {
+ // update our parent window first
+ GetMDIFrame()->OnUpdateFrameTitle (bAddToTitle);
+ if ((GetStyle() & FWS_ADDTOTITLE) == 0) {
+ return; // leave child window alone!
+ }
+ CDocument* pDocument = GetActiveDocument();
+ if (bAddToTitle && pDocument != NULL) {
+ CString strPianoRoll;
+ strPianoRoll.LoadString (IDS_PIANOROLL);
+ CString strTitle;
+ if (m_nWindow > 0) {
+ strTitle.Format (_T("%s:%d(%s)"), pDocument->GetTitle (), m_nWindow, strPianoRoll);
+ }
+ else {
+ strTitle.Format (_T("%s(%s)"), pDocument->GetTitle (), strPianoRoll);
+ }
+ this->SetWindowText (strTitle);
+ }
+}
+
+// 再配置用関数(CFrameWnd::RecalcLayoutのオーバーライド)
+void CPianoRollFrame::RecalcLayout (BOOL bNotify) {
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+
+ // 基本クラスの関数を処理
+ CFrameWnd::RecalcLayout (bNotify);
+
+ // アイコン化時には各コントロールのサイズを再計算しない。
+ if (rcClient.Width () == 0 || rcClient.Height () == 0) {
+ return;
+ }
+
+ // ツールバー1の高さ取得
+ CRect rcToolBar1;
+ m_wndToolBar1.GetWindowRect (&rcToolBar1);
+ m_lToolBar1Height = rcToolBar1.Height ();
+
+ // 高さ方向の位置計算
+ if (rcClient.Height () - m_lToolBar1Height <
+ PIANOROLLFRAME_SCALEHEIGHT + m_lHScrollBarHeight +
+ PIANOROLLFRAME_BORDERHEIGHT * 4 + PIANOROLLFRAME_SPLITTERHEIGHT) {
+ m_lScaleHeight = rcClient.Height () - m_lHScrollBarHeight -
+ PIANOROLLFRAME_BORDERHEIGHT * 4 - PIANOROLLFRAME_SPLITTERHEIGHT;
+ m_lKeyHeight = 0;
+ m_lVelHeight = 0;
+ }
+ else if (rcClient.Height () - m_lToolBar1Height < m_lVelHeight +
+ PIANOROLLFRAME_SCALEHEIGHT + m_lHScrollBarHeight +
+ PIANOROLLFRAME_BORDERHEIGHT * 4 + PIANOROLLFRAME_SPLITTERHEIGHT) {
+ m_lScaleHeight = PIANOROLLFRAME_SCALEHEIGHT;
+ m_lKeyHeight = 0;
+ m_lVelHeight = rcClient.Height () - m_lToolBar1Height -
+ m_lScaleHeight - m_lHScrollBarHeight -
+ PIANOROLLFRAME_BORDERHEIGHT * 4 - PIANOROLLFRAME_SPLITTERHEIGHT;
+ }
+ else {
+ m_lScaleHeight = PIANOROLLFRAME_SCALEHEIGHT;
+ m_lKeyHeight = rcClient.Height () - m_lToolBar1Height -
+ m_lScaleHeight - m_lVelHeight - m_lHScrollBarHeight -
+ PIANOROLLFRAME_BORDERHEIGHT * 4 - PIANOROLLFRAME_SPLITTERHEIGHT;
+ m_lVelHeight = m_lVelHeight;
+ }
+ //m_lVelHeight = __min (m_lVelHeight, 128);
+
+ // 幅方向の位置計算
+ if (rcClient.Width () <
+ PIANOROLLFRAME_SCALEWIDTH + m_lVScrollBarWidth +
+ PIANOROLLFRAME_BORDERWIDTH * 4) {
+ m_lScaleWidth = rcClient.Width () -
+ m_lVScrollBarWidth - PIANOROLLFRAME_BORDERWIDTH * 4;
+ m_lTimeWidth = 0;
+ m_lTrackListWidth = 0;
+
+ }
+
+ else if (rcClient.Width () <
+ PIANOROLLFRAME_SCALEWIDTH + m_lVScrollBarWidth +
+ PIANOROLLFRAME_BORDERWIDTH * 4 + PIANOROLLFRAME_SPLITTERWIDTH + m_lTrackListWidth) {
+ //m_lScaleWidth = rcClient.Width () -
+ // m_lVScrollBarWidth - PIANOROLLFRAME_BORDERWIDTH * 2;
+ m_lScaleWidth = PIANOROLLFRAME_SCALEWIDTH;
+ m_lTimeWidth = 0;
+ m_lTrackListWidth = rcClient.Width () - m_lScaleWidth -
+ m_lVScrollBarWidth - PIANOROLLFRAME_BORDERWIDTH * 4 -
+ PIANOROLLFRAME_SPLITTERWIDTH;
+
+ }
+ else {
+ m_lScaleWidth = PIANOROLLFRAME_SCALEWIDTH;
+ m_lTimeWidth = rcClient.Width () - m_lScaleWidth -
+ m_lVScrollBarWidth - PIANOROLLFRAME_BORDERWIDTH * 4 -
+ PIANOROLLFRAME_SPLITTERWIDTH - m_lTrackListWidth;
+ m_lTrackListWidth = m_lTrackListWidth;
+ }
+
+ // ビューの整列
+ if (m_pScaleView) {
+ m_pScaleView->MoveWindow (PIANOROLLFRAME_BORDERWIDTH,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT,
+ m_lScaleWidth, m_lScaleHeight);
+ }
+
+ if (m_pTimeScaleView) {
+ m_pTimeScaleView->MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT,
+ m_lTimeWidth, m_lScaleHeight);
+ }
+
+ if (m_pKeyScaleView) {
+ m_pKeyScaleView->MoveWindow (PIANOROLLFRAME_BORDERWIDTH,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lScaleWidth, m_lKeyHeight);
+ }
+
+ if (m_pKeyTimeView) {
+ m_pKeyTimeView->MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lTimeWidth, m_lKeyHeight);
+ }
+
+ if (m_pVelScaleView) {
+ m_pVelScaleView->MoveWindow (PIANOROLLFRAME_BORDERWIDTH,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT, m_lScaleWidth, m_lVelHeight);
+ }
+
+ if (m_pVelTimeView) {
+ m_pVelTimeView->MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT, m_lTimeWidth, m_lVelHeight);
+ }
+ // スクロールバーの整列
+ m_wndTimeScroll.MoveWindow (PIANOROLLFRAME_BORDERWIDTH,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT + m_lVelHeight,
+ m_lScaleWidth + m_lTimeWidth - m_lVScrollBarWidth * 2,
+ m_lHScrollBarHeight);
+
+ m_wndKeyScroll.MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT,
+ m_lVScrollBarWidth,
+ m_lScaleHeight + m_lKeyHeight - m_lVScrollBarWidth * 2);
+
+ m_wndVelScroll.MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT, m_lVScrollBarWidth,
+ m_lVelHeight - m_lVScrollBarWidth * 2);
+
+ m_wndSizeScroll.MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT + m_lVelHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ // ズームボタンの整列
+ m_wndTimeZoomDown.MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lTimeWidth - m_lVScrollBarWidth * 2,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT + m_lVelHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndTimeZoomUp.MoveWindow (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lTimeWidth - m_lVScrollBarWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT + m_lVelHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndKeyZoomDown.MoveWindow
+ (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT + m_lScaleHeight + m_lKeyHeight -
+ m_lVScrollBarWidth * 2,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndKeyZoomUp.MoveWindow
+ (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT + m_lScaleHeight + m_lKeyHeight -
+ m_lVScrollBarWidth,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndVelZoomDown.MoveWindow
+ (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT + m_lVelHeight - m_lVScrollBarWidth * 2,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndVelZoomUp.MoveWindow
+ (PIANOROLLFRAME_BORDERWIDTH + m_lScaleWidth + m_lTimeWidth,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT + m_lVelHeight - m_lVScrollBarWidth,
+ m_lVScrollBarWidth,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ // リストの整列
+ m_pTrackListBox->MoveWindow
+ (PIANOROLLFRAME_BORDERWIDTH * 3 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth + PIANOROLLFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT,
+ m_lTrackListWidth,
+ m_lScaleHeight + m_lKeyHeight);
+
+ m_pGraphKindListBox->MoveWindow
+ (PIANOROLLFRAME_BORDERWIDTH * 3 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth + PIANOROLLFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 3 +
+ m_lScaleHeight + m_lKeyHeight + PIANOROLLFRAME_SPLITTERHEIGHT,
+ m_lTrackListWidth,
+ m_lVelHeight + m_lHScrollBarHeight);
+
+
+ // スクロールバーのサイズが変化したので、バーのデザインを再調整する。
+ RecalcKeyScrollInfo ();
+ RecalcVelScrollInfo ();
+ RecalcTimeScrollInfo ();
+}
+
+// クライアント領域の生成(CFrameWnd::OnCreateClientのオーバーライド)
+BOOL CPianoRollFrame::OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext) {
+
+ // サイズ調整用のダミービュー生成(Visible = FALSE)
+ CWnd* pWnd = NULL;
+ m_pDummyView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_DUMMYVIEW);
+ if (m_pDummyView == NULL) {
+ return FALSE;
+ }
+ m_pDummyView->ShowWindow (SW_HIDE);
+
+ // 印刷用のビュー生成(Visible = FALSE)
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CPianoRollPrintView);
+ m_pPrintView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_PRINTVIEW);
+ if (m_pPrintView == NULL) {
+ return FALSE;
+ }
+ m_pPrintView->ShowWindow (SW_HIDE);
+
+ // ビュー1の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CPianoRollScaleView);
+ m_pScaleView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_SCALEVIEW);
+ if (m_pScaleView == NULL) {
+ return FALSE;
+ }
+ m_pScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // ビュー2の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CPianoRollTimeScaleView);
+ m_pTimeScaleView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_TIMESCALEVIEW);
+ if (m_pTimeScaleView == NULL) {
+ return FALSE;
+ }
+ m_pTimeScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // ビュー3の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CPianoRollKeyScaleView);
+ m_pKeyScaleView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_KEYSCALEVIEW);
+ if (m_pKeyScaleView == NULL) {
+ return FALSE;
+ }
+ m_pKeyScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // ビュー4の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CPianoRollKeyTimeView);
+ m_pKeyTimeView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_KEYTIMEVIEW);
+ if (m_pKeyTimeView == NULL) {
+ return FALSE;
+ }
+ m_pKeyTimeView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // ビュー5の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CPianoRollVelScaleView);
+ m_pVelScaleView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_VELSCALEVIEW);
+ if (m_pVelScaleView == NULL) {
+ return FALSE;
+ }
+ m_pVelScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // ビュー6の生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CPianoRollVelTimeView);
+ m_pVelTimeView = (CView*)CFrameWnd::CreateView (pContext, PIANOROLLFRAME_VELTIMEVIEW);
+ if (m_pVelTimeView == NULL) {
+ return FALSE;
+ }
+ m_pVelTimeView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // スクロールバーの生成
+ m_wndTimeScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_HORZ, CRect(0,0,0,0), this, PIANOROLLFRAME_TIMESCROLL);
+ m_wndKeyScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_VERT, CRect(0,0,0,0), this, PIANOROLLFRAME_KEYSCROLL);
+ m_wndVelScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_VERT, CRect(0,0,0,0), this, PIANOROLLFRAME_VELSCROLL);
+ m_wndSizeScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_SIZEBOX, CRect(0,0,0,0), this, PIANOROLLFRAME_SIZEBOX);
+
+ // ズームボタン類の生成
+ m_wndTimeZoomDown.Create
+ (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, PIANOROLLFRAME_TIMEZOOMDOWN);
+ m_wndTimeZoomUp.Create
+ (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, PIANOROLLFRAME_TIMEZOOMUP);
+ m_wndKeyZoomDown.Create
+ (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, PIANOROLLFRAME_KEYZOOMDOWN);
+ m_wndKeyZoomUp.Create
+ (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, PIANOROLLFRAME_KEYZOOMUP);
+ m_wndVelZoomDown.Create
+ (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, PIANOROLLFRAME_VELZOOMDOWN);
+ m_wndVelZoomUp.Create
+ (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, PIANOROLLFRAME_VELZOOMUP);
+
+ // トラックリストボックスの作成
+ m_pTrackListBox =
+ (CCheckListBox*)
+ (new CTrackListBox (pContext->m_pCurrentDoc, IDR_POPUPMENU13));
+ m_pTrackListBox->Create
+ (WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|
+ LBS_NOTIFY|LBS_DISABLENOSCROLL|LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOINTEGRALHEIGHT,
+ CRect(0,0,0,0), this, PIANOROLLFRAME_TRACKLIST);
+
+ // グラフの種類リストボックスの作成
+ m_pGraphKindListBox =
+ (CGraphKindListBox*)
+ (new CGraphKindListBox (pContext->m_pCurrentDoc, IDR_POPUPMENU15));
+ m_pGraphKindListBox->Create
+ (WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|
+ LBS_NOTIFY|LBS_DISABLENOSCROLL|LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOINTEGRALHEIGHT,
+ CRect(0,0,0,0), this, PIANOROLLFRAME_GRAPHKINDLIST);
+
+ // コントロールの位置合わせはWM_SIZEなどによるRecalcLaoyoutに任せる。
+ return TRUE;
+
+}
+
+// 印刷用のコマンドをトラップ(CFrameWnd::OnCmdMsgのオーバーライド)
+BOOL CPianoRollFrame::OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 印刷用のコマンドの場合、強制的にCPianoRollPrintViewに渡す。
+ if ((nID == ID_FILE_PRINT || nID == ID_FILE_PRINT_DIRECT || nID == ID_FILE_PRINT_PREVIEW) &&
+ pSekaijuApp->m_bRecording == FALSE) {
+ if (m_pPrintView) {
+ return ((CPianoRollPrintView*)m_pPrintView)->OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+ }
+ return FALSE;
+ }
+ // その他のコマンドはデフォルトの処理とする。
+ return CFrameWnd::OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CPianoRollFrame::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+
+ CRect rcTemp;
+
+ // ツールバー1の作成
+ if (!m_wndToolBar1.Create (this) ||
+ !m_wndToolBar1.LoadToolBar (IDR_PIANOROLL1)) {
+ TRACE0 ("Failed to create toolbar\n");
+ return -1;
+ }
+ m_wndToolBar1.SetBarStyle (m_wndToolBar1.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ //m_wndToolBar1.EnableDocking (CBRS_ALIGN_ANY);
+ //EnableDocking (CBRS_ALIGN_ANY);
+ //DockControlBar (&m_wndToolBar1);
+
+ LoadAccelTable (MAKEINTRESOURCE (IDR_PIANOROLL));
+
+ // トラックコンボの作成
+ m_wndToolBar1.SetButtonInfo (6, IDC_TRACKCOMBO, TBBS_SEPARATOR, 80);
+ m_wndToolBar1.GetItemRect (6, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndTrackCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_TRACKCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndTrackCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // チャンネルコンボの作成
+ m_wndToolBar1.SetButtonInfo (8, IDC_CHANNELCOMBO, TBBS_SEPARATOR, 40);
+ m_wndToolBar1.GetItemRect (8, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndChannelCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_CHANNELCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndChannelCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // スナップコンボの作成
+ m_wndToolBar1.SetButtonInfo (10, IDC_SNAPCOMBO, TBBS_SEPARATOR, 100);
+ m_wndToolBar1.GetItemRect (10, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndSnapCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_SNAPCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndSnapCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // ベロシティコンボの作成
+ m_wndToolBar1.SetButtonInfo (12, IDC_VELOCITYCOMBO, TBBS_SEPARATOR, 50);
+ m_wndToolBar1.GetItemRect (12, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndVelocityCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWN,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_VELOCITYCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndVelocityCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+
+ // スピンの作成(テスト)
+ //m_wndVelocitySpin.Create (
+ // WS_VISIBLE | WS_TABSTOP | WS_CHILD | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_AUTOBUDDY | UDS_ALIGNRIGHT,
+ // rcTemp, &m_wndToolBar1, IDC_VELOCITYSPIN);
+
+ // 長さコンボの作成
+ m_wndToolBar1.SetButtonInfo (14, IDC_DURATIONCOMBO, TBBS_SEPARATOR, 50);
+ m_wndToolBar1.GetItemRect (14, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndDurationCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWN,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_DURATIONCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndDurationCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // グラフの種類コンボの作成
+ m_wndToolBar1.SetButtonInfo (16, IDC_GRAPHKINDCOMBO, TBBS_SEPARATOR, 120);
+ m_wndToolBar1.GetItemRect (16, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndGraphKindCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_GRAPHKINDCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndGraphKindCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // グラフのスナップコンボの作成
+ m_wndToolBar1.SetButtonInfo (18, IDC_GRAPHSNAPCOMBO, TBBS_SEPARATOR, 100);
+ m_wndToolBar1.GetItemRect (18, &rcTemp);
+ rcTemp.top = 2;
+ rcTemp.bottom = 120;
+ if (!m_wndGraphSnapCombo.CreateEx (
+ WS_EX_CLIENTEDGE, _T("COMBOBOX"), NULL,
+ WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_VSCROLL | CBS_DROPDOWNLIST,
+ rcTemp.left, rcTemp.top, rcTemp.Width (), rcTemp.Height (),
+ m_wndToolBar1.GetSafeHwnd (), (HMENU)IDC_GRAPHSNAPCOMBO)) {
+ TRACE0 ("Failed to create edit box\n");
+ return -1;
+ }
+ m_wndGraphSnapCombo.SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+
+ // 親クラスの関数呼び出し
+ int nRet = CChildFrame::OnCreate (lpCreateStruct);
+
+ // スクロールポジションの位置あわせ
+ SetKeyScrollPos (64 * m_lKeyZoom - m_lKeyHeight / 2);
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+
+ // トラックコンボボックスの充満
+ UpdateTrackCombo ();
+
+ // チャンネルコンボの充満
+ int i;
+ CString strText;
+ for (i = 0; i < 16; i++) {
+ strText.Format (_T("%d"), i + 1);
+ m_wndChannelCombo.AddString (strText);
+ }
+ m_wndChannelCombo.SetCurSel (0);
+
+ // カレントチャンネルの自動選択
+ if (pSekaijuDoc->m_pTempTrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+
+ // スナップコンボの充満
+ UpdateSnapCombo ();
+ m_wndSnapCombo.SetCurSel (3);
+
+ // ベロシティコンボの充満
+ UpdateVelocityCombo ();
+ m_wndVelocityCombo.SetCurSel (6);
+
+ // 長さコンボの充満
+ UpdateDurationCombo ();
+ m_wndDurationCombo.SetCurSel (3);
+
+ // グラフスナップコンボの充満
+ UpdateGraphSnapCombo ();
+ m_wndGraphSnapCombo.SetCurSel (7);
+
+ // トラックリストの充満
+ UpdateTrackList ();
+ m_pTrackListBox->SetCurSel (0);
+ m_pTrackListBox->SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+ long lCount = m_pTrackListBox->GetCount ();
+ i = 0;
+ if (pSekaijuDoc->m_pTempTrack) {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (0 <= i && i < lCount) {
+ m_pTrackListBox->SetCheck (i, pMIDITrack == pSekaijuDoc->m_pTempTrack ? TRUE : FALSE);
+ m_bTrackVisible[i] = (pMIDITrack == pSekaijuDoc->m_pTempTrack ? TRUE : FALSE);
+ }
+ i++;
+ }
+ }
+ else {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (0 <= i && i < lCount) {
+ m_pTrackListBox->SetCheck (i, TRUE);
+ m_bTrackVisible[i] = (TRUE);
+ }
+ i++;
+ }
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+
+ // カレントトラックとカレントチャンネルを更新
+ long lTrackIndex = 0;
+ if (pSekaijuDoc->m_pTempTrack) {
+ lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ }
+ else if (MIDIData_GetFormat (pMIDIData) == 1 && lCount >= 2) {
+ lTrackIndex = 1;
+ }
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ }
+
+
+ // グラフの種類コンボの充満(先にトラックリストを完成させGetCurTrackIndexを効かせること)
+ UpdateGraphKindCombo ();
+ m_wndGraphKindCombo.SetCurSel (1);
+
+ // グラフの種類リストの充満
+ UpdateGraphKindList ();
+ m_pGraphKindListBox->SetCurSel (1);
+ m_pGraphKindListBox->SetFont (CFont::FromHandle ((HFONT)::GetStockObject (DEFAULT_GUI_FONT)));
+ lCount = m_pGraphKindListBox->GetCount ();
+ for (i = 0; i < lCount; i++) {
+ m_pGraphKindListBox->SetCheck (i, IsGraphVisible (i) ? 1 : 0);
+ }
+
+ // 自動ページ更新の設定
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) {
+ m_bAutoPageUpdate = TRUE;
+ }
+
+
+ SetActiveView (m_pKeyTimeView, FALSE);
+ m_pKeyTimeView->SetFocus ();
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return nRet;
+}
+
+// ウィンドウ破棄時
+void CPianoRollFrame::OnDestroy () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_pTrackListBox->DestroyWindow ();
+ delete m_pTrackListBox;
+ m_pGraphKindListBox->DestroyWindow ();
+ delete m_pGraphKindListBox;
+ CChildFrame::OnDestroy ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// ウィンドウサイズ変更時
+void CPianoRollFrame::OnSize (UINT nType, int cx, int cy) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ // 基本クラスの関数呼び出し
+ CChildFrame::OnSize (nType, cx, cy);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// タイマー呼び出し時
+void CPianoRollFrame::OnTimer (UINT nIDEvent) {
+ //if (nIDEvent == 0x11) {
+ // m_pKeyTimeView->SendMessage (WM_TIMER, 11, NULL);
+ // m_pVelTimeView->SendMessage (WM_TIMER, 11, NULL);
+ //}
+}
+
+// 背景消去(CFrameWnd::OnEraseBkgndのオーバーライド)
+BOOL CPianoRollFrame::OnEraseBkgnd (CDC* pDC) {
+ return 0;
+}
+
+// ウィンドウがアクティブになったとき
+void CPianoRollFrame::OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd) {
+ CChildFrame::OnMDIActivate (bActivate, pActivateWnd, pDeactivateWnd);
+}
+
+// 描画するとき
+void CPianoRollFrame::OnPaint () {
+ CPaintDC dc (this);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ // 左上側領域のくぼみ描画
+ CRect rcClient1 (rcClient);
+ rcClient1.top = m_lToolBar1Height;
+ rcClient1.bottom = m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 2 +
+ m_lScaleHeight + m_lKeyHeight;
+ rcClient1.right = PIANOROLLFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth;
+ dc.Draw3dRect (&rcClient1, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient1.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient1, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 左下側領域のくぼみ描画
+ CRect rcClient2 (rcClient);
+ rcClient2.top = m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 2 +
+ m_lScaleHeight + m_lKeyHeight + PIANOROLLFRAME_SPLITTERHEIGHT;
+ rcClient2.right = PIANOROLLFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth;
+ dc.Draw3dRect (&rcClient2, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient2.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient2, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 右上側領域のくぼみ描画
+ CRect rcClient3 (rcClient);
+ rcClient3.top = m_lToolBar1Height;
+ rcClient3.bottom = m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 2 +
+ m_lScaleHeight + m_lKeyHeight;
+ rcClient3.left = PIANOROLLFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth + PIANOROLLFRAME_SPLITTERWIDTH;
+ dc.Draw3dRect (&rcClient3, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient3.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient3, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 右下側領域のくぼみ描画
+ CRect rcClient4 (rcClient);
+ rcClient4.top = m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 2 +
+ m_lScaleHeight + m_lKeyHeight + PIANOROLLFRAME_SPLITTERHEIGHT;
+ rcClient4.left = PIANOROLLFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth +
+ m_lVScrollBarWidth + PIANOROLLFRAME_SPLITTERWIDTH;
+ dc.Draw3dRect (&rcClient4, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient4.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient4, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 横境界部分の描画
+ CBrush brush;
+ brush.CreateSolidBrush (::GetSysColor (COLOR_3DFACE));
+ CRect rcClient5 (rcClient);
+ rcClient5.top = rcClient1.bottom + 1;
+ rcClient5.bottom = rcClient2.top - 1;
+ dc.FillRect (&rcClient5, &brush);
+ // 縦境界部分の描画
+ CRect rcClient6 (rcClient);
+ rcClient6.left = rcClient1.right + 1;
+ rcClient6.right = rcClient3.left - 1;
+ dc.FillRect (&rcClient6, &brush);
+}
+
+// キーが押された時
+void CPianoRollFrame::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CWnd* pOldFocus = GetFocus ();
+ switch (nChar) {
+ // D(描画)P(ペン)
+ case 'D':
+ case 'P':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_PIANOROLL_PEN, 0);
+ }
+ break;
+ // L(線)
+ case 'L':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_PIANOROLL_LINE, 0);
+ }
+ break;
+ // E(消しゴム)
+ case 'E':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_PIANOROLL_ERASER, 0);
+ }
+ break;
+ // S(選択)
+ case 'S':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_PIANOROLL_SELECT, 0);
+ }
+ break;
+ // B(スクラブ)
+ case 'B':
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_COMMAND, ID_PIANOROLL_SPEAKER, 0);
+ }
+ break;
+ // ↑
+ case VK_UP:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pKeyScaleView || GetFocus () == m_pKeyTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndKeyScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ else if (GetFocus () == m_pVelScaleView || GetFocus () == m_pVelTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndVelScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ }
+ break;
+ // ↓
+ case VK_DOWN:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pKeyScaleView || GetFocus () == m_pKeyTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndKeyScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ else if (GetFocus () == m_pVelScaleView || GetFocus () == m_pVelTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndVelScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ }
+ break;
+ // PageUp
+ case VK_PRIOR:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pKeyScaleView || GetFocus () == m_pKeyTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndKeyScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ else if (GetFocus () == m_pVelScaleView || GetFocus () == m_pVelTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndVelScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ }
+ break;
+ // PageDown
+ case VK_NEXT:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pKeyScaleView || GetFocus () == m_pKeyTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndKeyScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ else if (GetFocus () == m_pVelScaleView || GetFocus () == m_pVelTimeView) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndVelScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ }
+ break;
+ // ←
+ case VK_LEFT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ break;
+ // →
+ case VK_RIGHT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ break;
+ // Home
+ case VK_HOME:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ break;
+ // End
+ case VK_END:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)pOldFocus->GetSafeHwnd ());
+ }
+ break;
+ // '-'(ズームダウン)
+ case 189:
+ case VK_SUBTRACT:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_thePianoRollOption.m_bEnableKeyZoomKey) {
+ this->PostMessage (WM_COMMAND, PIANOROLLFRAME_KEYZOOMDOWN, 0);
+ }
+ if (pSekaijuApp->m_thePianoRollOption.m_bEnableVelZoomKey) {
+ this->PostMessage (WM_COMMAND, PIANOROLLFRAME_VELZOOMDOWN, 0);
+ }
+ if (pSekaijuApp->m_thePianoRollOption.m_bEnableTimeZoomKey) {
+ this->PostMessage (WM_COMMAND, PIANOROLLFRAME_TIMEZOOMDOWN, 0);
+ }
+ }
+ break;
+
+ // '+'(ズームアップ)
+ case 187:
+ case VK_ADD:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_thePianoRollOption.m_bEnableKeyZoomKey) {
+ this->PostMessage (WM_COMMAND, PIANOROLLFRAME_KEYZOOMUP, 0);
+ }
+ if (pSekaijuApp->m_thePianoRollOption.m_bEnableVelZoomKey) {
+ this->PostMessage (WM_COMMAND, PIANOROLLFRAME_VELZOOMUP, 0);
+ }
+ if (pSekaijuApp->m_thePianoRollOption.m_bEnableTimeZoomKey) {
+ this->PostMessage (WM_COMMAND, PIANOROLLFRAME_TIMEZOOMUP, 0);
+ }
+ }
+ break;
+ }
+ return;
+}
+
+
+
+// マウス左ボタン押された時
+void CPianoRollFrame::OnLButtonDown (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 上半分(ピアノロール)と下半分(コントローラー)の境界線上をドラッグすると、境界線が上下に移動
+ if (m_bSplitterMovingH || m_bSplitterMovingV) {
+ SetCapture ();
+ m_ptMouseDown = m_ptMouseMoveOld = point;
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ if (m_bSplitterMovingH && m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeAll);
+ }
+ else if (m_bSplitterMovingH) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeNS);
+ }
+ else if (m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+ }
+}
+
+// マウス右ボタン押された時
+void CPianoRollFrame::OnRButtonDown (UINT nFlags, CPoint point) {
+}
+
+// マウス左ボタン離されたとき
+void CPianoRollFrame::OnLButtonUp (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (GetCapture () == this) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ ReleaseDC (pDC);
+ ReleaseCapture ();
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ CPoint ptDelta = point - m_ptMouseDown;
+ if (m_bSplitterMovingH) {
+ m_lVelHeight = CLIP (0, (m_lVelHeight - ptDelta.y),
+ PIANOROLLFRAME_VELHEIGHT * m_lVelZoom + 16);
+ }
+ if (m_bSplitterMovingV) {
+ m_lTrackListWidth = CLIP (0,
+ (m_lTrackListWidth - ptDelta.x), 1600);
+ }
+ m_bSplitterMovingH = FALSE;
+ m_bSplitterMovingV = FALSE;
+ RecalcLayout ();
+ Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+}
+
+// マウス右ボタン離されたとき
+void CPianoRollFrame::OnRButtonUp (UINT nFlags, CPoint point) {
+
+
+}
+
+// マウスが動かされたとき
+void CPianoRollFrame::OnMouseMove (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // キャプター中
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ m_ptMouseMoveOld = point;
+ }
+ // 非キャプター中
+ else {
+ // カーソルが水平スプリッター上にあるか
+ m_bSplitterMovingH =
+ m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 2 + m_lScaleHeight + m_lKeyHeight <= point.y &&
+ point.y < m_lToolBar1Height + PIANOROLLFRAME_BORDERHEIGHT * 2 + m_lScaleHeight + m_lKeyHeight +
+ PIANOROLLFRAME_SPLITTERHEIGHT;
+ // カーソルが垂直スプリッター上にあるか
+ m_bSplitterMovingV =
+ PIANOROLLFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth + m_lVScrollBarWidth <= point.x &&
+ point.x < PIANOROLLFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lTimeWidth + m_lVScrollBarWidth +
+ PIANOROLLFRAME_SPLITTERWIDTH;
+ // カーソルが水平スプリッターと垂直スプリッターの交差部にある場合
+ if (m_bSplitterMovingH && m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeAll);
+ }
+ // カーソルが水平スプリッター上にある場合
+ else if (m_bSplitterMovingH) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeNS);
+ }
+ // カーソルが垂直スプリッター上にある場合
+ else if (m_bSplitterMovingV) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+ // カーソルがスプリッターにない場合
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ }
+ }
+}
+
+// 時間方向ズームダウン(20091220:左端位置保持機能追加、自動ページ更新自動オフ追加)
+void CPianoRollFrame::OnTimeZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTimeZoom = m_lTimeZoom;
+ long lOldTimePos = m_wndTimeScroll.GetScrollPos ();
+ long lNewTimeZoom = CLIP (1, m_lTimeZoom - 1, 16);
+ long lNewTimePos = lOldTimePos * lNewTimeZoom / lOldTimeZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lTimeZoom = lNewTimeZoom;
+ RecalcTimeScrollInfo ();
+ m_wndTimeScroll.SetScrollPos (lNewTimePos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ m_pTimeScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ //m_bAutoPageUpdate = TRUE;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 時間方向ズームアップ(20091220:左端位置保持機能追加、自動ページ更新自動オフ追加)
+void CPianoRollFrame::OnTimeZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTimeZoom = m_lTimeZoom;
+ long lOldTimePos = m_wndTimeScroll.GetScrollPos ();
+ long lNewTimeZoom = CLIP (1, m_lTimeZoom + 1, 16);
+ long lNewTimePos = lOldTimePos * lNewTimeZoom / lOldTimeZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lTimeZoom = lNewTimeZoom;
+ RecalcTimeScrollInfo ();
+ m_wndTimeScroll.SetScrollPos (lNewTimePos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ m_pTimeScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ //m_bAutoPageUpdate = TRUE;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// キー方向ズームダウン(20091220:上端位置保持機能追加)
+void CPianoRollFrame::OnKeyZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldKeyZoom = m_lKeyZoom;
+ long lOldKeyPos = m_wndKeyScroll.GetScrollPos ();
+ long lNewKeyZoom = CLIP (4, m_lKeyZoom - 1, 16);
+ long lNewKeyPos = lOldKeyPos * lNewKeyZoom / lOldKeyZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lKeyZoom = lNewKeyZoom;
+ RecalcKeyScrollInfo ();
+ m_wndKeyScroll.SetScrollPos (lNewKeyPos);
+ m_lKeyScrollPos = m_wndKeyScroll.GetScrollPos ();
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// キー方向ズームアップ(20091220:上端位置保持機能追加)
+void CPianoRollFrame::OnKeyZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldKeyZoom = m_lKeyZoom;
+ long lOldKeyPos = m_wndKeyScroll.GetScrollPos ();
+ long lNewKeyZoom = CLIP (4, m_lKeyZoom + 1, 16);
+ long lNewKeyPos = lOldKeyPos * lNewKeyZoom / lOldKeyZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lKeyZoom = lNewKeyZoom;
+ RecalcKeyScrollInfo ();
+ m_wndKeyScroll.SetScrollPos (lNewKeyPos);
+ m_lKeyScrollPos = m_wndKeyScroll.GetScrollPos ();
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// ベロシティ方向ズームダウン(20091220:上端位置保持機能追加)
+void CPianoRollFrame::OnVelZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldVelZoom = m_lVelZoom;
+ long lOldVelPos = m_wndVelScroll.GetScrollPos ();
+ long lNewVelZoom = CLIP (1, m_lVelZoom - 1, 4);
+ long lNewVelPos = lOldVelPos * lNewVelZoom / lOldVelZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lVelZoom = lNewVelZoom;
+ m_lVelHeight = MIN (m_lVelHeight, 128 * m_lVelZoom);
+ RecalcLayout (FALSE);
+ m_wndVelScroll.SetScrollPos (lNewVelPos);
+ m_lVelScrollPos = m_wndVelScroll.GetScrollPos ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ this->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// ベロシティ方向ズームアップ(20091220:上端位置保持機能追加)
+void CPianoRollFrame::OnVelZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldVelZoom = m_lVelZoom;
+ long lOldVelPos = m_wndVelScroll.GetScrollPos ();
+ long lNewVelZoom = CLIP (1, m_lVelZoom + 1, 4);
+ long lNewVelPos = lOldVelPos * lNewVelZoom / lOldVelZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lVelZoom = lNewVelZoom;
+ m_lVelHeight = MIN (m_lVelHeight, 128 * m_lVelZoom);
+ RecalcLayout (FALSE);
+ m_wndVelScroll.SetScrollPos (lNewVelPos);
+ m_lVelScrollPos = m_wndVelScroll.GetScrollPos ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ this->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 水平スクロール
+void CPianoRollFrame::OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndTimeScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lTimeScrollPos;
+ switch (nSBCode) {
+ case SB_LINELEFT:
+ lNewPos = m_lTimeScrollPos - m_lTimeZoom;
+ break;
+ case SB_LINERIGHT:
+ lNewPos = m_lTimeScrollPos + m_lTimeZoom;
+ break;
+ case SB_PAGELEFT:
+ lNewPos = m_lTimeScrollPos - m_lTimeZoom * 4;
+ break;
+ case SB_PAGERIGHT:
+ lNewPos = m_lTimeScrollPos + m_lTimeZoom * 4;
+ break;
+ case SB_LEFT: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_RIGHT: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetTimeScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_bAutoPageUpdate = FALSE;
+ m_pKeyTimeView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 垂直スクロール
+void CPianoRollFrame::OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndKeyScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lKeyScrollPos;
+ switch (nSBCode) {
+ case SB_LINEUP:
+ lNewPos = m_lKeyScrollPos - m_lKeyZoom;
+ break;
+ case SB_LINEDOWN:
+ lNewPos = m_lKeyScrollPos + m_lKeyZoom;
+ break;
+ case SB_PAGEUP:
+ lNewPos = m_lKeyScrollPos - m_lKeyZoom * 12;
+ break;
+ case SB_PAGEDOWN:
+ lNewPos = m_lKeyScrollPos + m_lKeyZoom * 12;
+ break;
+ case SB_TOP: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_BOTTOM: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetKeyScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_pKeyTimeView->SetFocus ();
+ }
+ else if (pScrollBar == &m_wndVelScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lVelScrollPos;
+ switch (nSBCode) {
+ case SB_LINEUP:
+ lNewPos = m_lVelScrollPos - m_lVelZoom * 2;
+ break;
+ case SB_LINEDOWN:
+ lNewPos = m_lVelScrollPos + m_lVelZoom * 2;
+ break;
+ case SB_PAGEUP:
+ lNewPos = m_lVelScrollPos - m_lVelZoom * 20;
+ break;
+ case SB_PAGEDOWN:
+ lNewPos = m_lVelScrollPos + m_lVelZoom * 20;
+ break;
+ case SB_TOP: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_BOTTOM: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetVelScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_pVelTimeView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 『ツール(&T)』-『ペン(&P)』
+void CPianoRollFrame::OnPianoRollPen () {
+ m_lCurTool = ID_PIANOROLL_PEN;
+}
+
+// 『ツール(&T)』-『ペン(&P)』
+void CPianoRollFrame::OnUpdatePianoRollPenUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_PIANOROLL_PEN);
+}
+
+// 『ツール(&T)』-『線(&L)』
+void CPianoRollFrame::OnPianoRollLine () {
+ m_lCurTool = ID_PIANOROLL_LINE;
+}
+
+// 『ツール(&T)』-『線(&L)』
+void CPianoRollFrame::OnUpdatePianoRollLineUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_PIANOROLL_LINE);
+}
+
+// 『ツール(&T)』-『消しゴム(&E)』
+void CPianoRollFrame::OnPianoRollEraser () {
+ m_lCurTool = ID_PIANOROLL_ERASER;
+}
+
+// 『ツール(&T)』-『消しゴム(&E)』
+void CPianoRollFrame::OnUpdatePianoRollEraserUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_PIANOROLL_ERASER);
+}
+
+// 『ツール(&T)』-『選択(&S)』
+void CPianoRollFrame::OnPianoRollSelect () {
+ m_lCurTool = ID_PIANOROLL_SELECT;
+}
+
+// 『ツール(&T)』-『選択(&S)』
+void CPianoRollFrame::OnUpdatePianoRollSelectUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_PIANOROLL_SELECT);
+}
+
+// 『ツール(&T)』-『スピーカ(&P)』
+void CPianoRollFrame::OnPianoRollSpeaker () {
+ m_lCurTool = ID_PIANOROLL_SPEAKER;
+}
+
+// 『ツール(&T)』-『スピーカ(&P)』
+void CPianoRollFrame::OnUpdatePianoRollSpeakerUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_PIANOROLL_SPEAKER);
+}
+
+// 『ツール(&T)』-『現在のトラックのみ表示(&C)』
+void CPianoRollFrame::OnPianoRollOnlyCurTrack () {
+ long lTrackCount = m_pTrackListBox->GetCount ();
+ long lTrackCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bOnlyCurTrack) {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ }
+ else {
+ m_bOnlyCurTrack = TRUE;
+ m_bShowAllTrack = FALSE;
+ }
+ for (long i = 0; i < lTrackCount; i++) {
+ m_pTrackListBox->SetCheck (i, IsTrackVisible (i) ? 1 : 0);
+ }
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ツール(&T)』-『現在のトラックのみ表示(&C)』
+void CPianoRollFrame::OnUpdatePianoRollOnlyCurTrackUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bOnlyCurTrack);
+}
+
+// 『ツール(&T)』-『全てのトラックを表示(&A)』
+void CPianoRollFrame::OnPianoRollShowAllTrack () {
+ long lTrackCount = m_pTrackListBox->GetCount ();
+ long lTrackCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bShowAllTrack) {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ }
+ else {
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = TRUE;
+ }
+ for (long i = 0; i < lTrackCount; i++) {
+ m_pTrackListBox->SetCheck (i, IsTrackVisible (i) ? 1 : 0);
+ }
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ツール(&T)』-『全てのトラックを表示(&A)』
+void CPianoRollFrame::OnUpdatePianoRollShowAllTrackUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bShowAllTrack);
+}
+
+// 『ツール(&T)』-『現在のグラフのみ表示(&C)』
+void CPianoRollFrame::OnPianoRollOnlyCurGraph () {
+ long lGraphKindCount = m_pGraphKindListBox->GetCount ();
+ long lGraphKindCurSel = m_pGraphKindListBox->GetCurSel ();
+ if (m_bOnlyCurGraph) {
+ m_bOnlyCurGraph = FALSE;
+ m_bShowAllGraph = FALSE;
+ }
+ else {
+ m_bOnlyCurGraph = TRUE;
+ m_bShowAllGraph = FALSE;
+ }
+ for (long i = 0; i < lGraphKindCount; i++) {
+ m_pGraphKindListBox->SetCheck (i, IsGraphVisible (i) ? 1 : 0);
+ }
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+}
+
+// 『ツール(&T)』-『現在のグラフのみ表示(&C)』
+void CPianoRollFrame::OnUpdatePianoRollOnlyCurGraphUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bOnlyCurGraph);
+}
+
+
+// 『ツール(&T)』-『全てのグラフを表示(&A)』
+void CPianoRollFrame::OnPianoRollShowAllGraph () {
+ long lGraphKindCount = m_pGraphKindListBox->GetCount ();
+ long lGraphKindCurSel = m_pGraphKindListBox->GetCurSel ();
+ if (m_bShowAllGraph) {
+ m_bOnlyCurGraph = FALSE;
+ m_bShowAllGraph = FALSE;
+ }
+ else {
+ m_bOnlyCurGraph = FALSE;
+ m_bShowAllGraph = TRUE;
+ }
+ for (long i = 0; i < lGraphKindCount; i++) {
+ m_pGraphKindListBox->SetCheck (i, IsGraphVisible (i) ? 1 : 0);
+ }
+ m_pKeyTimeView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+}
+
+// 『ツール(&T)』-『全てのグラフを表示(&A)』
+void CPianoRollFrame::OnUpdatePianoRollShowAllGraphUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bShowAllGraph);
+}
+
+// 『ツール(&T)』-『自動ページ更新』
+void CPianoRollFrame::OnPianoRollAutoPageUpdate () {
+ m_bAutoPageUpdate = !m_bAutoPageUpdate;
+}
+
+// 『ツール(&T)』-『自動ページ更新』
+void CPianoRollFrame::OnUpdatePianoRollAutoPageUpdateUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bAutoPageUpdate);
+}
+
+// トラックコンボが選択され終わった時
+void CPianoRollFrame::OnTrackComboSelEndOK () {
+ // カレントトラックを更新する
+ long lCurTrackIndex = m_wndTrackCombo.GetCurSel ();
+ SetCurTrackIndex (lCurTrackIndex);
+ SetTrackVisible (lCurTrackIndex);
+ // カレントチャンネルも更新する
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// トラックリストのチェックボックスが変化したとき
+void CPianoRollFrame::OnTrackListChkChange () {
+ // トラックの表示/非表示をチェックボックスの状態に合わせる
+ long lCount = m_pTrackListBox->GetCount ();
+ long lCurSel = m_pTrackListBox->GetCurSel ();
+ if (m_bOnlyCurTrack) {
+ m_bOnlyCurTrack = FALSE;
+ }
+ for (long i = 0; i < lCount; i++) {
+ m_bTrackVisible[i] = m_pTrackListBox->GetCheck (i);
+ if (m_bTrackVisible[i] == FALSE) { // TODO
+ m_bShowAllTrack = FALSE;
+ }
+ }
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// トラックリストの選択項目が変化したとき
+void CPianoRollFrame::OnTrackListSelChange () {
+ // カレントトラックを変更する
+ long lCurTrackIndex = m_pTrackListBox->GetCurSel ();
+ SetCurTrackIndex (lCurTrackIndex);
+ // カレントチャンネルも更新する
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// グラフの種類コンボが選択され終わった時
+void CPianoRollFrame::OnGraphKindComboSelEndOK () {
+ long lCurGraphKind = m_wndGraphKindCombo.GetCurSel ();
+ SetCurGraphKind (lCurGraphKind);
+ SetGraphVisible (lCurGraphKind);
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// グラフの種類リストのチェックボックスが変化したとき
+void CPianoRollFrame::OnGraphKindListChkChange () {
+ // グラフの表示/非表示をチェックボックスの状態に合わせる
+ long lCount = m_pGraphKindListBox->GetCount ();
+ long lCurSel = m_pGraphKindListBox->GetCurSel ();
+ if (m_bOnlyCurGraph) {
+ m_bOnlyCurGraph = FALSE;
+ }
+ else {
+ for (long i = 0; i < lCount; i++) {
+ m_bGraphVisible[i] = m_pGraphKindListBox->GetCheck (i);
+ if (m_bGraphVisible[i] == FALSE) {
+ m_bShowAllGraph = FALSE;
+ }
+ }
+ }
+ //m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// グラフの種類リストの選択項目が変化したとき
+void CPianoRollFrame::OnGraphKindListSelChange () {
+ // カレントグラフを変更する。
+ long lCurGraphKind = m_pGraphKindListBox->GetCurSel ();
+ SetCurGraphKind (lCurGraphKind);
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『このトラックのみ表示ON』
+void CPianoRollFrame::OnPopupTrackVisibleOn () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ return;
+ }
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lCount = m_pTrackListBox->GetCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, i == lTrackIndex ? 1 : 0);
+ m_bTrackVisible[i] = (i == lTrackIndex ? TRUE : FALSE);
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // カレントトラックとカレントチャンネルを更新
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『このトラックのみ表示ON』
+void CPianoRollFrame::OnUpdatePopupTrackVisibleOnUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+
+// 『ポップアップ』-『このトラックのみ表示OFF』
+void CPianoRollFrame::OnPopupTrackVisibleOff () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ return;
+ }
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lCount = m_pTrackListBox->GetCount ();
+ ASSERT (0 <= lTrackIndex && lTrackIndex < lCount);
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, i == lTrackIndex ? 0 : 1);
+ m_bTrackVisible[i] = (i == lTrackIndex ? FALSE : TRUE);
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // カレントトラックとカレントチャンネルを更新
+ if (m_bTrackVisible[lTrackIndex]) {
+ SetCurTrackIndex (lTrackIndex);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pSekaijuDoc->m_pTempTrack);
+ if (0 <= lOutputChannel && lOutputChannel <= 15) {
+ SetCurChannel (lOutputChannel);
+ }
+ }
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『このトラックのみ表示OFF』
+void CPianoRollFrame::OnUpdatePopupTrackVisibleOffUI (CCmdUI* pCmdUI) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『全トラック表示ON』
+void CPianoRollFrame::OnPopupTrackVisibleAll () {
+ long lCount = m_pTrackListBox->GetCount ();
+ long i = 0;
+ for (i = 0; i < lCount; i++) {
+ m_pTrackListBox->SetCheck (i, 1);
+ m_bTrackVisible[i] = TRUE;
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『全トラック表示ON』
+void CPianoRollFrame::OnUpdatePopupTrackVisibleAllUI (CCmdUI* pCmdUI) {
+}
+
+// 『ポップアップ』-『このイベントのプロパティ(&R)』
+void CPianoRollFrame::OnPopupEventProperty () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ if (pSekaijuDoc->m_pTempEvent == NULL || pSekaijuDoc->m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsNote (pSekaijuDoc->m_pTempEvent)) {
+ return;
+ }
+ MIDIEvent* pNoteOffEvent = pSekaijuDoc->m_pTempEvent->m_pNextCombinedEvent;
+ if (pNoteOffEvent == NULL) {
+ return;
+ }
+ long lTrackIndex = pSekaijuDoc->GetTrackIndex (pSekaijuDoc->m_pTempTrack);
+ long lTime = MIDIEvent_GetTime (pSekaijuDoc->m_pTempEvent);
+ CString strTime;
+ pSekaijuDoc->LongTimeToStringTime (pSekaijuDoc->m_pMIDIData, lTime, &strTime);
+ CPropertyNoteDlg theDlg;
+ theDlg.m_bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ theDlg.m_bNoteOnNoteOn0 = (MIDIEvent_GetKind (pNoteOffEvent) & 0xF0) == 0x80 ? FALSE : TRUE;
+ MIDITrack* pMIDITrack;
+ forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) {
+ TCHAR szTrackName[256];
+ memset (szTrackName, 0, sizeof (szTrackName));
+ MIDITrack_GetName (pMIDITrack, szTrackName, TSIZEOF (szTrackName));
+ theDlg.m_theTrackNameArray.Add (szTrackName);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ theDlg.m_theTrackOutputChannelArray.Add ((DWORD)lTrackOutputChannel);
+ }
+ long lKey = 0;
+ for (lKey = 0; lKey < 128; lKey++) {
+ CString strKeyName;
+ strKeyName = pSekaijuDoc->GetKeyName (pSekaijuDoc->m_pTempTrack, lTime, lKey);
+ theDlg.m_theKeyNameArray.Add (strKeyName);
+ }
+ theDlg.m_nTrackIndex = (int)lTrackIndex;
+ theDlg.m_strTime = strTime;
+ theDlg.m_nChannel = (int)MIDIEvent_GetChannel (pSekaijuDoc->m_pTempEvent) + 1;
+ theDlg.m_nKey = (int)MIDIEvent_GetKey (pSekaijuDoc->m_pTempEvent);
+ theDlg.m_nOnVelocity = (int)MIDIEvent_GetVelocity (pSekaijuDoc->m_pTempEvent);
+ theDlg.m_nOffVelocity = (int)MIDIEvent_GetVelocity (pNoteOffEvent);
+ theDlg.m_nDuration = (int)MIDIEvent_GetDuration (pSekaijuDoc->m_pTempEvent);
+ if (theDlg.DoModal () == IDOK) {
+ // トラック抽出
+ long lTrackIndex = (long)theDlg.m_nTrackIndex;
+ if (MIDIData_GetFormat (pSekaijuDoc->m_pMIDIData) == 1 && lTrackIndex == 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ MIDITrack* pNewTrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ if (pNewTrack == NULL) {
+ CString strMsg;
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // タイム文字列をlong型に変換
+ long lTime = MIDIEvent_GetTime (pSekaijuDoc->m_pTempEvent);
+ long lErrorID = pSekaijuDoc->StringTimeToLongTime (pSekaijuDoc->m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ BeginWaitCursor ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_NOTE));
+ pSekaijuDoc->AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 所属トラックが変更されない場合
+ if (pNewTrack == pSekaijuDoc->m_pTempTrack) {
+ // EOTの履歴保持(20110109修正)
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pSekaijuDoc->m_pTempEvent);
+ VERIFY (pNewEvent = pSekaijuDoc->ReplaceMIDIEvent (pSekaijuDoc->m_pTempEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetChannel (pNewEvent, theDlg.m_nChannel - 1);
+ MIDIEvent_SetKey (pNewEvent, theDlg.m_nKey);
+ MIDIEvent_SetVelocity (pNewEvent, theDlg.m_nOnVelocity);
+ MIDIEvent_SetDuration (pNewEvent, theDlg.m_nDuration);
+ if (!theDlg.m_bNoteOnNoteOn0) {
+ MIDIEvent* pNewNoteOffEvent = pNewEvent->m_pNextCombinedEvent;
+ MIDIEvent_SetVelocity (pNewNoteOffEvent, theDlg.m_nOffVelocity);
+ }
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ // EOTの履歴保持(20110109修正)
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+ // 所属トラックが変更される場合
+ else {
+ // イベントの置換と除去
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pSekaijuDoc->m_pTempEvent);
+ VERIFY (pNewEvent = pSekaijuDoc->ReplaceMIDIEvent (pSekaijuDoc->m_pTempEvent));
+ VERIFY (MIDITrack_RemoveEvent (pSekaijuDoc->m_pTempTrack, pNewEvent));
+ // EOTの履歴保持(20110109修正)
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ // イベントの挿入と変更
+ VERIFY (MIDITrack_InsertEvent (pNewTrack, pNewEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetChannel (pNewEvent, theDlg.m_nChannel - 1);
+ MIDIEvent_SetKey (pNewEvent, theDlg.m_nKey);
+ MIDIEvent_SetVelocity (pNewEvent, theDlg.m_nOnVelocity);
+ MIDIEvent_SetDuration (pNewEvent, theDlg.m_nDuration);
+ if (!theDlg.m_bNoteOnNoteOn0) {
+ MIDIEvent* pNewNoteOffEvent = pNewEvent->m_pNextCombinedEvent;
+ MIDIEvent_SetVelocity (pNewNoteOffEvent, theDlg.m_nOffVelocity);
+ }
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ // EOTの履歴保持(20110109修正)
+ pLastEvent = MIDITrack_GetLastEvent (pNewTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ SetTrackVisible (theDlg.m_nTrackIndex);
+ SetCurTrackIndex (theDlg.m_nTrackIndex);
+ SetCurChannel (theDlg.m_nChannel - 1);
+ SetCurVelocity (theDlg.m_nOnVelocity);
+ SetCurDuration (theDlg.m_nDuration);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『このイベントのプロパティ(&R)』
+void CPianoRollFrame::OnUpdatePopupEventPropertyUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (pSekaijuDoc->m_pTempEvent == NULL || pSekaijuDoc->m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsNote (pSekaijuDoc->m_pTempEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ MIDIEvent* pNoteOffEvent = pSekaijuDoc->m_pTempEvent->m_pNextCombinedEvent;
+ if (pNoteOffEvent == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+
+// 『ポップアップ』-『このグラフの種類のみ表示ON』
+void CPianoRollFrame::OnPopupGraphKindVisibleOn () {
+ long i;
+ long lGraphIndex = ((CGraphKindListBox*)m_pGraphKindListBox)->GetLastRButtonDownIndex ();
+ long lCount = m_pGraphKindListBox->GetCount ();
+ for (i = 0; i < lCount; i++) {
+ m_pGraphKindListBox->SetCheck (i, i == lGraphIndex ? 1 : 0);
+ m_bGraphVisible[i] = (i == lGraphIndex ? TRUE : FALSE);
+ }
+ m_bOnlyCurGraph = FALSE;
+ m_bShowAllGraph = FALSE;
+ // カレントグラフを更新
+ if (m_bGraphVisible[lGraphIndex]) {
+ SetCurGraphKind (lGraphIndex);
+ }
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『このグラフのみ表示ON』
+void CPianoRollFrame::OnUpdatePopupGraphKindVisibleOnUI (CCmdUI* pCmdUI) {
+}
+
+// 『ポップアップ』-『このグラフの種類のみ表示OFF』
+void CPianoRollFrame::OnPopupGraphKindVisibleOff () {
+ long i;
+ long lGraphIndex = ((CGraphKindListBox*)m_pGraphKindListBox)->GetLastRButtonDownIndex ();
+ long lCount = m_pGraphKindListBox->GetCount ();
+ for (i = 0; i < lCount; i++) {
+ m_pGraphKindListBox->SetCheck (i, i == lGraphIndex ? 0 : 1);
+ m_bGraphVisible[i] = (i == lGraphIndex ? FALSE : TRUE);
+ }
+ m_bOnlyCurGraph = FALSE;
+ m_bShowAllGraph = FALSE;
+ // カレントグラフを更新
+ if (m_bGraphVisible[lGraphIndex]) {
+ SetCurGraphKind (lGraphIndex);
+ }
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+}
+
+// 『ポップアップ』-『このグラフのみ表示OFF』
+void CPianoRollFrame::OnUpdatePopupGraphKindVisibleOffUI (CCmdUI* pCmdUI) {
+}
+
+
+// 『ポップアップ』-『全グラフ表示ON』
+void CPianoRollFrame::OnPopupGraphKindVisibleAll () {
+ long i = 0;
+ long lCount = m_pGraphKindListBox->GetCount ();
+ for (i = 0; i < lCount; i++) {
+ m_pGraphKindListBox->SetCheck (i, 1);
+ m_bGraphVisible[i] = TRUE;
+ }
+ m_bOnlyCurTrack = FALSE;
+ m_bShowAllTrack = FALSE;
+ // 再描画
+ m_pKeyScaleView->Invalidate ();
+ m_pKeyTimeView->Invalidate ();
+ m_pVelScaleView->Invalidate ();
+ m_pVelTimeView->Invalidate ();
+
+}
+
+// 『ポップアップ』-『全グラフ表示ON』
+void CPianoRollFrame::OnUpdatePopupGraphKindVisibleAllUI (CCmdUI* pCmdUI) {
+}
diff --git a/src/PianoRollFrame.h b/src/PianoRollFrame.h
new file mode 100644
index 0000000..72bdac9
--- /dev/null
+++ b/src/PianoRollFrame.h
@@ -0,0 +1,245 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールフレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLFRAME_H_
+#define _PIANOROLLFRAME_H_
+
+class CPianoRollFrame : public CChildFrame {
+ DECLARE_DYNCREATE (CPianoRollFrame)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ long m_lToolBar1Height; // ツールバー1の高さ[pixel]
+ long m_lKeyHeight; // キービュー(上ペイン)の高さ[pixel]
+ long m_lScaleHeight; // 上部目盛りビューの高さ[pixel]
+ long m_lVelHeight; // ベロシティビュー(下ペイン)の高さ[pixel]
+ long m_lScaleWidth; // 左部目盛りビューの幅[pixel]
+ long m_lTimeWidth; // 時間ビュー(左ペイン)の幅[pixel]
+ long m_lHScrollBarHeight; // 水平スクロールバーの高さ[pixel]
+ long m_lVScrollBarWidth; // 垂直スクロールバーの幅[pixel]
+ long m_lTrackListWidth; // トラックリスト(右ペイン)の幅[pixel]
+ long m_lKeyZoom; // キー方向拡大倍率[倍]
+ long m_lTimeZoom; // タイム方向拡大倍率[倍]
+ long m_lVelZoom; // ベロシティ方向ズーム倍率[倍]
+ long m_lKeyScrollPos; // キー方向スクロール位置[pixel]
+ long m_lVelScrollPos; // ベロシティ方向スクロール位置[pixel]
+ long m_lTimeScrollPos; // 時間方向スクロール位置[pixel]
+public:
+ CFont m_theFont; // ピアノロールウィンドウで使うフォント
+public:
+ CSekaijuToolBar m_wndToolBar1; // ツールバー1
+ CColorfulComboBox m_wndTrackCombo; // トラックコンボボックス
+ CComboBox m_wndChannelCombo; // チャンネルコンボボックス
+ CComboBox m_wndSnapCombo; // スナップコンボボックス
+ CComboBox m_wndVelocityCombo; // ベロシティコンボボックス
+ CComboBox m_wndDurationCombo; // 音長さコンボボックス
+ CComboBox m_wndGraphKindCombo; // グラフの種類コンボボックス
+ CComboBox m_wndGraphSnapCombo; // グラフスナップコンボボックス
+ CView* m_pDummyView; // ダミービュー(Visible=FALSE)へのポインタ
+ CView* m_pPrintView; // 印刷用ビュー(Visible=FALSE)へのポインタ
+ CView* m_pScaleView; // 目盛りビューへのポインタ
+ CView* m_pTimeScaleView; // 時間目盛りビューへのポインタ
+ CView* m_pKeyScaleView; // 音階目盛りビューへのポインタ
+ CView* m_pKeyTimeView; // 音階-時間ビューへのポインタ
+ CView* m_pVelScaleView; // ベロシティ目盛りビューへのポインタ
+ CView* m_pVelTimeView; // ベロシティ-時間ビューへのポインタ
+ CCheckListBox* m_pTrackListBox; // トラックリストボックスへのポインタ
+ CCheckListBox* m_pGraphKindListBox; // グラフの種類リストボックス
+ CScrollBar m_wndTimeScroll; // 時間方向スクロールバー
+ CScrollBar m_wndKeyScroll; // 音階方向スクロールバー
+ CScrollBar m_wndVelScroll; // ベロシティ方向スクロールバー
+ CScrollBar m_wndSizeScroll; // サイズ変更スクロールバー
+ CBitmapButton m_wndTimeZoomUp; // 時間方向拡大ボタン
+ CBitmapButton m_wndTimeZoomDown; // 時間方向縮小ボタン
+ CBitmapButton m_wndVelZoomUp; // ベロシティ方向拡大ボタン
+ CBitmapButton m_wndVelZoomDown; // ベロシティ方向縮小ボタン
+ CBitmapButton m_wndKeyZoomUp; // キー方向拡大ボタン
+ CBitmapButton m_wndKeyZoomDown; // キー方向縮小ボタン
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標(スプリッターを動かすのに使う)
+ CPoint m_ptMouseMoveOld; // マウスが動かされたときの前回の座標(スプリッターを動かすのに使う)
+ BOOL m_bSplitterMovingH; // 現在水平スプリッターを動かしているところか?
+ BOOL m_bSplitterMovingV; // 現在垂直スプリッターを動かしているところか?
+public:
+ BOOL m_bAutoPageUpdate; // 自動的にページを更新するか?
+ long m_lCurTool; // 現在の選択されているツール(0=描画,1=線画,2=消しゴム,3=選択,4=試聴)
+protected:
+ BOOL m_bOnlyCurTrack; // 現在のトラックのみを表示するか?
+ BOOL m_bShowAllTrack; // すべてのトラックを表示するか?
+ BOOL m_bTrackVisible[MAXMIDITRACKNUM]; // トラック[0〜65535]は可視か?
+ BOOL m_bOnlyCurGraph; // 現在のグラフのみを表示するか?
+ BOOL m_bShowAllGraph; // すべてのグラフを表示するか?
+ BOOL m_bGraphVisible[256]; // グラフ[0〜255]は可視か?
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollFrame (); // コンストラクタ
+ virtual ~CPianoRollFrame(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual CSekaijuDoc* GetDocument ();
+ virtual long GetTimeZoom ();
+ virtual long GetKeyZoom ();
+ virtual long GetVelZoom ();
+ virtual long XtoTime (long x);
+ virtual long TimetoX (long lTime);
+ virtual long YtoKey (long y);
+ virtual long KeytoY (long lKey);
+ virtual long YtoPitchBend (long y);
+ virtual long YtoVel (long y);
+ virtual long YtoTempoBPM (long y);
+ virtual long VeltoY (long lVel);
+ virtual long PitchBendtoY (long lPitchBend);
+ virtual long TempoBPMtoY (long lTempo);
+ virtual long GetTimeScrollPos ();
+ virtual long GetKeyScrollPos ();
+ virtual long GetVelScrollPos ();
+ virtual long SetTimeScrollPos (long lTimeScrollPos);
+ virtual long SetKeyScrollPos (long lKeyScrollPos);
+ virtual long SetVelScrollPos (long lVelScrollPos);
+ virtual long GetVisibleLeftTime ();
+ virtual long GetVisibleRightTime ();
+ virtual long GetVisibleTopKey ();
+ virtual long GetVisibleBottomKey ();
+ virtual long GetVisibleTopVel ();
+ virtual long GetVisibleBottomVel ();
+ virtual void DrawSplitterCaptor (CDC* pDC, CPoint pt);
+ virtual long GetCurTrackIndex ();
+ virtual long GetCurChannel ();
+ virtual long GetCurSnap ();
+ virtual long GetCurVelocity ();
+ virtual long GetCurDuration ();
+ virtual long GetCurGraphKind ();
+ virtual long GetCurGraphSnap ();
+ virtual BOOL SetCurTrackIndex (long lCurTrackIndex);
+ virtual BOOL SetCurChannel (long lCurChannel);
+ virtual BOOL SetCurSnap (long lCurSnap);
+ virtual BOOL SetCurVelocity (long lCurVelocity);
+ virtual BOOL SetCurDuration (long lCurDuration);
+ virtual BOOL SetCurGraphKind (long lCurGraphKind);
+ virtual BOOL SetCurGraphSnap (long lCurGraphKind);
+ virtual BOOL IsTrackVisible (long lTrackIndex);
+ virtual BOOL SetTrackVisible (long lTrackIndex);
+ virtual BOOL IsGraphVisible (long lGraphKind);
+ virtual BOOL SetGraphVisible (long lGraphKind);
+ virtual BOOL UpdateTrackCombo ();
+ virtual BOOL UpdateGraphKindCombo ();
+ virtual BOOL UpdateTrackList ();
+ virtual BOOL UpdateGraphKindList ();
+ virtual BOOL UpdateSnapCombo ();
+ virtual BOOL UpdateVelocityCombo ();
+ virtual BOOL UpdateDurationCombo ();
+ virtual BOOL UpdateGraphSnapCombo ();
+ virtual void RecalcKeyScrollInfo ();
+ virtual void RecalcVelScrollInfo ();
+ virtual void RecalcTimeScrollInfo ();
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+ virtual void OnUpdateFrameTitle (BOOL bAddToTitle);
+ virtual void RecalcLayout (BOOL bNotify = TRUE);
+ virtual BOOL OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ virtual BOOL OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnSize (UINT nType, int cx, int cy);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg BOOL OnEraseBkgnd (CDC* pDC);
+ afx_msg void OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd);
+ afx_msg void OnPaint ();
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnTimeZoomDown ();
+ afx_msg void OnTimeZoomUp ();
+ afx_msg void OnKeyZoomDown ();
+ afx_msg void OnKeyZoomUp ();
+ afx_msg void OnVelZoomDown ();
+ afx_msg void OnVelZoomUp ();
+ afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnPianoRollPen ();
+ afx_msg void OnUpdatePianoRollPenUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollLine ();
+ afx_msg void OnUpdatePianoRollLineUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollEraser ();
+ afx_msg void OnUpdatePianoRollEraserUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollSelect ();
+ afx_msg void OnUpdatePianoRollSelectUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollSpeaker ();
+ afx_msg void OnUpdatePianoRollSpeakerUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollOnlyCurTrack ();
+ afx_msg void OnUpdatePianoRollOnlyCurTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollShowAllTrack ();
+ afx_msg void OnUpdatePianoRollShowAllTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollOnlyCurGraph ();
+ afx_msg void OnUpdatePianoRollOnlyCurGraphUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollShowAllGraph ();
+ afx_msg void OnUpdatePianoRollShowAllGraphUI (CCmdUI* pCmdUI);
+ afx_msg void OnPianoRollAutoPageUpdate ();
+ afx_msg void OnUpdatePianoRollAutoPageUpdateUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnTrackComboSelEndOK ();
+ afx_msg void OnTrackListChkChange ();
+ afx_msg void OnTrackListSelChange ();
+ afx_msg void OnGraphKindComboSelEndOK ();
+ afx_msg void OnGraphKindListChkChange ();
+ afx_msg void OnGraphKindListSelChange ();
+
+ afx_msg void OnPopupEventProperty ();
+ afx_msg void OnUpdatePopupEventPropertyUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackVisibleOn ();
+ afx_msg void OnUpdatePopupTrackVisibleOnUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackVisibleOff ();
+ afx_msg void OnUpdatePopupTrackVisibleOffUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackVisibleAll ();
+ afx_msg void OnUpdatePopupTrackVisibleAllUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupGraphKindVisibleOn ();
+ afx_msg void OnUpdatePopupGraphKindVisibleOnUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupGraphKindVisibleOff ();
+ afx_msg void OnUpdatePopupGraphKindVisibleOffUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupGraphKindVisibleAll ();
+ afx_msg void OnUpdatePopupGraphKindVisibleAllUI (CCmdUI* pCmdUI);
+
+ DECLARE_MESSAGE_MAP()
+};
+
+
+#endif
+
diff --git a/src/PianoRollKeyScaleView.cpp b/src/PianoRollKeyScaleView.cpp
new file mode 100644
index 0000000..e191ebd
--- /dev/null
+++ b/src/PianoRollKeyScaleView.cpp
@@ -0,0 +1,517 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールキースケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "PianoRollKeyScaleView.h"
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CPianoRollKeyScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CPianoRollKeyScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollKeyScaleView::CPianoRollKeyScaleView () {
+}
+
+// デストラクタ
+CPianoRollKeyScaleView::~CPianoRollKeyScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CPianoRollKeyScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ pDC->SetWindowOrg (0, pPianoRollFrame->GetKeyScrollPos ());
+}
+
+// 描画
+void CPianoRollKeyScaleView::OnDraw (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ int w = rcClient.Width ();
+ int hh;
+ int i;
+ long lKeyZoom = pPianoRollFrame->GetKeyZoom ();
+ //pDC->Rectangle (0, 0, w, m_nKeyZoom * 128);
+ pDC->MoveTo (0, 0);
+ pDC->LineTo (w, 0);
+ // 10オクターブループ
+ for (i = 0; i < 11; i++) {
+ hh = (128 - 12 * i) * lKeyZoom ;
+ // 白鍵と白鍵の間の線
+ pDC->MoveTo (0, hh - lKeyZoom * 0);
+ pDC->LineTo (w, hh - lKeyZoom * 0);
+ pDC->MoveTo (0, hh - lKeyZoom * 3 / 2);
+ pDC->LineTo (w, hh - lKeyZoom * 3 / 2);
+ pDC->MoveTo (0, hh - lKeyZoom * 7 / 2);
+ pDC->LineTo (w, hh - lKeyZoom * 7 / 2);
+ pDC->MoveTo (0, hh - lKeyZoom * 5);
+ pDC->LineTo (w, hh - lKeyZoom * 5);
+ pDC->MoveTo (0, hh - lKeyZoom * 13 / 2);
+ pDC->LineTo (w, hh - lKeyZoom * 13 / 2);
+ pDC->MoveTo (0, hh - lKeyZoom * 17 / 2);
+ pDC->LineTo (w, hh - lKeyZoom * 17 / 2);
+ pDC->MoveTo (0, hh - lKeyZoom * 21 / 2);
+ pDC->LineTo (w, hh - lKeyZoom * 21 / 2);
+ // 黒鍵部分塗りつぶし
+ pDC->FillSolidRect
+ (0, hh - lKeyZoom * 2, w * 2 / 3, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, hh - lKeyZoom * 4, w * 2 / 3, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, hh - lKeyZoom * 7, w * 2 / 3, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, hh - lKeyZoom * 9, w * 2 / 3, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, hh - lKeyZoom * 11, w * 2 / 3, lKeyZoom, RGB (0, 0, 0));
+ }
+ //pDC->MoveTo (0, 0);
+ //pDC->LineTo (0, m_nKeyZoom * 128);
+ //pDC->MoveTo (w - 1, 0);
+ //pDC->LineTo (w - 1, m_nKeyZoom * 128);
+
+ // 文字
+ pDC->FillSolidRect
+ (0, 0, 0, 0, ::GetSysColor (COLOR_WINDOW));
+ CRect rcText (rcClient);
+ rcText.left = w * 2 / 3;
+ CFont* pOldFont = pDC->SelectObject (&(pPianoRollFrame->m_theFont));
+ for (i = 0; i < 11; i++) {
+ hh = (128 - 12 * i) * lKeyZoom;
+ rcText.top = hh - lKeyZoom / 2 - 6;
+ rcText.bottom = hh - lKeyZoom / 2 + 6;
+ CString strText;
+ strText.Format (_T("%d"), i * 12);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ pDC->SelectObject (pOldFont);
+
+ // 選択部反転
+ if (GetCapture () == this) {
+ long lDownY = pPianoRollFrame->KeytoY (m_lDownKey);
+ long lCurY = pPianoRollFrame->KeytoY (m_lCurKey);
+ long lTop = __min (lDownY, lCurY) - lKeyZoom;
+ long lBottom = __max (lDownY, lCurY);
+ CRect rect (0, lTop, w, lBottom);
+ pDC->SetROP2 (R2_NOT);
+ pDC->Rectangle (&rect);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CPianoRollKeyScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キーが押された時
+void CPianoRollKeyScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ switch (nChar) {
+ // Deleteキー
+ case VK_DELETE:
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ break;
+ // デフォルト
+ default:
+ pPianoRollFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+
+// マウス左ボタン押された時
+void CPianoRollKeyScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetKeyScrollPos ());
+ point += CSize (0, pPianoRollFrame->GetKeyScrollPos ());
+
+ // 履歴の記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+
+ m_lOldKey = pPianoRollFrame->YtoKey (m_ptMouseDown.y);
+ m_lDownKey = pPianoRollFrame->YtoKey (point.y);
+ m_lCurKey = pPianoRollFrame->YtoKey (point.y);
+
+ // 発音
+ long lCurTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lTrackOutputPort && lTrackOutputPort < MAXMIDIOUTDEVICENUM) {
+ MIDIOut* pMIDIOut = pSekaijuApp->m_pMIDIOut[lTrackOutputPort];
+ MIDIStatus* pMIDIOutStatus = pSekaijuApp->m_pMIDIOutStatus[lTrackOutputPort];
+ long lChannel = lTrackOutputChannel;
+ long lVelocity = pPianoRollFrame->GetCurVelocity ();
+ if (lChannel < 0 || lChannel >= 16) {
+ lChannel = pPianoRollFrame->GetCurChannel ();
+ }
+ BYTE byMsg[3];
+ byMsg[0] = 0x90 | (BYTE)CLIP(0, lChannel, 15);
+ byMsg[1] = (BYTE)CLIP (0, m_lDownKey + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ byMsg[2] = (BYTE)CLIP (0, lVelocity + MIDITrack_GetVelocityPlus (pMIDITrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMsg, 3);
+ }
+ if (pMIDIOutStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIOutStatus, byMsg, 3);
+ }
+ }
+ }
+
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ Invalidate ();
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CPianoRollKeyScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+}
+
+// マウス左ボタン離されたとき
+void CPianoRollKeyScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetKeyScrollPos ());
+ point += CSize (0, pPianoRollFrame->GetKeyScrollPos ());
+
+ if (GetCapture () == this) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ KillTimer (0x21);
+ ReleaseCapture ();
+
+ long lMinKey = __min (m_lDownKey, m_lCurKey);
+ long lMaxKey = __max (m_lDownKey, m_lCurKey);
+
+ // 古いキーを消音
+ long lCurTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lTrackOutputPort && lTrackOutputPort < MAXMIDIOUTDEVICENUM) {
+ MIDIOut* pMIDIOut = pSekaijuApp->m_pMIDIOut[lTrackOutputPort];
+ MIDIStatus* pMIDIOutStatus = pSekaijuApp->m_pMIDIOutStatus[lTrackOutputPort];
+ long lChannel = lTrackOutputChannel;
+ if (lChannel < 0 || lChannel >= 16) {
+ lChannel = pPianoRollFrame->GetCurChannel ();
+ }
+ BYTE byMsg[3];
+ byMsg[0] = 0x90 | (BYTE)CLIP(0, lChannel, 15);
+ byMsg[1] = (BYTE)CLIP (0, m_lCurKey + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ byMsg[2] = 0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMsg, 3);
+ }
+ if (pMIDIOutStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIOutStatus, byMsg, 3);
+ }
+ }
+ }
+
+ // 該当範囲にあるノートイベントの選択
+ long i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if ((MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent)) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ long lKey = MIDIEvent_GetKey (pMIDIEvent);
+ if (lMinKey <= lKey && lKey <= lMaxKey) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CPianoRollKeyScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CPianoRollKeyScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetKeyScrollPos ());
+ point += CSize (0, pPianoRollFrame->GetKeyScrollPos ());
+
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ m_lCurKey = pPianoRollFrame->YtoKey (point.y);
+ m_lDownKey = pPianoRollFrame->YtoKey (m_ptMouseDown.y);
+ m_lOldKey = pPianoRollFrame->YtoKey (m_ptMouseMove.y);
+ // 前回のキーと今回のキーが異なる場合のみ
+ if (m_lOldKey != m_lCurKey) {
+ // 古いキーを消音、新しいキーを発音
+ long lCurTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lCurTrackIndex);
+ if (pMIDITrack) {
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lTrackOutputPort && lTrackOutputPort < MAXMIDIOUTDEVICENUM) {
+ MIDIOut* pMIDIOut = pSekaijuApp->m_pMIDIOut[lTrackOutputPort];
+ MIDIStatus* pMIDIOutStatus = pSekaijuApp->m_pMIDIOutStatus[lTrackOutputPort];
+ long lChannel = lTrackOutputChannel;
+ long lVelocity = pPianoRollFrame->GetCurVelocity ();
+ if (lChannel < 0 || lChannel >= 16) {
+ lChannel = pPianoRollFrame->GetCurChannel ();
+ }
+ BYTE byMsg[3];
+ byMsg[0] = 0x90 | (BYTE)CLIP(0, lChannel, 15);
+ byMsg[1] = (BYTE)CLIP (0, m_lOldKey + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ byMsg[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMsg, 3);
+ }
+ if (pMIDIOutStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIOutStatus, byMsg, 3);
+ }
+ byMsg[1] = (BYTE)CLIP (0, m_lCurKey + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ byMsg[2] = (BYTE)CLIP (1, lVelocity + MIDITrack_GetVelocityPlus (pMIDITrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMsg, 3);
+ }
+ if (pMIDIOutStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIOutStatus, byMsg, 3);
+ }
+ }
+ }
+ // 鍵盤再描画
+ Invalidate (TRUE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CPianoRollKeyScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CPianoRollKeyScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CPianoRollKeyScaleView::OnTimer (UINT nIDEvent) {
+
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetKeyScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldKeyScrollPos = pPianoRollFrame->GetKeyScrollPos ();
+ if (m_ptMouseMove.y < rcClient.top) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pPianoRollFrame->m_wndKeyScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y >= rcClient.bottom) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pPianoRollFrame->m_wndKeyScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldKeyScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+// マウスホイールが回された時
+void CPianoRollKeyScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lKeyScrollPos = pPianoRollFrame->GetKeyScrollPos ();
+ long lKeyZoom = pPianoRollFrame->GetKeyZoom ();
+ lKeyScrollPos -= lKeyZoom * lDelta / WHEELDELTA;
+ pPianoRollFrame->SetKeyScrollPos (lKeyScrollPos);
+ }
+}
diff --git a/src/PianoRollKeyScaleView.h b/src/PianoRollKeyScaleView.h
new file mode 100644
index 0000000..55fe3d5
--- /dev/null
+++ b/src/PianoRollKeyScaleView.h
@@ -0,0 +1,78 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールキースケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLKEYSCALEVIEW_H_
+#define _PIANOROLLKEYSCALEVIEW_H_
+
+class CPianoRollKeyScaleView : public CSekaijuView {
+protected:
+ DECLARE_DYNCREATE (CPianoRollKeyScaleView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lDownKey; // マウスが押されたときの時の音階(0〜127)
+ long m_lCurKey; // マウスが指す現在の音階(0〜127)
+ long m_lOldKey; // マウスが指す前回の音階(0〜127)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollKeyScaleView (); // コンストラクタ
+ virtual ~CPianoRollKeyScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo = NULL);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
+
diff --git a/src/PianoRollKeyTimeView.cpp b/src/PianoRollKeyTimeView.cpp
new file mode 100644
index 0000000..28a06fe
--- /dev/null
+++ b/src/PianoRollKeyTimeView.cpp
@@ -0,0 +1,2181 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールキータイムビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "PianoRollKeyTimeView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CPianoRollKeyTimeView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CPianoRollKeyTimeView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_TIMER ()
+ ON_WM_KEYDOWN ()
+ ON_WM_KEYUP ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollKeyTimeView::CPianoRollKeyTimeView () {
+ m_lCurTime = m_lOldTime = 0;
+ m_lOldY1 = m_lOldY2 = 0;
+ m_bOldDraw = TRUE;
+ m_pTempEvent = NULL;
+ m_lTempMode = 0;
+ m_pLastEvent = NULL;
+}
+
+// デストラクタ
+CPianoRollKeyTimeView::~CPianoRollKeyTimeView () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// ノート矩形を取得する
+CRect CPianoRollKeyTimeView::GetNoteRect (MIDIEvent* pNoteOnEvent) {
+ ASSERT (pNoteOnEvent);
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ if (!MIDIEvent_IsNoteOn (pNoteOnEvent)) {
+ return CRect (0,0,0,0);
+ }
+ long lTime = MIDIEvent_GetTime (pNoteOnEvent);
+ long lKey = MIDIEvent_GetKey (pNoteOnEvent);
+ long lDuration = MIDIEvent_GetDuration (pNoteOnEvent);
+ long x = pPianoRollFrame->TimetoX (lTime);
+ long w = pPianoRollFrame->TimetoX (lDuration);
+ long y = pPianoRollFrame->KeytoY (lKey);
+ long h = pPianoRollFrame->GetKeyZoom ();
+ return CRect (x, y - h, x + w, y);
+}
+
+
+
+
+// 旧位置の縦線消去
+void CPianoRollKeyTimeView::EraseOldLine (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ if (rcClient.left <= m_lOldX && m_lOldX <= rcClient.right && m_bOldDraw == TRUE) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_lOldX, m_lOldY1);
+ pDC->LineTo (m_lOldX, m_lOldY2);
+ }
+}
+
+// 現在位置の縦線描画
+void CPianoRollKeyTimeView::DrawCurLine (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ long x = pPianoRollFrame->TimetoX (m_lCurTime);
+ if (rcClient.left <= x && x <= rcClient.right) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ m_bOldDraw = TRUE;
+ m_lOldTime = m_lCurTime;
+ m_lOldX = x;
+ m_lOldY1 = rcClient.top;
+ m_lOldY2 = rcClient.bottom;
+ }
+ else {
+ m_bOldDraw = FALSE;
+ }
+}
+
+// ポップアップメニューの表示
+BOOL CPianoRollKeyTimeView::ShowPopupMenu (CPoint ptMenu) {
+
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (m_lTempMode == 0x1001);
+ // ノートイベント上でポップアップメニューを表示した場合
+ if (m_pTempEvent) {
+ pSekaijuDoc->m_lTempTime = MIDIEvent_GetTime (m_pTempEvent);
+ pSekaijuDoc->m_pTempTrack = MIDIEvent_GetParent (m_pTempEvent);
+ pSekaijuDoc->m_pTempEvent = m_pTempEvent;
+ }
+ // 何もないところでポップアップメニューを表示した場合
+ else {
+ pSekaijuDoc->m_lTempTime = pSekaijuDoc->m_lNewTime;
+ pSekaijuDoc->m_pTempTrack = NULL; //pSekaijuDoc->m_pTempTrack; // 20100429修正
+ pSekaijuDoc->m_pTempEvent = NULL;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU11));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pPianoRollFrame);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lTempMode = 0x0000;
+
+ return TRUE;
+}
+
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CPianoRollKeyTimeView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ pDC->SetWindowOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+}
+
+// 描画
+void CPianoRollKeyTimeView::OnDraw (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[1]);
+ CPen penBeat (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen penOctave (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[1]);
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long x, y, lTime;
+ long lVisibleLeftTime = pPianoRollFrame->GetVisibleLeftTime ();
+ long lVisibleRightTime = pPianoRollFrame->GetVisibleRightTime ();
+ long lVisibleTopKey = pPianoRollFrame->GetVisibleTopKey ();
+ long lVisibleBottomKey = pPianoRollFrame->GetVisibleBottomKey ();
+ long lLeftMeasure, lLeftBeat, lLeftTick;
+ long lRightMeasure, lRightBeat, lRightTick;
+ long lnn, ldd, lcc, lbb;
+ long lUnitTick;
+ long temp;
+
+ // 横線の描画
+ CPen* pOldPen = pDC->SelectObject (&penKey);
+ long lKeyZoom = pPianoRollFrame->GetKeyZoom ();
+ long i, j;
+ for (i = lVisibleBottomKey; i <= lVisibleTopKey + 1; i++) {
+ y = pPianoRollFrame->KeytoY (i);
+ // 黒鍵部の塗り潰し
+ temp = i % 12;
+ if (temp == 1 || temp == 3 || temp == 6 || temp == 8 || temp == 10) {
+ pDC->FillSolidRect (rcClient.left, y, rcClient.Width (), -lKeyZoom,
+ pSekaijuApp->m_theColorOption.m_lBackColor[1]);
+ }
+ // 白鍵部の塗り潰し
+ else {
+ pDC->FillSolidRect (rcClient.left, y, rcClient.Width (), -lKeyZoom,
+ pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+ }
+ // 横線描画
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+
+ // 縦線の描画
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ MIDIData_BreakTime (pMIDIData, lVisibleLeftTime, &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_BreakTime (pMIDIData, lVisibleRightTime, &lRightMeasure, &lRightBeat, &lRightTick);
+ for (i = lLeftMeasure; i <= lRightMeasure; i++) {
+ // 小節線の描画
+ MIDIData_MakeTimeEx (pMIDIData, i, 0, 0, &lTime, &lnn, &ldd, &lcc, &lbb);
+ x = pPianoRollFrame->TimetoX (lTime);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ // 拍線の描画
+ pDC->SelectObject (&penBeat);
+ lUnitTick = lTimeResolution * 4 / (1 << ldd);
+ for (long j = 1; j < lnn; j++) {
+ x = pPianoRollFrame->TimetoX (lTime + j * lUnitTick);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ }
+ }
+ }
+ else {
+ long lLeftFrameNumber = lVisibleLeftTime / lTimeResolution;
+ long lRightFrameNumber = lVisibleRightTime / lTimeResolution;
+ for (i = lLeftFrameNumber; i <= lRightFrameNumber; i++) {
+ // フレーム境界線の描画
+ lTime = i * lTimeResolution;
+ x = pPianoRollFrame->TimetoX (lTime);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+
+ // オクターブ線の描画
+ pDC->SelectObject (&penOctave);
+ for (j = lVisibleBottomKey; j <= lVisibleTopKey; j++) {
+ if (j % 12 == 0) {
+ y = pPianoRollFrame->KeytoY (j);
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+ }
+
+ // ピアノロールバーの描画
+ long w;
+ CPen penBar (PS_SOLID, 1, RGB (0, 0, 0));
+ pDC->SelectObject (&penBar);
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ long lColor = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ if (pMIDIEvent->m_lTime < lVisibleRightTime) {
+ x = pPianoRollFrame->TimetoX (MIDIEvent_GetTime (pMIDIEvent));
+ w = pPianoRollFrame->TimetoX (MIDIEvent_GetDuration (pMIDIEvent));
+ y = pPianoRollFrame->KeytoY (MIDIEvent_GetKey (pMIDIEvent));
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent)) {
+ pDC->FillSolidRect (CRect (x, y, x + w, y - lKeyZoom), RGB (0, 0, 0));
+ }
+ else {
+ pDC->FillSolidRect (CRect (x, y, x + w, y - lKeyZoom), lColor);
+ }
+ pDC->Draw3dRect (x, y - lKeyZoom, w, lKeyZoom ,RGB (255,255,255), RGB (0, 0, 0));
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ pDC->SelectObject (pOldPen);
+
+ // 現在位置の描画
+ DrawCurLine (pDC);
+
+ // マウストラッカーが必要な場合、マウストラッカーの描画
+ if (GetCapture () == this) {
+ if (m_lTempMode == 0x0401) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseDown.y);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseMove.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseDown.x, m_ptMouseMove.y);
+ pDC->MoveTo (m_ptMouseMove.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+ // ライントラッカーが必要な場合、ライントラッカーの描画
+ else if (m_lTempMode == 0x0201) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ Sleep (0);
+}
+
+// ビューの更新
+void CPianoRollKeyTimeView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ PostMessage (WM_TIMER, 0x11, NULL);
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+// ウィンドウクラスの変更
+BOOL CPianoRollKeyTimeView::PreCreateWindow (CREATESTRUCT& cs) {
+ CView::PreCreateWindow (cs);
+ cs.lpszClass = AfxRegisterWndClass
+ (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS,
+ NULL, // デフォルトカーソル無し
+ (HBRUSH)::GetStockObject (WHITE_BRUSH), // デフォルト背景ブラシ
+ NULL); // デフォルトアイコン無し
+ return TRUE;
+}
+
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CPianoRollKeyTimeView::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+ SetTimer (0x11, 55, NULL);
+ return CSekaijuView::OnCreate (lpCreateStruct);
+}
+
+// ウィンドウ破棄時
+void CPianoRollKeyTimeView::OnDestroy () {
+ KillTimer (0x11);
+ CSekaijuView::OnDestroy ();
+}
+
+// タイマー呼び出し時
+void CPianoRollKeyTimeView::OnTimer (UINT nIDEvent) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+
+ // 演奏・記録中のカレントバー移動処理
+ if (nIDEvent == 0x11) {
+ if (pSekaijuDoc->m_pMIDIData && pSekaijuDoc->m_pMIDIClock) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ CDC* pDC = GetDC ();
+ OnPrepareDC (pDC, NULL);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ m_lCurTime = MIDIClock_GetTickCount (GetDocument ()->m_pMIDIClock);
+ // 前回の時刻と現在の時刻が違っている場合のみ
+ if (m_lOldTime != m_lCurTime) {
+ EraseOldLine (pDC);
+ DrawCurLine (pDC);
+ }
+ // ページの更新およびオートスクロール(手動スクロール時はしない)
+ if (pPianoRollFrame->m_bAutoPageUpdate == TRUE) {
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ // 現在位置が右側へはみ出した場合
+ long lRightMeasure; long lRightBeat; long lRightTick; long lTempRightTime;
+ MIDIData_BreakTime (pMIDIData, pPianoRollFrame->GetVisibleRightTime (),
+ &lRightMeasure, &lRightBeat, &lRightTick);
+ MIDIData_MakeTime (pMIDIData, lRightMeasure, 0, 0, &lTempRightTime);
+ if (m_lCurTime >= lTempRightTime) {
+ long lNewMeasure; long lNewBeat; long lNewTick;
+ MIDIData_BreakTime (pMIDIData, m_lCurTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ MIDIData_MakeTime (pMIDIData, lNewMeasure, 0, 0, &lTempRightTime);
+ int x = pPianoRollFrame->TimetoX (lTempRightTime);
+ pPianoRollFrame->SetTimeScrollPos (x);
+ }
+ // 現在位置が左側へはみ出した場合
+ long lLeftMeasure; long lLeftBeat; long lLeftTick; long lTempLeftTime;
+ MIDIData_BreakTime (pMIDIData, pPianoRollFrame->GetVisibleLeftTime (),
+ &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_MakeTime (pMIDIData, lLeftMeasure, 0, 0, &lTempLeftTime);
+ if (m_lCurTime < lTempLeftTime) {
+ long lNewMeasure; long lNewBeat; long lNewTick;
+ MIDIData_BreakTime (GetDocument()->m_pMIDIData, m_lCurTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ MIDIData_MakeTime (GetDocument()->m_pMIDIData, lNewMeasure, 0, 0, &lTempLeftTime);
+ int x = pPianoRollFrame->TimetoX (lTempLeftTime);
+ pPianoRollFrame->SetTimeScrollPos (x);
+ }
+ }
+ else {
+ // 現在位置が右側へはみ出した場合
+ long lRightFrameNumber = pPianoRollFrame->GetVisibleRightTime () / lTimeResolution;
+ long lTempRightTime = lRightFrameNumber * lTimeResolution;
+ if (m_lCurTime >= lTempRightTime) {
+ lTempRightTime = (m_lCurTime / lTimeResolution) * lTimeResolution;
+ long x = pPianoRollFrame->TimetoX (lTempRightTime);
+ pPianoRollFrame->SetTimeScrollPos (x);
+ }
+ // 現在位置が左側へはみ出した場合
+ long lLeftFrameNumber = pPianoRollFrame->GetVisibleLeftTime () / lTimeResolution;
+ long lTempLeftTime = lLeftFrameNumber * lTimeResolution;
+ if (m_lCurTime < lTempLeftTime) {
+ lTempLeftTime = (m_lCurTime / lTimeResolution) * lTimeResolution;
+ long x = pPianoRollFrame->TimetoX (lTempLeftTime);
+ pPianoRollFrame->SetTimeScrollPos (x);
+ }
+ }
+ }
+ ReleaseDC (pDC);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理
+ else if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ long lOldTimeScrollPos = pPianoRollFrame->GetTimeScrollPos ();
+ long lOldKeyScrollPos = pPianoRollFrame->GetKeyScrollPos ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (m_ptMouseMove.x < rcClient.left) {
+ pPianoRollFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pPianoRollFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.x > rcClient.right) {
+ pPianoRollFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pPianoRollFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ if (m_ptMouseMove.y < rcClient.top) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pPianoRollFrame->m_wndKeyScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y > rcClient.bottom) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pPianoRollFrame->m_wndKeyScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x - lOldTimeScrollPos);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldKeyScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+
+// キーが押された時
+void CPianoRollKeyTimeView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ switch (nChar) {
+ // DEL
+ case VK_DELETE:
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CHistoryUnit* pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ long lOldKey = pPianoRollFrame->YtoKey (m_ptMouseMove.y);
+ switch (m_lTempTool) {
+ // ペン
+ case ID_PIANOROLL_PEN:
+ if ((m_lTempMode == 0x0101 || m_lTempMode == 0x0102) && m_pTempEvent != NULL) {
+ ASSERT (m_pTempTrack);
+ // 置こうとしているノート又は移動中のノート削除
+ if (m_lTempMode = 0x0101) {
+ MIDIEvent_Delete (m_pTempEvent);
+ m_pTempEvent = NULL;
+ }
+ else if (m_lTempMode = 0x0102) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempEvent);
+ MIDITrack_RemoveEvent (m_pTempTrack, m_pTempEvent);
+ }
+ // 履歴記録
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ // 古いキー消音
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ BYTE byMIDIMessage[3];
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ ReleaseCapture ();
+ KillTimer (0x21);
+ m_lTempMode = 0;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ break;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ // キャプター中でないならば
+ else {
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ }
+ break;
+ // ESC
+ case VK_ESCAPE:
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CHistoryUnit* pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ long lOldKey = pPianoRollFrame->YtoKey (m_ptMouseMove.y);
+ switch (m_lTempTool) {
+ // ペン
+ case ID_PIANOROLL_PEN:
+ if (m_lTempMode == 0x0101 && m_pTempEvent != NULL) {
+ ASSERT (m_pTempTrack);
+ // 置こうとしているノート廃止
+ MIDIEvent_Delete (m_pTempEvent);
+ m_pTempEvent = NULL;
+ // 履歴記録
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ // 古いキー消音
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ BYTE byMIDIMessage[3];
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ ReleaseCapture ();
+ KillTimer (0x21);
+ m_lTempMode = 0;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ break;
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ break;
+ // Control
+ case VK_CONTROL:
+ if (1) {
+ WORD wX = (WORD)(m_ptMouseMove.x - pPianoRollFrame->GetTimeScrollPos ());
+ WORD wY = (WORD)(m_ptMouseMove.y - pPianoRollFrame->GetKeyScrollPos ());
+ UINT nFlags = m_nMouseMoveFlags | MK_CONTROL;
+ PostMessage (WM_MOUSEMOVE, (WPARAM)nFlags, (LPARAM)((wY << 16) | wX));
+ }
+ break;
+ // デフォルト
+ default:
+ pPianoRollFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+
+// キーが離された時
+void CPianoRollKeyTimeView::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ switch (nChar) {
+ // Control
+ case VK_CONTROL:
+ if (1) {
+ WORD wX = (WORD)(m_ptMouseMove.x - pPianoRollFrame->GetTimeScrollPos ());
+ WORD wY = (WORD)(m_ptMouseMove.y - pPianoRollFrame->GetKeyScrollPos ());
+ UINT nFlags = m_nMouseMoveFlags & (~MK_CONTROL);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)nFlags, (LPARAM)((wY << 16) | wX));
+ }
+ break;
+ }
+ return;
+}
+
+// マウス左ボタン押された時
+void CPianoRollKeyTimeView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ point += sizWndOrg;
+ ASSERT (m_pTempEvent == NULL);
+ ASSERT (m_lTempMode == 0);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempKey = pPianoRollFrame->YtoKey (point.y);
+ m_lTempTime = pPianoRollFrame->XtoTime (point.x);
+ m_lTempTool = pPianoRollFrame->m_lCurTool;
+ m_lTempChannel = pPianoRollFrame->GetCurChannel ();
+ m_lTempChannel = CLIP (0, m_lTempChannel, 15);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempVelocity = CLIP (1, m_lTempVelocity, 127);
+ m_lTempDuration = pPianoRollFrame->GetCurDuration ();
+ m_lTempDuration = CLIP (1, m_lTempDuration, 65535);
+ m_lTempSnap = pPianoRollFrame->GetCurSnap ();
+ m_lTempSnap = CLIP (1, m_lTempSnap, MIDIData_GetTimeResolution (pMIDIData));
+ m_pTempEvent = NULL;
+ m_pLastEvent = NULL;
+ CRect rcRegion;
+ BOOL bPtInNote = FALSE;
+ CRect rcNote;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ BYTE byMIDIMessage[3];
+ long i = 0;
+ switch (m_lTempTool) {
+ // ペン
+ case ID_PIANOROLL_PEN:
+ // フォーマット1のMIDIデータで最初のトラックにノートを置くのを禁止
+ if (lFormat == 1 && m_lTempTrackIndex == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ // 既存のノートの上にマウスが置かれた場合
+ i = MIDIData_CountTrack (pMIDIData) - 1; // 20090629追加
+ forEachTrackInverse (pMIDIData, pTempTrack) { // 20090629修正
+ long lPort = MIDITrack_GetOutputPort (pTempTrack);
+ if (0 <= lPort && lPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[lPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[lPort];
+ }
+ if (pPianoRollFrame->IsTrackVisible (i)) { // 20090629修正
+ forEachEventInverse (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) && MIDIEvent_IsNote (pTempEvent)) {
+ CRect rcNote = GetNoteRect (pTempEvent);
+ if (rcNote.top <= point.y && point.y <= rcNote.bottom) {
+ // 長方形の左辺上をクリック
+ if (rcNote.left <= point. x && point.x < rcNote.left + rcNote.Width () / 4) {
+ pPianoRollFrame->SetCurTrackIndex (i);
+ pPianoRollFrame->SetCurVelocity (MIDIEvent_GetVelocity (pTempEvent));
+ pPianoRollFrame->SetCurDuration (MIDIEvent_GetDuration (pTempEvent));
+ pPianoRollFrame->SetCurChannel (MIDIEvent_GetChannel (pTempEvent));
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempDuration = pPianoRollFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (pTempTrack); // 20100226修正
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) { // 20100226追加
+ m_lTempChannel = pPianoRollFrame->GetCurChannel (); // 20100226追加
+ } // 20100226追加
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (pTempEvent);
+ m_lTempMode = 0x0103;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ m_pTempEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ InvalidateRect (rcRegion - sizWndOrg);
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ // 長方形の右辺上をクリック
+ else if (rcNote.right - rcNote.Width () / 4 < point. x && point.x <= rcNote.right) {
+ pPianoRollFrame->SetCurTrackIndex (i);
+ pPianoRollFrame->SetCurVelocity (MIDIEvent_GetVelocity (pTempEvent));
+ pPianoRollFrame->SetCurDuration (MIDIEvent_GetDuration (pTempEvent));
+ pPianoRollFrame->SetCurChannel (MIDIEvent_GetChannel (pTempEvent));
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempDuration = pPianoRollFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (pTempTrack); // 20100226修正
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) { // 20100226追加
+ m_lTempChannel = pPianoRollFrame->GetCurChannel (); // 20100226追加
+ } // 20100226追加
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (pTempEvent);
+ m_lTempMode = 0x0104;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ m_pTempEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ InvalidateRect (rcRegion - sizWndOrg);
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ // 長方形の内部をクリック
+ else if (rcNote.left <= point. x && point.x <= rcNote.right) {
+ pPianoRollFrame->SetCurTrackIndex (i);
+ pPianoRollFrame->SetCurVelocity (MIDIEvent_GetVelocity (pTempEvent));
+ pPianoRollFrame->SetCurDuration (MIDIEvent_GetDuration (pTempEvent));
+ pPianoRollFrame->SetCurChannel (MIDIEvent_GetChannel (pTempEvent));
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempDuration = pPianoRollFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (pTempTrack); // 20100226修正
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) { // 20100226追加
+ m_lTempChannel = pPianoRollFrame->GetCurChannel (); // 20100226追加
+ } // 20100226追加
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (pTempEvent);
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, m_lTempKey + MIDITrack_GetKeyPlus (pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ m_lTempMode = 0x0102;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ m_pTempEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ InvalidateRect (rcRegion - sizWndOrg);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ }
+ }
+ }
+ if (m_lTempMode != 0) {
+ break;
+ }
+ }
+ i--;
+ }
+ // 何もないところにマウスが置かれた場合
+ if (m_pTempEvent == NULL) {
+ if (MIDIData_GetFormat (pMIDIData) == 1 &&
+ m_pTempTrack == MIDIData_GetFirstTrack (pMIDIData)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ if (pPianoRollFrame->IsTrackVisible (m_lTempTrackIndex) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (m_lTempTrackIndex);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ m_lTempTime = (m_lTempTime / m_lTempSnap) * m_lTempSnap;
+ m_lTempTimeNoteOn = m_lTempTime;
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ m_pTempEvent = MIDIEvent_CreateNote
+ (m_lTempTime, m_lTempChannel, m_lTempKey, m_lTempVelocity, m_lTempDuration);
+ if (m_pTempEvent == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_ANY_MORE_BEACUSE_OF_INSUFFICIENT_MEMORY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ MIDITrack_InsertEvent (m_pTempTrack, m_pTempEvent);
+ m_lTempMode = 0x0101;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, m_lTempKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ rcRegion = GetNoteRect (m_pTempEvent);
+ InvalidateRect (rcRegion - sizWndOrg);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ }
+ break;
+ // 線
+ case ID_PIANOROLL_LINE:
+ if (MIDIData_GetFormat (pMIDIData) == 1 &&
+ m_pTempTrack == MIDIData_GetFirstTrack (pMIDIData)) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ if (pPianoRollFrame->IsTrackVisible (m_lTempTrackIndex) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (m_lTempTrackIndex);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ m_lTempTime = (m_lTempTime / m_lTempSnap) * m_lTempSnap;
+ m_lTempTimeNoteOn = m_lTempTime;
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, m_lTempKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ ::SetCursor (pSekaijuApp->m_hCursorLine);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ m_lTempMode = 0x0201;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ // フォーマット1のMIDIデータで最初のトラックにノートを消すのを禁止
+ if (lFormat == 1 && m_lTempTrackIndex == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_DELETE_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ m_pTempEvent = NULL;
+ m_lTempMode = 0x0301;
+ // 既存のノートの上にマウスが置かれたか調べる
+ bPtInNote = FALSE;
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEventInverse (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) && MIDIEvent_IsNote (pTempEvent)) {
+ CRect rcNote = GetNoteRect (pTempEvent);
+ // 既存のノートの上をクリックした場合
+ if (rcNote.top <= point.y && point.y <= rcNote.bottom &&
+ rcNote.left <= point.x && point. x<= rcNote.right) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ rcRegion = rcNote - sizWndOrg;
+ InvalidateRect (rcRegion);
+ bPtInNote = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (bPtInNote) {
+ break;
+ }
+ i++;
+ }
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ bPtInNote = FALSE;
+ i = 0;
+ // 既存の選択されているノートの上にマウスが置かれたか調べる
+ forEachTrack (pMIDIData, pTempTrack) {
+ long lPort = MIDITrack_GetOutputPort (pTempTrack);
+ if (0 <= lPort && lPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[lPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[lPort];
+ }
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) && MIDIEvent_IsNote (pTempEvent) &&
+ pSekaijuDoc->IsEventSelected (pTempEvent)) {
+ rcNote = GetNoteRect (pTempEvent);
+ if (rcNote.top <= point.y && point.y <= rcNote.bottom &&
+ rcNote.left <= point.x && point. x<= rcNote.right) {
+ bPtInNote = TRUE;
+ break;
+ }
+ }
+ }
+ if (bPtInNote) {
+ break;
+ }
+ }
+ i++;
+ }
+ // 既存の選択されているノートの上にマウスが置かれた場合(複写又は移動モード)
+ if (bPtInNote) {
+ pPianoRollFrame->SetCurTrackIndex (i);
+ pPianoRollFrame->SetCurVelocity (MIDIEvent_GetVelocity (pTempEvent));
+ pPianoRollFrame->SetCurDuration (MIDIEvent_GetDuration (pTempEvent));
+ pPianoRollFrame->SetCurChannel (MIDIEvent_GetChannel (pTempEvent));
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempDuration = pPianoRollFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (pTempTrack); // 20100226修正
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) { // 20100226追加
+ m_lTempChannel = pPianoRollFrame->GetCurChannel (); // 20100226追加
+ } // 20100226追加
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (pTempEvent);
+ m_lTempNoteDuration = MIDIEvent_GetDuration (pTempEvent);
+ m_pTempEvent = pTempEvent;
+ m_theTempSelectedEventArray.RemoveAll ();
+ // 複写の場合(CONTROLが押されている)
+ if (nFlags & MK_CONTROL) {
+ VERIFY (strHistoryName.LoadString (IDS_DUPLICATE_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ i = 0; //20080902追加
+ forEachTrack (pMIDIData, pTempTrack) { //20080902修正
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ // このトラックのEndofTrackイベントを履歴記録
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ // 選択ノートイベントの複写
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ pSekaijuDoc->IsEventSelected (pTempEvent) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ // 選択されたノートオンを非選択状態にする。
+ MIDIEvent* pCloneEvent = NULL;
+ pCloneEvent = pSekaijuDoc->SelectEvent (pTempEvent, 0, pCurHistoryUnit);
+ if (pCloneEvent == NULL) {
+ continue;
+ }
+ // ノートオンを複写し、複写した方を選択状態にする。
+ pCloneEvent = pSekaijuDoc->DuplicateMIDIEvent (pCloneEvent);
+ if (pCloneEvent) {
+ pCloneEvent->m_lUser1 = MIDIEvent_GetKey (pCloneEvent);
+ pCloneEvent->m_lUser2 = MIDIEvent_GetTime (pCloneEvent);
+ pCloneEvent->m_lUser3 = MIDIEvent_GetDuration (pCloneEvent);
+ pSekaijuDoc->SetEventSelected (pCloneEvent, 1);
+ m_theTempSelectedEventArray.Add (pCloneEvent);
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ i++;
+ }
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAllCopy);
+ m_lTempMode = 0x0403;
+ }
+ // 移動の場合(CONTROLが押されていない)
+ else {
+ VERIFY (strHistoryName.LoadString (IDS_MOVE_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ i = 0; //20080902追加
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ pSekaijuDoc->IsEventSelected (pTempEvent) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDIEvent* pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ if (pCloneEvent) {
+ pCloneEvent->m_lUser1 = MIDIEvent_GetKey (pCloneEvent);
+ pCloneEvent->m_lUser2 = MIDIEvent_GetTime (pCloneEvent);
+ pCloneEvent->m_lUser3 = MIDIEvent_GetDuration (pCloneEvent);
+ m_theTempSelectedEventArray.Add (pCloneEvent);
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ i++;
+ }
+ // 長方形の左辺上をクリック(開始時刻の移動)
+ if (rcNote.left <= point.x && point.x < rcNote.left + rcNote.Width () / 4) {
+ m_lTempMode = 0x0406;
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+ // 長方形の右辺上をクリック(終了時刻の移動)
+ else if (rcNote.right - rcNote.Width() / 4 <= point.x && point.x < rcNote.right) {
+ m_lTempMode = 0x0407;
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+ // 長方形の中央部をクリック(移動)
+ else {
+ m_lTempMode = 0x0402;
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ }
+ // 移動又は複写の場合のみ音だし
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, m_lTempKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ rcRegion = GetNoteRect (m_pTempEvent);
+ InvalidateRect (rcRegion - sizWndOrg);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+
+ }
+ // 何もないところにマウスが置かれた場合(選択範囲モード)
+ else {
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+ m_lTempMode = 0x0401;
+ dc.SetROP2 (R2_NOT);
+ dc.SetPixel (point, RGB (0, 0, 0));
+ dc.SetROP2 (R2_COPYPEN);
+ ::SetCursor (pSekaijuApp->m_hCursorSelect);
+ Invalidate ();
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ }
+ break;
+
+ // スクラブ
+ case ID_PIANOROLL_SPEAKER:
+ if (pSekaijuApp->m_bPlaying) {
+ pPianoRollFrame->SendMessage (WM_COMMAND, (WPARAM)ID_CONTROL_PLAY, (LPARAM)0);
+ }
+ if (pSekaijuApp->m_thePianoRollOption.m_bSpeakerModeVisibleTrack) {
+ long i = 0;
+ long lTempOutputOn[MAXMIDITRACKNUM];
+ forEachTrack (pMIDIData, pTempTrack) {
+ lTempOutputOn[i] = MIDITrack_GetOutputOn (pTempTrack);
+ MIDITrack_SetOutputOn (pTempTrack, pPianoRollFrame->IsTrackVisible (i));
+ i++;
+ }
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ MIDITrack_SetOutputOn (pTempTrack, lTempOutputOn[i]);
+ i++;
+ }
+ }
+ else {
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ }
+ m_lTempMode = 0x0501;
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CPianoRollKeyTimeView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // マウスキャプター中は何もしない
+ if (GetCapture () == this) {
+ return;
+ }
+
+ // 他の操作中は何もしない
+ if (m_lTempMode != 0x0000) {
+ return;
+ }
+
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ point += sizWndOrg;
+ ASSERT (m_pTempEvent == NULL);
+ ASSERT (m_lTempMode == 0);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ m_pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempKey = pPianoRollFrame->YtoKey (point.y);
+ m_lTempTime = pPianoRollFrame->XtoTime (point.x);
+ m_lTempTool = pPianoRollFrame->m_lCurTool;
+ m_lTempChannel = pPianoRollFrame->GetCurChannel ();
+ m_lTempChannel = CLIP (0, m_lTempChannel, 15);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempVelocity = CLIP (1, m_lTempVelocity, 127);
+ m_lTempDuration = pPianoRollFrame->GetCurDuration ();
+ m_lTempDuration = CLIP (1, m_lTempDuration, 65535);
+ m_lTempSnap = pPianoRollFrame->GetCurSnap ();
+ m_lTempSnap = CLIP (1, m_lTempSnap, MIDIData_GetTimeResolution (pMIDIData));
+ m_pTempEvent = NULL;
+ m_pLastEvent = NULL;
+ CRect rcRegion;
+ BOOL bPtInNote = FALSE;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ // 既存のノートの上にマウスが置かれた場合
+ long i = MIDIData_CountTrack (pMIDIData) - 1; // 20090629修正
+ forEachTrackInverse (pMIDIData, pTempTrack) { // 20090629修正
+ long lPort = MIDITrack_GetOutputPort (pTempTrack);
+ if (0 <= lPort && lPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[lPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[lPort];
+ }
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEventInverse (pTempTrack, pTempEvent) { // 20090629修正
+ if (MIDIEvent_IsNoteOn (pTempEvent) && MIDIEvent_IsNote (pTempEvent)) {
+ CRect rcNote = GetNoteRect (pTempEvent);
+ // 長方形の内部をクリック
+ if (rcNote.top <= point.y && point.y <= rcNote.bottom) {
+ if (rcNote.left <= point. x && point.x <= rcNote.right) {
+ //pPianoRollFrame->SetCurTrackIndex (i);
+ //pPianoRollFrame->SetCurVelocity (MIDIEvent_GetVelocity (pTempEvent));
+ //pPianoRollFrame->SetCurDuration (MIDIEvent_GetDuration (pTempEvent));
+ //pPianoRollFrame->SetCurChannel (MIDIEvent_GetChannel (pTempEvent));
+ m_lTempTrackIndex = i;
+ m_pTempTrack = pSekaijuDoc->GetTrack (i);
+ m_lTempOutputPort = MIDITrack_GetOutputPort (m_pTempTrack);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempDuration = pPianoRollFrame->GetCurDuration ();
+ m_lTempChannel = MIDITrack_GetOutputChannel (pTempTrack); // 20110115修正
+ if (m_lTempChannel < 0 || m_lTempChannel >= 16) { // 20110115追加
+ m_lTempChannel = pPianoRollFrame->GetCurChannel (); // 20110115追加
+ } // 20110115追加
+ m_lTempTimeNoteOn = MIDIEvent_GetTime (pTempEvent);
+ m_pTempEvent = pTempEvent;
+ break;
+ }
+ }
+ }
+ }
+ if (m_pTempEvent) {
+ break;
+ }
+ }
+ i--; // 20090629修正
+ }
+ m_lTempMode = 0x1001;
+
+ ShowPopupMenu (ptMenu);
+
+ m_pTempEvent = NULL;
+ m_lTempMode = 0x0000;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス左ボタン離されたとき
+void CPianoRollKeyTimeView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ point += sizWndOrg;
+
+ long lDownKey = pPianoRollFrame->YtoKey (m_ptMouseDown.y);
+ long lOldKey = pPianoRollFrame->YtoKey (m_ptMouseMove.y);
+ long lNewKey = pPianoRollFrame->YtoKey (point.y);
+ long lDownTime = pPianoRollFrame->XtoTime (m_ptMouseDown.x);
+ long lOldTime = pPianoRollFrame->XtoTime (m_ptMouseMove.x);
+ long lNewTime = pPianoRollFrame->XtoTime (point.x);
+ long lStartKey = MIN (lDownKey, lNewKey);
+ long lEndKey = MAX (lDownKey, lNewKey);
+ long lStartTime = MIN (lDownTime, lNewTime);
+ long lEndTime = MAX (lDownTime, lNewTime);
+ long i = 0;
+ CRect rcRegion;
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ BYTE byMIDIMessage[3];
+ switch (m_lTempTool) {
+ // ペン
+ case ID_PIANOROLL_PEN:
+ ASSERT (m_pTempTrack);
+ ASSERT (m_pTempEvent);
+ ASSERT (m_lTempMode);
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 音符挿入中又は音符移動中の場合に限り
+ if (m_lTempMode == 0x0101 || m_lTempMode == 0x0102) {
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ // 履歴記録
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pTempEvent);
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ break;
+ // 線
+ case ID_PIANOROLL_LINE:
+ ASSERT (m_pTempTrack);
+ ASSERT (m_lTempMode);
+ if (m_lTempMode == 0x0201) {
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_NOTE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // EOT処理
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ // ノートイベントの挿入
+ long lKey = 0;
+ long lStartTime2 = 0;
+ long lEndTime2 = 0;
+ long lDur = 0;
+ long lCh = m_lTempChannel & 0x0F;
+ long lVel = CLIP (1, m_lTempVelocity, 127);
+ // 垂直線の場合
+ if (lEndTime == lStartTime) {
+ ;
+ }
+ // 水平線の場合
+ else if (lEndKey == lStartKey) {
+ lDur = lEndTime - lStartTime;
+ MIDIEvent* pNewEvent = MIDIEvent_CreateNote
+ (lStartTime, lCh, lKey, lVel, lDur);
+ if (pNewEvent) {
+ MIDITrack_InsertEvent (m_pTempTrack, pNewEvent);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ }
+ }
+ // 左下→右上又は右上→左下の場合
+ else if (lDownKey < lOldKey && lDownTime < lOldTime ||
+ lDownKey > lOldKey && lDownTime > lOldTime) {
+ for (lKey = lStartKey; lKey <= lEndKey; lKey++) {
+ lStartTime2 = lStartTime +
+ (lEndTime - lStartTime) * (lKey - lStartKey) / (lEndKey - lStartKey);
+ lEndTime2 = lStartTime +
+ (lEndTime - lStartTime) * (lKey + 1 - lStartKey) / (lEndKey - lStartKey);
+ lDur = lEndTime2 - lStartTime2;
+ MIDIEvent* pNewEvent = MIDIEvent_CreateNote
+ (lStartTime2, lCh, lKey, lVel, lDur);
+ if (pNewEvent) {
+ MIDITrack_InsertEvent (m_pTempTrack, pNewEvent);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ }
+ }
+ }
+ // 右下→左上又は左上→右下の場合
+ else if (lDownKey < lOldKey && lDownTime > lOldTime ||
+ lDownKey > lOldKey && lDownTime < lOldTime) {
+ for (lKey = lEndKey; lKey >= lStartKey; lKey--) {
+ lStartTime2 = lStartTime +
+ (lEndTime - lStartTime) * (lEndKey - lKey) / (lEndKey - lStartKey);
+ lEndTime2 = lStartTime +
+ (lEndTime - lStartTime) * (lEndKey - lKey + 1) / (lEndKey - lStartKey);
+ lDur = lEndTime2 - lStartTime2;
+ MIDIEvent* pNewEvent = MIDIEvent_CreateNote
+ (lStartTime2, lCh, lKey, lVel, lDur);
+ if (pNewEvent) {
+ MIDITrack_InsertEvent (m_pTempTrack, pNewEvent);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ }
+ }
+ }
+ // EOT処理
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ }
+ break;
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ break;
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 音符移動中又は音符複写中の場合又は開始時刻の移動中又は終了時刻の移動中
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403 || m_lTempMode == 0x0406 || m_lTempMode == 0x0407) {
+ // 各選択イベントのマウスダウン時のキー情報とタイム情報を削除
+ long j;
+ long lTempSelectedEventCount = m_theTempSelectedEventArray.GetSize ();
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pTempEvent->m_lUser1 = 0;
+ pTempEvent->m_lUser2 = 0;
+ pTempEvent->m_lUser3 = 0;
+ }
+ // 複写の場合
+ if (m_lTempMode == 0x0403) {
+ // 元の位置と同じ場合は複写しない。
+ if ((lDownKey == lNewKey) &&
+ (lDownTime / m_lTempSnap) * m_lTempSnap ==
+ (lNewTime / m_lTempSnap) * m_lTempSnap) {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ MIDIEvent_Delete (pCloneEvent);
+ }
+ }
+ // 元の位置と異なる場所に複写された場合、複写確定、履歴記録。
+ else {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ }
+ }
+ // 移動の場合、開始時刻の移動の場合、終了時刻の移動の場合
+ else if (m_lTempMode == 0x0402 || m_lTempMode == 0x0406 || m_lTempMode == 0x0407) {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ }
+ // EOTの履歴記録
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent);
+ }
+ }
+ }
+ i++;
+ }
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ }
+ // 選択範囲変更中の場合
+ else if (m_lTempMode == 0x0401) {
+ // 新規矩形内部選択(左→右へドラッグ)
+ if (m_ptMouseMove.x >= m_ptMouseDown.x) {
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ if ((MIDIEvent_IsNoteOn (pTempEvent) || MIDIEvent_IsNoteOff (pTempEvent)) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pTempEvent);
+ long lDur = MIDIEvent_GetDuration (pTempEvent);
+ if (lStartTime <= lTime && lTime <= lEndTime &&
+ lStartTime <= lTime + lDur && lTime + lDur <= lEndTime) {
+ long lKey = MIDIEvent_GetKey (pTempEvent);
+ if (lStartKey + 1 <= lKey && lKey <= lEndKey - 1) { // 2010042
+ MIDIEvent* pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+ }
+ // 新規矩形接触選択(右→左へドラッグ) // 20100503追加
+ else {
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ if ((MIDIEvent_IsNoteOn (pTempEvent) || MIDIEvent_IsNoteOff (pTempEvent)) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pTempEvent);
+ long lDur = MIDIEvent_GetDuration (pTempEvent);
+ if (lStartTime <= lTime && lTime <= lEndTime ||
+ lStartTime <= lTime + lDur && lTime + lDur <= lEndTime ||
+ lTime <= lStartTime && lEndTime <= lTime + lDur) {
+ long lKey = MIDIEvent_GetKey (pTempEvent);
+ if (lStartKey <= lKey && lKey <= lEndKey) {
+ MIDIEvent* pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+ }
+ }
+ break;
+
+ // スクラブ
+ case ID_PIANOROLL_SPEAKER:
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllSoundOff ();
+ break;
+ }
+ m_theTempSelectedEventArray.RemoveAll ();
+ m_pTempEvent = NULL;
+ m_lTempMode = 0;
+ KillTimer (0x21);
+ ReleaseCapture ();
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// マウス右ボタン離されたとき
+void CPianoRollKeyTimeView::OnRButtonUp (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+}
+
+// マウスが動かされたとき
+void CPianoRollKeyTimeView::OnMouseMove (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetKeyScrollPos ());
+ point += sizWndOrg;
+ CRect rcClient;
+ GetClientRect (&rcClient);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ long lDownKey = pPianoRollFrame->YtoKey (m_ptMouseDown.y);
+ long lOldKey = pPianoRollFrame->YtoKey (m_ptMouseMove.y);
+ long lNewKey = pPianoRollFrame->YtoKey (point.y);
+ long lDownTime = pPianoRollFrame->XtoTime (m_ptMouseDown.x);
+ long lOldTime = pPianoRollFrame->XtoTime (m_ptMouseMove.x);
+ long lNewTime = pPianoRollFrame->XtoTime (point.x);
+ CRect rcRegion;
+
+ BYTE byMIDIMessage[3];
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ // マウスが動かされていないのにこの関数が呼び出された場合は何もしない(20090629追加)
+ if (point == m_ptMouseMove) {
+ pSekaijuDoc->m_theCriticalSection.Unlock (); // 20090704修正
+ return;
+ }
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIStatus = NULL;
+ pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ if (0 <= m_lTempOutputPort && m_lTempOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempOutputPort];
+ pMIDIStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempOutputPort];
+ }
+ long i = 0;
+ BOOL bErased = FALSE;
+ // ツール別の操作
+ switch (m_lTempTool) {
+ case ID_PIANOROLL_PEN:
+ ASSERT (m_pTempTrack);
+ ASSERT (m_pTempEvent);
+ ASSERT (m_lTempMode);
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 音符移動中
+ if (m_lTempMode == 0x0101 || m_lTempMode == 0x0102) {
+ // キーが変わった場合
+ if (lOldKey != lNewKey) {
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // 新しいキーを設定
+ MIDIEvent_SetKey (m_pTempEvent, CLIP (0, lNewKey, 127));
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ // 新しいキー発音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lNewKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ // 時刻が変わった場合
+ if ((lOldTime / m_lTempSnap) * m_lTempSnap !=
+ (lNewTime / m_lTempSnap) * m_lTempSnap) {
+ long lDeltaTime =
+ (lNewTime / m_lTempSnap) * m_lTempSnap -
+ (lOldTime / m_lTempSnap) * m_lTempSnap;
+ long lCurTime = MIDIEvent_GetTime (m_pTempEvent);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ long lTempTime = CLIP (0, lCurTime + lDeltaTime, 0x7FFF0000);
+ MIDIEvent_SetTime (m_pTempEvent, lTempTime);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+ }
+ // 音符の開始時刻移動
+ else if (m_lTempMode == 0x0103) {
+ // 時刻が変わった場合(20081227修正,20120731修正)
+ if ((lOldTime + m_lTempSnap / 2) / m_lTempSnap != (lNewTime + m_lTempSnap / 2) / m_lTempSnap) {
+ long lTempTime = MIDIEvent_GetTime (m_pTempEvent);
+ long lTempDuration = MIDIEvent_GetDuration (m_pTempEvent);
+ long lDeltaTime = (lNewTime + m_lTempSnap / 2) / m_lTempSnap * m_lTempSnap - lTempTime;
+ long lTime = CLIP (0, lTempTime + lDeltaTime, 0x7FFFFFFF);
+ long lDuration = CLIP (1, lTempDuration - lDeltaTime, 65535);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ MIDIEvent_SetTime (m_pTempEvent, lTime);
+ MIDIEvent_SetDuration (m_pTempEvent, lDuration);
+ pPianoRollFrame->SetCurDuration (lDuration);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+ }
+ // 音符の終了時刻移動
+ else if (m_lTempMode == 0x0104) {
+ // 時刻が変わった場合(20081227修正,20120731修正)
+ if ((lOldTime + m_lTempSnap / 2) / m_lTempSnap != (lNewTime + m_lTempSnap / 2) / m_lTempSnap) {
+ long lTempTime = MIDIEvent_GetTime (m_pTempEvent);
+ long lTempDuration = MIDIEvent_GetDuration (m_pTempEvent);
+ long lDeltaTime = (lNewTime + m_lTempSnap / 2) / m_lTempSnap * m_lTempSnap - lTempDuration - lTempTime;
+ long lDuration = CLIP (1, lTempDuration + lDeltaTime, 65535);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ MIDIEvent_SetDuration (m_pTempEvent, lDuration);
+ pPianoRollFrame->SetCurDuration (lDuration);
+ rcRegion = GetNoteRect (m_pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+ }
+ break;
+
+ // 線
+ case ID_PIANOROLL_LINE:
+ ASSERT (m_pTempTrack);
+ ASSERT (m_lTempMode);
+ // 音符移動中
+ if (m_lTempMode == 0x0201) {
+ rcRegion = CRect (m_ptMouseDown, m_ptMouseMove);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown, point);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ // キーが変わった場合
+ if (lOldKey != lNewKey) {
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // 新しいキー発音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lNewKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ }
+ break;
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ bErased = FALSE; // 20090629追加
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 既存のノートの上にマウスが置かれた場合 */
+ i = MIDIData_CountTrack (pMIDIData) - 1;
+ forEachTrackInverse (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEventInverse (pTempTrack, pTempEvent) { // 20090629追加
+ if (MIDIEvent_IsNoteOn (pTempEvent) && MIDIEvent_IsNote (pTempEvent)) {
+ CRect rcNote = GetNoteRect (pTempEvent);
+ // 長方形の内部を通過
+ if (rcNote.top <= point.y && point.y <= rcNote.bottom &&
+ rcNote.left <= point.x && point.x <= rcNote.right) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ rcRegion = rcNote;
+ rcRegion.InflateRect (1, 1);
+ bErased = TRUE; // 20090629追加
+ InvalidateRect (rcRegion - sizWndOrg);
+ break;
+ }
+ }
+ }
+ if (bErased) { // 20090629追加
+ break;
+ }
+ }
+ i--;
+ }
+ break;
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 移動又は複写中
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403 || m_lTempMode == 0x0406 || m_lTempMode == 0x0407) {
+ long lTempSelectedEventArrayCount = m_theTempSelectedEventArray.GetSize ();
+ long i;
+ // キーが変わった場合
+ if (lOldKey != lNewKey) {
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ long lDeltaKey = lNewKey - lDownKey;
+ // 古いキー消音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lOldKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)0;
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ // 新しいキーを設定
+ for (i = 0; i < lTempSelectedEventArrayCount; i++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)m_theTempSelectedEventArray.GetAt (i);
+ rcRegion = GetNoteRect (pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ long lTempKey = pTempEvent->m_lUser1;
+ long lTargetKey = lTempKey + lDeltaKey;
+ lTargetKey = CLIP (0, lTargetKey, 127);
+ MIDIEvent_SetKey (pTempEvent, lTargetKey);
+ rcRegion = GetNoteRect (pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+ // 新しいキー発音
+ byMIDIMessage[0] = 0x90 | (m_lTempChannel & 0x0F);
+ byMIDIMessage[1] = (BYTE)CLIP (0, lNewKey + MIDITrack_GetKeyPlus (m_pTempTrack), 127);
+ byMIDIMessage[2] = (BYTE)CLIP (1, m_lTempVelocity + MIDITrack_GetVelocityPlus (m_pTempTrack), 127);
+ if (pMIDIOut) {
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMIDIMessage, 3);
+ }
+ if (pMIDIStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus, byMIDIMessage, 3);
+ }
+ }
+ }
+ // 時刻が変わった場合
+ if ((lOldTime + m_lTempSnap) / 2 / m_lTempSnap != (lNewTime + m_lTempSnap) / m_lTempSnap) {
+ for (i = 0; i < lTempSelectedEventArrayCount; i++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)m_theTempSelectedEventArray.GetAt (i);
+ rcRegion = GetNoteRect (pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ long lTempTime = pTempEvent->m_lUser2;
+ long lTempDuration = pTempEvent->m_lUser3;
+ // 移動又は複写中
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ long lDeltaTime =
+ (lNewTime + m_lTempSnap / 2) / m_lTempSnap * m_lTempSnap -
+ (lDownTime + m_lTempSnap / 2) / m_lTempSnap * m_lTempSnap;
+ long lTime = CLIP (0, lTempTime + lDeltaTime, 0x7FFFFFFF);
+ MIDIEvent_SetTime (pTempEvent, lTime);
+ }
+ // 開始時刻の移動中
+ else if (m_lTempMode == 0x0406) {
+ long lDeltaTime = (lNewTime + m_lTempSnap / 2) / m_lTempSnap * m_lTempSnap -
+ m_lTempTimeNoteOn;
+ long lTime = CLIP (0, lTempTime + lDeltaTime, 0x7FFFFFFF);
+ long lDuration = CLIP (1, lTempDuration - lDeltaTime, 65535);
+ MIDIEvent_SetTime (pTempEvent, lTime);
+ MIDIEvent_SetDuration (pTempEvent, lDuration);
+ pPianoRollFrame->SetCurDuration (lDuration);
+ }
+ // 終了時刻の移動中
+ else if (m_lTempMode == 0x0407) {
+ long lDeltaTime = (lNewTime + m_lTempSnap / 2) / m_lTempSnap * m_lTempSnap -
+ m_lTempTimeNoteOn - m_lTempNoteDuration;
+ long lDuration = CLIP (1, lTempDuration + lDeltaTime, 65535);
+ MIDIEvent_SetDuration (pTempEvent, lDuration);
+ pPianoRollFrame->SetCurDuration (lDuration);
+ }
+ rcRegion = GetNoteRect (pTempEvent);
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+ }
+ }
+ // 選択範囲移動中
+ else if (m_lTempMode = 0x0401) {
+ // 案B(選択矩形はちらつくが内部はちらつかない)
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseMove.x, m_ptMouseDown.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseMove.y, m_ptMouseMove.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseDown.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseMove.x, m_ptMouseDown.y, m_ptMouseMove.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, point.x, m_ptMouseDown.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, point.y, point.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseDown.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (point.x, m_ptMouseDown.y, point.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+ break;
+
+ // スクラブ
+ case ID_PIANOROLL_SPEAKER:
+ m_lTempTime = pPianoRollFrame->XtoTime (point.x);
+ if (pSekaijuApp->m_thePianoRollOption.m_bSpeakerModeVisibleTrack) {
+ long i = 0;
+ long lTempOutputOn[MAXMIDITRACKNUM];
+ forEachTrack (pMIDIData, pTempTrack) {
+ lTempOutputOn[i] = MIDITrack_GetOutputOn (pTempTrack);
+ MIDITrack_SetOutputOn (pTempTrack, pPianoRollFrame->IsTrackVisible (i));
+ i++;
+ }
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ MIDITrack_SetOutputOn (pTempTrack, lTempOutputOn[i]);
+ i++;
+ }
+ }
+ else {
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ }
+ break;
+ }
+ }
+ // 非キャプター中(カーソルの種類だけ変更)
+ else {
+ long i = 0;
+ BOOL bChanged = FALSE;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ switch (pPianoRollFrame->m_lCurTool) {
+ // 描画
+ case ID_PIANOROLL_PEN:
+ i = MIDIData_CountTrack (pMIDIData) - 1; // 20090629追加
+ forEachTrackInverse (pMIDIData, pMIDITrack) { // 20090629修正
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEventInverse (pMIDITrack, pMIDIEvent) { // 20090629修正
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ if (MIDIEvent_GetKey (pMIDIEvent) == lNewKey) {
+ long lNoteOnTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ long lNoteOffTime = lNoteOnTime + lDuration;
+ if (lNoteOnTime <= lNewTime && lNewTime < lNoteOnTime + lDuration / 4) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ bChanged = TRUE;
+ break;
+ }
+ else if (lNoteOnTime + lDuration / 4 <= lNewTime &&
+ lNewTime <= lNoteOffTime - lDuration / 4) {
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ bChanged = TRUE;
+ break;
+ }
+ else if (lNoteOffTime - lDuration / 4 < lNewTime && lNewTime <= lNoteOffTime) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ bChanged = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (bChanged) { // 20090629追加
+ break;
+ }
+ }
+ i--;
+ }
+ if (bChanged == FALSE) {
+ ::SetCursor (pSekaijuApp->m_hCursorDraw);
+ }
+ break;
+ // 線
+ case ID_PIANOROLL_LINE:
+ ::SetCursor (pSekaijuApp->m_hCursorLine);
+ break;
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ ::SetCursor (pSekaijuApp->m_hCursorEraser);
+ break;
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent)) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ if (MIDIEvent_GetKey (pMIDIEvent) == lNewKey) {
+ long lNoteOnTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lNoteDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ long lNoteOffTime = lNoteOnTime + MIDIEvent_GetDuration (pMIDIEvent);
+ if (lNoteOnTime <= lNewTime && lNewTime <= lNoteOffTime) {
+ // 複写
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAllCopy);
+ }
+ // 移動
+ else {
+ if (lNoteOnTime <= lNewTime && lNewTime < lNoteOnTime + lNoteDuration / 4) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+ else if (lNoteOffTime - lNoteDuration / 4 < lNewTime && lNewTime <= lNoteOffTime) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ }
+ bChanged = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+ if (!bChanged) {
+ ::SetCursor (pSekaijuApp->m_hCursorSelect);
+ }
+ break;
+ // スピーカー
+ case ID_PIANOROLL_SPEAKER:
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ break;
+ // 不明
+ default:
+ //::SetCursor (pSekaijuApp->m_hCursorArrow);
+ break;
+ }
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウスホイールが回された時
+void CPianoRollKeyTimeView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lKeyScrollPos = pPianoRollFrame->GetKeyScrollPos ();
+ long lKeyZoom = pPianoRollFrame->GetKeyZoom ();
+ lKeyScrollPos -= lKeyZoom * lDelta / WHEELDELTA;
+ pPianoRollFrame->SetKeyScrollPos (lKeyScrollPos);
+ }
+}
diff --git a/src/PianoRollKeyTimeView.h b/src/PianoRollKeyTimeView.h
new file mode 100644
index 0000000..4c2c9f6
--- /dev/null
+++ b/src/PianoRollKeyTimeView.h
@@ -0,0 +1,103 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールキータイムビュークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLKEYTIMEVIEW_H_
+#define _PIANOROLLKEYTIMEVIEW_H_
+
+class CPianoRollKeyTimeView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CPianoRollKeyTimeView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ long m_lCurTime; // 現在の描画タイム[tick]又は[サブフレーム]
+ long m_lOldTime; // 前回の描画タイム[tick]又は[サブフレーム]
+ long m_lOldX; // 前回の縦線x座標[pixel]
+ long m_lOldY1; // 前回の縦線y上座標[pixel]
+ long m_lOldY2; // 前回の縦線y下座標[pixel]
+ BOOL m_bOldDraw; // 前回縦線を描画したか?
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lTempTool; // 一時的なツール(0〜)
+ long m_lTempTrackIndex; // 一時的なトラック番号(0〜65535)
+ long m_lTempSnap; // 一時的なスナップタイム[tick]
+ long m_lTempVelocity; // 一時的なベロシティ(0〜127)
+ long m_lTempDuration; // 一時的な音長さ(0〜)[tick]
+ long m_lTempOutputPort; // 一時的な出力ポート(0〜15)
+ long m_lTempChannel; // 一時的なチャンネル(0〜15)
+ long m_lTempKey; // 一時的な音階(0〜127)
+ long m_lTempTime; // 一時的なタイム(0〜)[tick]
+ long m_lTempTimeNoteOn; // 一時的なノートオンタイム(0〜)[tick]
+ long m_lTempNoteDuration;
+ MIDITrack* m_pTempTrack; // 一時的なトラックへのポインタ
+ MIDIEvent* m_pTempEvent; // 一時的なイベントへのポインタ
+ MIDIEvent* m_pLastEvent; // 一時的な最後のイベントへのポインタ
+ long m_lTempMode; // 一時的なモード
+ CPtrArray m_theTempSelectedEventArray; // 一時的な選択されているイベントの配列
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollKeyTimeView (); // コンストラクタ
+ virtual ~CPianoRollKeyTimeView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual CRect GetNoteRect (MIDIEvent* pNoteOnEvent);
+ virtual void EraseOldLine (CDC* pDC);
+ virtual void DrawCurLine (CDC* pDC);
+ virtual BOOL ShowPopupMenu (CPoint ptMenu);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif
+
diff --git a/src/PianoRollOptionPage.cpp b/src/PianoRollOptionPage.cpp
new file mode 100644
index 0000000..9d3bf8b
--- /dev/null
+++ b/src/PianoRollOptionPage.cpp
@@ -0,0 +1,96 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールオプションページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "PianoRollOptionPage.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollOptionPage::CPianoRollOptionPage () : CPropertyPage (CPianoRollOptionPage::IDD) {
+ m_lDefKeyZoom = 0;
+ m_lDefVelZoom = 0;
+ m_lDefTimeZoom = 0;
+ m_bSpeakerModeVisibleTrack = FALSE;
+ m_lGraphLineWidth = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CPianoRollOptionPage::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_PIANOROLLOPTION_DEFKEYZOOM, m_lDefKeyZoom);
+ DDV_MinMaxInt (pDX, m_lDefKeyZoom, 4, 16);
+ DDX_Text (pDX, IDC_PIANOROLLOPTION_DEFVELZOOM, m_lDefVelZoom);
+ DDV_MinMaxInt (pDX, m_lDefVelZoom, 1, 4);
+ DDX_Text (pDX, IDC_PIANOROLLOPTION_DEFTIMEZOOM, m_lDefTimeZoom);
+ DDV_MinMaxInt (pDX, m_lDefTimeZoom, 1, 16);
+ DDX_Check (pDX, IDC_PIANOROLLOPTION_ENABLEKEYZOOMKEY, m_bEnableKeyZoomKey);
+ DDX_Check (pDX, IDC_PIANOROLLOPTION_ENABLEVELZOOMKEY, m_bEnableVelZoomKey);
+ DDX_Check (pDX, IDC_PIANOROLLOPTION_ENABLETIMEZOOMKEY, m_bEnableTimeZoomKey);
+ DDX_Radio (pDX, IDC_PIANOROLLOPTION_SPEAKERMODEALLTRACK, m_bSpeakerModeVisibleTrack);
+ DDX_Text (pDX, IDC_PIANOROLLOPTION_GRAPHLINEWIDTH, m_lGraphLineWidth);
+ DDV_MinMaxInt (pDX, m_lGraphLineWidth, 1, 4);
+}
+
+// ダイアログの初期化
+BOOL CPianoRollOptionPage::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PIANOROLLOPTION_DEFKEYZOOMSP))->SetRange (4, 16);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PIANOROLLOPTION_DEFVELZOOMSP))->SetRange (1, 4);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PIANOROLLOPTION_DEFTIMEZOOMSP))->SetRange (1, 16);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PIANOROLLOPTION_GRAPHLINEWIDTHSP))->SetRange (1, 4);
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+BEGIN_MESSAGE_MAP (CPianoRollOptionPage, CPropertyPage)
+END_MESSAGE_MAP ()
+
+
diff --git a/src/PianoRollOptionPage.h b/src/PianoRollOptionPage.h
new file mode 100644
index 0000000..a6a35d3
--- /dev/null
+++ b/src/PianoRollOptionPage.h
@@ -0,0 +1,64 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールオプションページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLOPTIONPAGE_H_
+#define _PIANOROLLOPTIONPAGE_H_
+
+class CPianoRollOptionPage : public CPropertyPage {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lDefKeyZoom; // デフォルトのキー方向拡大倍率[倍]
+ long m_lDefVelZoom; // デフォルトのベロシティ方向拡大倍率[倍]
+ long m_lDefTimeZoom; // デフォルトのタイム方向拡大倍率[倍]
+ BOOL m_bEnableKeyZoomKey; // 鍵盤方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bEnableVelZoomKey; // ベロシティ方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bEnableTimeZoomKey; // 時間方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bSpeakerModeVisibleTrack; // 可視状態のトラックを試聴する
+ long m_lGraphLineWidth; // グラフの幅[pixel]
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollOptionPage (); // コンストラクタ
+ enum {IDD = IDD_PIANOROLLOPTION};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ //afx_msg void OnChangeEnableAutoSave ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/PianoRollPrintView.cpp b/src/PianoRollPrintView.cpp
new file mode 100644
index 0000000..cbe1c80
--- /dev/null
+++ b/src/PianoRollPrintView.cpp
@@ -0,0 +1,1075 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロール印刷ビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include <afxpriv.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "PianoRollPrintView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+#define PIANOROLLPRINTVIEW_LEFTMARGIN 200
+#define PIANOROLLPRINTVIEW_RIGHTMARGIN 200
+#define PIANOROLLPRINTVIEW_TOPMARGIN 200
+#define PIANOROLLPRINTVIEW_BOTTOMMARGIN 200
+#define PIANOROLLPRINTVIEW_VELHEIGHT 256
+#define PIANOROLLPRINTVIEW_KEYHEIGHT 2560
+#define PIANOROLLPRINTVIEW_SCALEHEIGHT 100
+#define PIANOROLLPRINTVIEW_SCALEWIDTH 100
+
+
+IMPLEMENT_DYNCREATE (CPianoRollPrintView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CPianoRollPrintView, CSekaijuView)
+ ON_COMMAND (ID_FILE_PRINT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollPrintView::CPianoRollPrintView () {
+ // 印刷用文字フォントの作成(2.5ミリ)
+ CString strDefaultFontName;
+ VERIFY (strDefaultFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (25, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strDefaultFontName);
+
+}
+
+// デストラクタ
+CPianoRollPrintView::~CPianoRollPrintView () {
+ m_theFont.DeleteObject ();
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 時刻[tick]をx座標[*1/10mm]に変換する
+long CPianoRollPrintView::TimetoX (long lTime) {
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return lTime * 80 / lTimeResolution; // 4分音符を8mmと定義する。
+}
+
+// ベロシティ又は値(0〜127)をy座標[*1/10mm]に変換する。
+long CPianoRollPrintView::VeltoY (long lVel) {
+ return lVel * PIANOROLLPRINTVIEW_VELHEIGHT / 128 + 16;
+}
+
+// ピッチベンド(0〜16383)をy座標[*1/10mm]に変換する。
+long CPianoRollPrintView::PitchBendtoY (long lPitchBend) {
+ return lPitchBend * PIANOROLLPRINTVIEW_VELHEIGHT / 16384 + 16;
+}
+
+// テンポBPM(1〜256*)をy座標[*1/10mm]に変換する。
+long CPianoRollPrintView::TempoBPMtoY (long lTempoBPM) {
+ return MIN (lTempoBPM, 256) * PIANOROLLPRINTVIEW_VELHEIGHT / 256 + 16;
+}
+
+// キー(0〜127)をy座標[*1/10mm]に変換する。
+long CPianoRollPrintView::KeyToY (long lKey) {
+ return lKey * PIANOROLLPRINTVIEW_KEYHEIGHT / 128;
+}
+
+
+// 指定時刻にフラグとテキストを描画
+void CPianoRollPrintView::DrawFlagAndText
+(CDC* pDC, long lTime, LPCTSTR lpszText, long lColor) {
+ long x = TimetoX (lTime);
+ CRect rcBack (x, PIANOROLLPRINTVIEW_SCALEHEIGHT / 2, x + 1024, PIANOROLLPRINTVIEW_SCALEHEIGHT);
+ CRect rcFlag (x, PIANOROLLPRINTVIEW_SCALEHEIGHT * 6 / 10, x + 20, PIANOROLLPRINTVIEW_SCALEHEIGHT * 9 / 10);
+ CRect rcText (x + 30, PIANOROLLPRINTVIEW_SCALEHEIGHT / 2, x + 1024, PIANOROLLPRINTVIEW_SCALEHEIGHT);
+ CPen pen;
+ pen.CreatePen (PS_SOLID, 1, lColor);
+ CPen* pOldPen = pDC->SelectObject (&pen);
+ pDC->FillSolidRect (&rcBack, ::GetSysColor (COLOR_BTNFACE));
+ pDC->FillSolidRect (&rcFlag, lColor);
+ pDC->MoveTo (x, PIANOROLLPRINTVIEW_SCALEHEIGHT * 5 / 10);
+ pDC->LineTo (x, PIANOROLLPRINTVIEW_SCALEHEIGHT * 9 / 10);
+ pDC->SetBkMode (TRANSPARENT);
+ long lOldColor = pDC->GetTextColor ();
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->SetTextColor (lColor);
+ pDC->DrawText (lpszText, rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ pDC->SetTextColor (lOldColor);
+ pDC->SelectObject (pOldFont);
+ pDC->SelectObject (pOldPen);
+}
+
+// ベロシティ目盛り描画
+void CPianoRollPrintView::DrawVelScaleView (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+
+ // 背景グレー塗りつぶし
+ pDC->FillSolidRect (0, 0, PIANOROLLPRINTVIEW_SCALEWIDTH, PIANOROLLPRINTVIEW_VELHEIGHT + 32, lColorBtnFace);
+
+ // 目盛り横線描画
+ long i;
+ for (i = 0; i <= 8; i++) {
+ long y = PIANOROLLPRINTVIEW_VELHEIGHT * i / 8 + 16;
+ pDC->MoveTo (0, y);
+ pDC->LineTo (PIANOROLLPRINTVIEW_SCALEWIDTH, y);
+ }
+
+ // 値文字描画
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ // ベロシティ値又はチャンネルアフタータッチ値又はコントロールチェンジ値の描画(0〜64〜127)
+ if (pPianoRollFrame->GetCurGraphKind () == 1 ||
+ pPianoRollFrame->GetCurGraphKind () == 2 ||
+ pPianoRollFrame->GetCurGraphKind () >= 4) {
+ for (i = 0; i <= 8; i++) {
+ long y = PIANOROLLPRINTVIEW_VELHEIGHT * i / 8 + 16;
+ CRect rcText (PIANOROLLPRINTVIEW_SCALEWIDTH / 2 - 30, y - 10, PIANOROLLPRINTVIEW_SCALEWIDTH / 2 + 30, y + 10);
+ pDC->FillSolidRect (rcText, lColorBtnFace);
+ CString strText;
+ strText.Format (_T("%d"), CLIP (0, i * 16, 127));
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ }
+ // ピッチベンド値の描画(-8192〜0〜8191)
+ else if (pPianoRollFrame->GetCurGraphKind () == 3) {
+ for (i = 0; i <= 8; i++) {
+ long y = PIANOROLLPRINTVIEW_VELHEIGHT * i / 8 + 16;
+ CRect rcText (PIANOROLLPRINTVIEW_SCALEWIDTH / 2 - 30, y - 10, PIANOROLLPRINTVIEW_SCALEWIDTH / 2 + 30, y + 10);
+ pDC->FillSolidRect (rcText, lColorBtnFace);
+ CString strText;
+ strText.Format (_T("%d"), CLIP (-8192, (i - 4) * 2048, 8191));
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ }
+ // テンポ値の描画(0〜256)
+ else if (pPianoRollFrame->GetCurGraphKind () == 0) {
+ for (i = 0; i <= 8; i++) {
+ long y = PIANOROLLPRINTVIEW_VELHEIGHT * i / 8 + 16;
+ CRect rcText (PIANOROLLPRINTVIEW_SCALEWIDTH / 2 - 30, y - 10, PIANOROLLPRINTVIEW_SCALEWIDTH / 2 + 30, y + 10);
+ pDC->FillSolidRect (rcText, lColorBtnFace);
+ CString strText;
+ strText.Format (_T("%d"), CLIP (0, i * 32, 256));
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ }
+ pDC->SelectObject (pOldFont);
+
+}
+
+// ベロシティ-時刻グラフ描画
+void CPianoRollPrintView::DrawVelTimeView (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[1]);
+ CPen penBeat (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen penOctave (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[1]);
+
+ // MIDIデータの性質を取得
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ // ロール部の幅を計算
+ long lLastTime;
+ MIDIData_MakeTime (pMIDIData, lEndMeasure + 1, 0, 0, &lLastTime);
+ long lRollWidth;
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lFeedTime = lTimeResolution * 120;
+ lRollWidth = TimetoX (lLastTime + lFeedTime);
+ }
+ else {
+ long lFeedTime = lTimeResolution * 120;
+ lRollWidth = TimetoX (lLastTime + lFeedTime);
+ }
+
+ // 背景の描画
+ CRect rcTemp (0, 0, lRollWidth, PIANOROLLPRINTVIEW_VELHEIGHT + 32);
+ pDC->FillSolidRect (rcTemp, pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+
+ // ベロシティロール部横線
+ long i = 0;
+ for (i = 0; i <= 8; i++) {
+ long y = PIANOROLLPRINTVIEW_VELHEIGHT * i / 8 + 16;
+ CPen* pOldPen = pDC->SelectObject (i % 4 == 0 ? &penOctave : &penKey);
+ pDC->MoveTo (0, y);
+ pDC->LineTo (lRollWidth, y);
+ pDC->SelectObject (pOldPen);
+ }
+
+ // ベロシティロール部縦線
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long j;
+ for (j = 0; j < lEndMeasure + 120; j++) {
+ CPen* pOldPen;
+ // 小節線の描画
+ long lTime, lnn, ldd, lcc, lbb;
+ MIDIData_MakeTimeEx (pMIDIData, j, 0, 0, &lTime, &lnn, &ldd, &lcc, &lbb);
+ long x = TimetoX (lTime);
+ pOldPen = pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, 0);
+ pDC->LineTo (x, PIANOROLLPRINTVIEW_VELHEIGHT + 32);
+ pDC->SelectObject (pOldPen);
+ // 拍線の描画
+ pOldPen = pDC->SelectObject (&penBeat);
+ long lUnitTick = lTimeResolution * 4 / (1 << ldd);
+ for (long jj = 1; jj < lnn; jj++) {
+ long x = TimetoX (lTime + jj * lUnitTick);
+ pDC->MoveTo (x, 0);
+ pDC->LineTo (x, PIANOROLLPRINTVIEW_VELHEIGHT + 32);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ else {
+ long lEndFrameNumber = lEndTime / lTimeResolution;
+ CPen* pOldPen;
+ pOldPen = pDC->SelectObject (&penMeasure);
+ long j;
+ for (j = 0; j <= lEndFrameNumber; j++) {
+ // フレーム境界線の描画
+ long lTime = j * lTimeResolution;
+ long x = TimetoX (lTime);
+ pDC->MoveTo (x, 0);
+ pDC->LineTo (x, PIANOROLLPRINTVIEW_VELHEIGHT + 32);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+
+ // ベロシティ値
+ long lGraphLineWidth = pSekaijuApp->m_thePianoRollOption.m_lGraphLineWidth;
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ // そのトラックが可視状態であれば
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ long lOldTempo = 60000000 / 100;
+ long lOldTempoTime = 0;
+ long lTrackColor = MIDITrack_GetForeColor (pMIDITrack);
+ CPen penControl (PS_SOLID, lGraphLineWidth, lTrackColor);
+ CPen* pOldPen = NULL;
+ CPen* pLastTempoPen = NULL;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long x, y;
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ // ベロシティの描画
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (1)) {
+ pOldPen = pDC->SelectObject (&penControl);
+ x = TimetoX (lTime);
+ long lValue = MIDIEvent_GetVelocity (pMIDIEvent);
+ y = VeltoY (lValue);
+ long y0 = VeltoY (0);
+ pDC->MoveTo (x, y);
+ pDC->LineTo (x, y0);
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // チャンネルアフタータッチの描画
+ else if (MIDIEvent_IsChannelAftertouch (pMIDIEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (2)) {
+ pOldPen = pDC->SelectObject (&penControl);
+ x = TimetoX (lTime);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ y = VeltoY (lValue);
+ long y0 = VeltoY (0);
+ pDC->MoveTo (x, y);
+ pDC->LineTo (x, y0);
+ if (lValue == 0) {
+ pDC->Ellipse (x - 5, y0 - 5, x + 5, y0 + 5);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // ピッチベンドの描画
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (3)) {
+ pOldPen = pDC->SelectObject (&penControl);
+ x = TimetoX (lTime);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ y = PitchBendtoY (lValue);
+ long yc = PitchBendtoY (8192);
+ pDC->MoveTo (x, y);
+ pDC->LineTo (x, yc);
+ if (lValue == 8192) {
+ pDC->Ellipse (x - 5, yc - 5, x + 5, yc + 5);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // コントロールチェンジの描画
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ if (pPianoRollFrame->IsGraphVisible (4 + lNumber)) {
+ pOldPen = pDC->SelectObject (&penControl);
+ x = TimetoX (lTime);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ y = VeltoY (lValue);
+ long y0 = VeltoY (0);
+ pDC->MoveTo (x, y);
+ pDC->LineTo (x, y0);
+ if (lValue == 0) {
+ pDC->Ellipse (x - 5, y0 - 5, x + 5 , y0 + 5);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // テンポの描画(トラック0のみ)
+ if (MIDIEvent_IsTempo (pMIDIEvent) && i == 0) {
+ if (pPianoRollFrame->IsGraphVisible (0)) {
+ pOldPen = pDC->SelectObject (&penControl);
+ x = TimetoX (lTime);
+ long xold = TimetoX (lOldTempoTime);
+ long lValue = MIDIEvent_GetTempo (pMIDIEvent);
+ lValue = CLIP (1, lValue, 60000000);
+ y = TempoBPMtoY (60000000 / lValue);
+ long yold = TempoBPMtoY (60000000 / lOldTempo);
+ pDC->MoveTo (xold, yold);
+ pDC->LineTo (x, yold);
+ pDC->LineTo (x, y);
+ lOldTempo = lValue;
+ lOldTempoTime = lTime;
+ pLastTempoPen = pDC->SelectObject (pOldPen);
+ }
+ }
+ }
+
+ // テンポの最終横線を描画する(トラック0のみ)
+ if (pPianoRollFrame->IsGraphVisible (0) && i == 0) {
+ if (pLastTempoPen) {
+ pOldPen = pDC->SelectObject (pLastTempoPen);
+ }
+ else {
+ pOldPen = pDC->SelectObject (&penControl);
+ }
+ long lTime = MIDIData_GetEndTime (pMIDIData);
+ long x = TimetoX (lTime);
+ long xold = TimetoX (lOldTempoTime);
+ long yold = TempoBPMtoY (60000000 / lOldTempo);
+ pDC->MoveTo (xold, yold);
+ pDC->LineTo (x, yold);
+ pDC->SelectObject (pOldPen);
+ }
+
+ }
+ i++;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+
+}
+
+// 鍵盤目盛り描画
+void CPianoRollPrintView::DrawKeyScaleView (CDC* pDC) {
+
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+
+ // 文字背景色を透明に
+ pDC->SetBkMode (TRANSPARENT);
+
+ // 鍵盤部描画
+ long w = PIANOROLLPRINTVIEW_SCALEWIDTH;
+ long lKeyZoom = PIANOROLLPRINTVIEW_KEYHEIGHT / 128;
+ long i = 0;
+ // 10オクターブループ
+ for (i = 0; i < 11; i++) {
+ long lOctY = 12 * i * lKeyZoom;
+ // 白鍵と白鍵の間の線
+ pDC->MoveTo (0, lOctY + lKeyZoom * 0);
+ pDC->LineTo (w, lOctY + lKeyZoom * 0);
+ pDC->MoveTo (0, lOctY + lKeyZoom * 3 / 2);
+ pDC->LineTo (w, lOctY + lKeyZoom * 3 / 2);
+ pDC->MoveTo (0, lOctY + lKeyZoom * 7 / 2);
+ pDC->LineTo (w, lOctY + lKeyZoom * 7 / 2);
+ pDC->MoveTo (0, lOctY + lKeyZoom * 5);
+ pDC->LineTo (w, lOctY + lKeyZoom * 5);
+ pDC->MoveTo (0, lOctY + lKeyZoom * 13 / 2);
+ pDC->LineTo (w, lOctY + lKeyZoom * 13 / 2);
+ pDC->MoveTo (0, lOctY + lKeyZoom * 17 / 2);
+ pDC->LineTo (w, lOctY + lKeyZoom * 17 / 2);
+ pDC->MoveTo (0, lOctY + lKeyZoom * 21 / 2);
+ pDC->LineTo (w, lOctY + lKeyZoom * 21 / 2);
+ // 黒鍵部分塗りつぶし
+ pDC->FillSolidRect
+ (0, lOctY + lKeyZoom * 1, w * 2 / 4, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, lOctY + lKeyZoom * 3, w * 2 / 4, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, lOctY + lKeyZoom * 6, w * 2 / 4, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, lOctY + lKeyZoom * 8, w * 2 / 4, lKeyZoom, RGB (0, 0, 0));
+ pDC->FillSolidRect
+ (0, lOctY + lKeyZoom * 10, w * 2 / 4, lKeyZoom, RGB (0, 0, 0));
+ }
+ //pDC->MoveTo (0, 0);
+ //pDC->LineTo (0, m_nKeyZoom * 128);
+ //pDC->MoveTo (w - 1, 0);
+ //pDC->LineTo (w - 1, m_nKeyZoom * 128);
+
+ // 鍵盤文字描画
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ for (i = 0; i < 11; i++) {
+ long lOctY = 12 * i * lKeyZoom;
+ CRect rcText;
+ rcText.left = w * 1 / 2;
+ rcText.right = w;
+ rcText.top = lOctY + lKeyZoom / 2 - 10;
+ rcText.bottom = lOctY + lKeyZoom / 2 + 10;
+ pDC->FillSolidRect (rcText, lColorWhite);
+ CString strText;
+ strText.Format (_T("%d"), i * 12);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ pDC->SelectObject (pOldFont);
+
+
+}
+
+// 鍵盤-時刻グラフ描画
+void CPianoRollPrintView::DrawKeyTimeView (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[1]);
+ CPen penBeat (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen penOctave (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[1]);
+
+ // MIDIデータの性質を取得
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ // ロール部の幅を計算
+ long lLastTime;
+ MIDIData_MakeTime (pMIDIData, lEndMeasure + 1, 0, 0, &lLastTime);
+ long lRollWidth;
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lFeedTime = lTimeResolution * 120;
+ lRollWidth = TimetoX (lLastTime + lFeedTime);
+ }
+ else {
+ long lFeedTime = lTimeResolution * 120;
+ lRollWidth = TimetoX (lLastTime + lFeedTime);
+ }
+
+ // 鍵盤ロール部横線
+ long lKeyZoom = PIANOROLLPRINTVIEW_KEYHEIGHT / 128;
+ long i;
+ for (i = 0; i <= 127; i++) {
+ //if (i % 12 == 1 || i % 12 == 3 || i % 12 == 6 || i % 12 == 8 || i % 12 == 10) {
+ // pDC->FillSolidRect (0, i * lKeyZoom, lRollWidth, lKeyZoom, RGB (255, 255, 200));
+ //}
+ long y = i * lKeyZoom;
+ // 黒鍵部の塗り潰し
+ long temp = i % 12;
+ if (temp == 1 || temp == 3 || temp == 6 || temp == 8 || temp == 10) {
+ pDC->FillSolidRect (0, y, lRollWidth, -lKeyZoom,
+ pSekaijuApp->m_theColorOption.m_lBackColor[1]);
+ }
+ // 白鍵部の塗り潰し
+ else {
+ pDC->FillSolidRect (0, y, lRollWidth, -lKeyZoom,
+ pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+ }
+
+ CPen* pOldPen = pDC->SelectObject (i % 12 == 0 ? &penOctave : &penKey);
+ pDC->MoveTo (0, i * lKeyZoom);
+ pDC->LineTo (lRollWidth , i * lKeyZoom);
+ pDC->SelectObject (pOldPen);
+ }
+
+ // 鍵盤ロール部縦線
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long j;
+ for (j = 0; j < lEndMeasure + 120; j++) {
+ CPen* pOldPen;
+ // 小節線の描画
+ long lTime, lnn, ldd, lcc, lbb;
+ MIDIData_MakeTimeEx (pMIDIData, j, 0, 0, &lTime, &lnn, &ldd, &lcc, &lbb);
+ long x = TimetoX (lTime);
+ pOldPen = pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, 0);
+ pDC->LineTo (x, PIANOROLLPRINTVIEW_KEYHEIGHT);
+ pDC->SelectObject (pOldPen);
+ // 拍線の描画
+ pOldPen = pDC->SelectObject (&penBeat);
+ long lUnitTick = lTimeResolution * 4 / (1 << ldd);
+ for (long jj = 1; jj < lnn; jj++) {
+ long x = TimetoX (lTime + jj * lUnitTick);
+ pDC->MoveTo (x, 0);
+ pDC->LineTo (x, PIANOROLLPRINTVIEW_KEYHEIGHT);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ else {
+ long lEndFrameNumber = lEndTime / lTimeResolution;
+ CPen* pOldPen;
+ pOldPen = pDC->SelectObject (&penMeasure);
+ long j;
+ for (j = 0; j <= lEndFrameNumber; j++) {
+ // フレーム境界線の描画
+ long lTime = j * lTimeResolution;
+ long x = TimetoX (lTime);
+ pDC->MoveTo (x, 0);
+ pDC->LineTo (x, PIANOROLLPRINTVIEW_KEYHEIGHT);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+
+ // ロール部音符バー
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ long lForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ long lNoteOnTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ long lNoteOffTime = lNoteOnTime + lDuration;
+ long lKey = MIDIEvent_GetKey (pMIDIEvent);
+ long x1 = TimetoX (lNoteOnTime);
+ long x2 = TimetoX (lNoteOffTime);
+ long y1 = lKey * lKeyZoom;
+ long y2 = (lKey + 1) * lKeyZoom;
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lForeColor);
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorWhite);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorWhite);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBlack);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBlack);
+ }
+ }
+ }
+ i++;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+
+// 目盛り描画
+void CPianoRollPrintView::DrawScaleView (CDC* pDC) {
+ // 左上余白部塗りつぶし
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (0, 0, PIANOROLLPRINTVIEW_SCALEWIDTH, PIANOROLLPRINTVIEW_SCALEHEIGHT, lColorBtnFace);
+}
+
+// 時刻目盛り描画
+void CPianoRollPrintView::DrawTimeScaleView (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+
+ // MIDIデータの性質を取得
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ // ロール部の幅を計算
+ long lLastTime;
+ MIDIData_MakeTime (pMIDIData, lEndMeasure + 1, 0, 0, &lLastTime);
+ long lRollWidth;
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lFeedTime = lTimeResolution * 120;
+ lRollWidth = TimetoX (lLastTime + lFeedTime);
+ }
+ else {
+ long lFeedTime = lTimeResolution * 120;
+ lRollWidth = TimetoX (lLastTime + lFeedTime);
+ }
+
+ // 文字背景色を透明に
+ pDC->SetBkMode (TRANSPARENT);
+
+ // 時刻ロール部文字
+ pDC->FillSolidRect (0, 0, lRollWidth, PIANOROLLPRINTVIEW_SCALEHEIGHT, lColorBtnFace);
+ long lOldTime = 0;
+ CString strText1;
+ CString strText2;
+ pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ if (pMIDITrack) {
+ long lColorTrack1 = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ // テンポ
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ strText1.Format (_T("%1.2lf"), (double)60000000 / (double)lTempo);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 拍子記号
+ else if (MIDIEvent_IsTimeSignature (pMIDIEvent)) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ strText1.Format (_T("%d/%d"), lnn, 1 << ldd);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 調性記号
+ else if (MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ strText1.Format (_T("%d%s"), labs (lsf), lsf >= 0 ? "#" : "b");
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // マーカー
+ else if (MIDIEvent_IsMarker (pMIDIEvent)) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIEvent_GetText (pMIDIEvent, szBuf, TSIZEOF (szBuf) - 1);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += szBuf;
+ lOldTime = lTime;
+ }
+ }
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ }
+
+ // 時刻目盛部
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long j;
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ for (j = 0; j < lEndMeasure + 120; j++) {
+ long lLeftTime;
+ long lRightTime;
+ MIDIData_MakeTime (pMIDIData, j, 0, 0, &lLeftTime);
+ MIDIData_MakeTime (pMIDIData, j + 1, 0, 0, &lRightTime);
+ long x1 = TimetoX (lLeftTime);
+ long x2 = TimetoX (lRightTime);
+ long y1 = 0;
+ long y2 = PIANOROLLPRINTVIEW_SCALEHEIGHT / 2;
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ CString strText;
+ strText.Format (_T("%d"), j + 1);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ pDC->SelectObject (pOldFont);
+ }
+ else {
+ long lEndFrameNumber = lEndTime / lTimeResolution;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 印刷時
+void CPianoRollPrintView::OnPrint (CDC* pDC, CPrintInfo* pInfo) {
+
+ pDC->SetMapMode (MM_LOMETRIC);
+ CPoint ptWindowOrg (0, 0);
+
+ long lLeftMargin = PIANOROLLPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = PIANOROLLPRINTVIEW_RIGHTMARGIN;
+ long lTopMargin = PIANOROLLPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = PIANOROLLPRINTVIEW_BOTTOMMARGIN;
+ long lVelHeight = PIANOROLLPRINTVIEW_VELHEIGHT + 32;
+ long lScaleHeight = PIANOROLLPRINTVIEW_SCALEHEIGHT;
+ long lKeyHeight = MIN (m_sizLogPaper.cy - lVelHeight - lScaleHeight - lTopMargin - lBottomMargin,
+ PIANOROLLPRINTVIEW_KEYHEIGHT);
+ long lScaleWidth = PIANOROLLPRINTVIEW_SCALEWIDTH;
+ long lTimeWidth = m_sizLogPaper.cx - lScaleWidth - lLeftMargin - lRightMargin;
+
+ CRgn theRgn;
+ CRect rcClip;
+
+ // ベロシティ目盛り部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lVelHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawVelScaleView (pDC);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 鍵盤目盛り部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin + lVelHeight;
+ rcClip.bottom = lBottomMargin + lVelHeight + lKeyHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lVelHeight + (PIANOROLLPRINTVIEW_KEYHEIGHT - lKeyHeight) / 2;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawKeyScaleView (pDC);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 左上余白部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = -lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin + lVelHeight + lKeyHeight;
+ rcClip.bottom = lBottomMargin + lVelHeight + lKeyHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lVelHeight - lKeyHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawScaleView (pDC);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // ベロシティロール部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lTimeWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lVelHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lTimeWidth * (pInfo->m_nCurPage - 1);
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawVelTimeView (pDC);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 鍵盤ロール部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lTimeWidth;
+ rcClip.top = lBottomMargin + lVelHeight;
+ rcClip.bottom = lBottomMargin + lVelHeight + lKeyHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lTimeWidth * (pInfo->m_nCurPage - 1);
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lVelHeight + (PIANOROLLPRINTVIEW_KEYHEIGHT - lKeyHeight) / 2;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawKeyTimeView (pDC);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 時刻目盛り部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lTimeWidth;
+ rcClip.top = lBottomMargin + lVelHeight + lKeyHeight;
+ rcClip.bottom = lBottomMargin + lVelHeight + lKeyHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lTimeWidth * (pInfo->m_nCurPage - 1);
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lVelHeight - lKeyHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawTimeScaleView (pDC);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // ヘッダー(タイトル)
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ pDC->SetTextColor (RGB (0, 0 ,0));
+ CRect rcText;
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = m_sizLogPaper.cy - lTopMargin;
+ rcText.bottom = m_sizLogPaper.cy - lTopMargin / 2;
+ TCHAR szText[256];
+ memset (szText, 0, sizeof (szText));
+ MIDIData_GetTitle (GetDocument()->m_pMIDIData, szText, TSIZEOF (szText));
+ CString strText;
+ if (TCSLEN (szText) == 0) {
+ strText = GetDocument()->GetTitle ();
+ }
+ else {
+ strText.Format (_T("%s"), szText);
+ }
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+ // フッター(ページ数/全ページ数)
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = lTopMargin / 2;
+ rcText.bottom = lTopMargin;
+ strText.Format (_T("%d/%d"), pInfo->m_nCurPage, pInfo->GetMaxPage ());
+ pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+}
+
+// 印刷準備時
+BOOL CPianoRollPrintView::OnPreparePrinting (CPrintInfo* pInfo) {
+ // デフォルトの印刷準備
+ return DoPreparePrinting (pInfo);
+}
+
+// 印刷開始時
+void CPianoRollPrintView::OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // 紙サイズの取得
+ m_sizDevPaper.cx = pDC->GetDeviceCaps (HORZRES); // [pixel]
+ m_sizDevPaper.cy = pDC->GetDeviceCaps (VERTRES); // [pixel]
+ m_sizLogPaper.cx = pDC->GetDeviceCaps (HORZSIZE) * 10; // [*0.1mm]
+ m_sizLogPaper.cy = pDC->GetDeviceCaps (VERTSIZE) * 10; // [*0.1mm]
+ m_sizLogPrinterDPI.cx = pDC->GetDeviceCaps (LOGPIXELSX); // [dpi]
+ m_sizLogPrinterDPI.cy = pDC->GetDeviceCaps (LOGPIXELSY); // [dpi]
+
+ // MIDIデータの性質を取得
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ // ロール部の幅を計算
+ long lLastTime = 0;
+ MIDIData_MakeTime (pMIDIData, lEndMeasure + 1, 0, 0, &lLastTime);
+ long lRollWidth = this->TimetoX (lLastTime);
+ long lLeftMargin = PIANOROLLPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = PIANOROLLPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = PIANOROLLPRINTVIEW_SCALEWIDTH;
+ long lTimeWidth = m_sizLogPaper.cx - lScaleWidth - lLeftMargin - lRightMargin;
+ long lNumPage = lRollWidth / MAX (lTimeWidth, 1) + 1;
+
+ // 印刷ページ数の設定
+ pInfo->SetMaxPage (lNumPage);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 印刷終了時
+void CPianoRollPrintView::OnEndPrinting (CDC* pDC, CPrintInfo* pInfo) {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
diff --git a/src/PianoRollPrintView.h b/src/PianoRollPrintView.h
new file mode 100644
index 0000000..10588af
--- /dev/null
+++ b/src/PianoRollPrintView.h
@@ -0,0 +1,79 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロール印刷ビュークラス
+// (C)2002-2011 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLPRINTVIEW_H_
+#define _PIANOROLLPRINTVIEW_H_
+
+class CPianoRollPrintView : public CSekaijuView {
+ DECLARE_DYNCREATE (CPianoRollPrintView)
+
+ // CPianoRollFrameからCPianoRollPrintView::OnCmdMsgの呼び出しを許可する。
+ friend class CPianoRollFrame;
+
+ // 印刷関係
+ CSize m_sizDevPaper; // 物理紙サイズ[ドット]
+ CSize m_sizLogPaper; // 論理紙サイズ[*1/10mm]
+ CSize m_sizLogPrinterDPI; // プリンタのDPI
+ CFont m_theFont; // 印刷用フォント
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollPrintView (); // コンストラクタ
+ virtual ~CPianoRollPrintView (); // デストラクタ
+
+ //------------------------------------------------------------------------------
+ // オペレーション
+ //------------------------------------------------------------------------------
+
+protected:
+ long TimetoX (long lTime);
+ long VeltoY (long lVel);
+ long PitchBendtoY (long lPitchBend);
+ long TempoBPMtoY (long lTempoBPM);
+ long KeyToY (long lKey);
+ void DrawFlagAndText (CDC* pDC, long lTime, LPCTSTR lpszText, long lColor);
+ void DrawVelScaleView (CDC* pDC);
+ void DrawVelTimeView (CDC* pDC);
+ void DrawKeyScaleView (CDC* pDC);
+ void DrawKeyTimeView (CDC* pDC);
+ void DrawScaleView (CDC* pDC);
+ void DrawTimeScaleView (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrint (CDC* pDC, CPrintInfo* pInfo);
+ virtual BOOL OnPreparePrinting (CPrintInfo* pInfo);
+ virtual void OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting (CDC* pDC, CPrintInfo* pInfo);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
+
diff --git a/src/PianoRollScaleView.cpp b/src/PianoRollScaleView.cpp
new file mode 100644
index 0000000..45fc198
--- /dev/null
+++ b/src/PianoRollScaleView.cpp
@@ -0,0 +1,163 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "PianoRollScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CPianoRollScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CPianoRollScaleView, CSekaijuView)
+ ON_WM_KEYDOWN ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollScaleView::CPianoRollScaleView () {
+}
+
+// デストラクタ
+CPianoRollScaleView::~CPianoRollScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 描画
+void CPianoRollScaleView::OnDraw (CDC* pDC) {
+ CSekaijuDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+}
+
+// ビューの更新
+void CPianoRollScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // 演奏開始した場合、リアルタイム入力開始した場合、位置移動した場合
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) { // 20091224追加
+ pPianoRollFrame->m_bAutoPageUpdate = TRUE;
+ }
+ }
+ // MIDIデータが変更された場合
+ if (lHint & SEKAIJUDOC_MIDIDATACHANGED) { /* 20091024追加 */
+ pPianoRollFrame->UpdateSnapCombo (); /* 20091024追加 */
+ pPianoRollFrame->UpdateDurationCombo (); /* 20091024追加 */
+ }
+ // MIDIトラックが変更された場合
+ if (lHint & SEKAIJUDOC_MIDITRACKCHANGED) {
+ pPianoRollFrame->UpdateTrackList ();
+ pPianoRollFrame->UpdateTrackCombo ();
+ }
+ // MIDIデータ又はMIDIトラック又はMIDIイベントが変更された場合
+ if ((lHint & SEKAIJUDOC_MIDIDATACHANGED) ||
+ (lHint & SEKAIJUDOC_MIDITRACKCHANGED) ||
+ (lHint & SEKAIJUDOC_MIDIEVENTCHANGED)) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ pMainFrame->SetPositionScrollRange (0, lEndTime, TRUE);
+ pPianoRollFrame->RecalcKeyScrollInfo ();
+ pPianoRollFrame->RecalcVelScrollInfo ();
+ pPianoRollFrame->RecalcTimeScrollInfo ();
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// キーが押された時
+void CPianoRollScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ pPianoRollFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ return;
+}
+
+// マウスホイールが回された時
+void CPianoRollScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lKeyScrollPos = pPianoRollFrame->GetKeyScrollPos ();
+ long lKeyZoom = pPianoRollFrame->GetKeyZoom ();
+ lKeyScrollPos -= lKeyZoom * lDelta / WHEELDELTA;
+ pPianoRollFrame->SetKeyScrollPos (lKeyScrollPos);
+ }
+}
+
+
+
diff --git a/src/PianoRollScaleView.h b/src/PianoRollScaleView.h
new file mode 100644
index 0000000..67ac6fb
--- /dev/null
+++ b/src/PianoRollScaleView.h
@@ -0,0 +1,51 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールスケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLSCALEVIEW_H_
+#define _PIANOROLLSCALEVIEW_H_
+
+class CPianoRollScaleView : public CSekaijuView {
+ DECLARE_DYNCREATE (CPianoRollScaleView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollScaleView (); // コンストラクタ
+ virtual ~CPianoRollScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
+
diff --git a/src/PianoRollTimeScaleView.cpp b/src/PianoRollTimeScaleView.cpp
new file mode 100644
index 0000000..7a9dcc4
--- /dev/null
+++ b/src/PianoRollTimeScaleView.cpp
@@ -0,0 +1,715 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールタイムスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "PianoRollTimeScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CPianoRollTimeScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CPianoRollTimeScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollTimeScaleView::CPianoRollTimeScaleView () {
+}
+
+// デストラクタ
+CPianoRollTimeScaleView::~CPianoRollTimeScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 指定時刻にフラグとテキストを描画
+void CPianoRollTimeScaleView::DrawFlagAndText
+(CDC* pDC, long lTime, LPCTSTR lpszText, long lColor) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ long x = pPianoRollFrame->TimetoX (lTime);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CRect rcBack (x, 0, x + 1024, 16);
+ CRect rcFlag (x, 3, x + 3, 12);
+ CRect rcText (x + 5, 0, x + 1024, 16);
+ CPen pen;
+ pen.CreatePen (PS_SOLID, 1, lColor);
+ CPen* pOldPen = pDC->SelectObject (&pen);
+ pDC->FillSolidRect (&rcBack, ::GetSysColor (COLOR_BTNFACE));
+ pDC->FillSolidRect (&rcFlag, lColor);
+ pDC->MoveTo (x, 3);
+ pDC->LineTo (x, 16);
+ pDC->SetBkMode (TRANSPARENT);
+ pDC->SetTextColor (lColor);
+ pDC->DrawText (lpszText, rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ pDC->SelectObject (pOldPen);
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CPianoRollTimeScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ pDC->SetWindowOrg (pPianoRollFrame->GetTimeScrollPos (), 0);
+}
+
+// 描画
+void CPianoRollTimeScaleView::OnDraw (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+ CFont* pOldFont = pDC->SelectObject (&(pPianoRollFrame->m_theFont));
+
+ long x, xold;
+ long lVisibleLeftTime = pPianoRollFrame->GetVisibleLeftTime ();
+ long lVisibleRightTime = pPianoRollFrame->GetVisibleRightTime ();
+ TCHAR szBuf[256];
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+
+ // 上段に拍子記号・調性記号・マーカーの描画
+ long lTime = 0;
+ long lOldTime = 0;
+ CString strText1;
+ CString strText2;
+ pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ if (pMIDITrack) {
+ long lColorTrack1 = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (0 <= lTime && lTime <= lVisibleRightTime) {
+ // テンポ
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo;
+ lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ strText1.Format (_T("%1.2lf"), (double)60000000 / (double)lTempo);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 拍子記号
+ else if (MIDIEvent_IsTimeSignature (pMIDIEvent)) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ strText1.Format (_T("%d/%d"), lnn, 1 << ldd);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 調性記号
+ else if (MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ strText1.Format (_T("%d%s"), labs (lsf), lsf >= 0 ? _T("#") : _T("b"));
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // マーカー
+ else if (MIDIEvent_IsMarker (pMIDIEvent)) {
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIEvent_GetText (pMIDIEvent, szBuf, TSIZEOF (szBuf) - 1);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += szBuf;
+ lOldTime = lTime;
+ }
+ }
+ }
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ }
+
+ // 下段に小節ボタン描画
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lLeftMeasure, lLeftBeat, lLeftTick;
+ long lRightMeasure, lRightBeat, lRightTick;
+ MIDIData_BreakTime (pMIDIData, lVisibleLeftTime, &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_BreakTime (pMIDIData, lVisibleRightTime, &lRightMeasure, &lRightBeat, &lRightTick);
+ xold = pPianoRollFrame->TimetoX (lVisibleLeftTime) - 1;
+ CRect theRect;
+ pDC->SetBkMode (TRANSPARENT);
+ for (long i = lLeftMeasure; i <= lRightMeasure + 1; i++) {
+ MIDIData_MakeTime (pMIDIData, i, 0, 0, &lTime);
+ x = pPianoRollFrame->TimetoX (lTime);
+ pDC->MoveTo (x, 16);
+ pDC->LineTo (x, 32);
+ theRect = CRect (xold, 16, x, 32);
+ pDC->Draw3dRect (xold, 16, x - xold, 16, lColorBtnHighlight, lColorBtnShadow);
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i);
+ pDC->SetTextColor (lColorBtnText);
+ pDC->DrawText (szBuf, -1, &theRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ xold = x;
+ }
+ }
+ else {
+ long lLeftFrameNumber = lVisibleLeftTime / lTimeResolution;
+ long lRightFrameNumber = lVisibleRightTime / lTimeResolution;
+ xold = pPianoRollFrame->TimetoX (lVisibleLeftTime) - 1;
+ CRect theRect;
+ pDC->SetBkMode (TRANSPARENT);
+ for (long i = lLeftFrameNumber; i <= lRightFrameNumber + 1; i++) {
+ lTime = i * lTimeResolution;
+ x = pPianoRollFrame->TimetoX (lTime);
+ pDC->MoveTo (x, 16);
+ pDC->LineTo (x, 32);
+ theRect = CRect (xold, 16, x, 32);
+ pDC->Draw3dRect (xold, 16, x - xold, 16, lColorBtnHighlight, lColorBtnShadow);
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i);
+ pDC->DrawText (szBuf, -1, &theRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ xold = x;
+ }
+ }
+ pDC->SelectObject (pOldFont);
+
+ if (GetCapture () == this) {
+ long lDownX = pPianoRollFrame->TimetoX (m_lDownTime);
+ long lCurX = pPianoRollFrame->TimetoX (m_lCurTime);
+ long lTop = rcClient.top;
+ long lBottom = rcClient.bottom;
+ CRect rect (lDownX, lBottom / 2, lCurX, lBottom);
+ pDC->SetROP2 (R2_NOT);
+ pDC->Rectangle (&rect);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// ビューの更新
+void CPianoRollTimeScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CPianoRollTimeScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キーが押された時
+void CPianoRollTimeScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ switch (nChar) {
+ // Deleteキー
+ case VK_DELETE:
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ break;
+ // デフォルト
+ default:
+ pPianoRollFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+// マウス左ボタン押された時
+void CPianoRollTimeScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), 0);
+ point += CSize (pPianoRollFrame->GetTimeScrollPos (), 0);
+
+ // 上半分をクリックしたとき(演奏位置移動)
+ if (point.y < rcClient.Height () / 2) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTime = pPianoRollFrame->XtoTime (point.x);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+ // 下半分(小節番号部)をクリックしたとき(小節選択)
+ else {
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ // 履歴の記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName; // 20110103追加
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT)); // 20110103追加
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName)); // 20110103修正
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+
+ m_lTempSnap = pPianoRollFrame->GetCurSnap ();
+ m_lTempSnap = CLIP (1, m_lTempSnap, MIDIData_GetTimeResolution (pMIDIData));
+ m_lOldTime = pPianoRollFrame->XtoTime (m_ptMouseDown.x) / m_lTempSnap * m_lTempSnap;
+ m_lDownTime = pPianoRollFrame->XtoTime (point.x) / m_lTempSnap * m_lTempSnap;
+ m_lCurTime = pPianoRollFrame->XtoTime (point.x) / m_lTempSnap * m_lTempSnap;
+
+ SetCapture ();
+ SetTimer (0x21, 55, NULL);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ Invalidate ();
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// マウス右ボタン押された時
+void CPianoRollTimeScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), 0);
+ point += sizWndOrg;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ if (point.y > rcClient.bottom / 2) {
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ long lTime = pPianoRollFrame->XtoTime (point.x);
+ //long lMeasure, lBeat, lTick;
+ //MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ //MIDIData_MakeTime (pMIDIData, lMeasure, 0, 0, &lTime);
+ pSekaijuDoc->m_lTempTime = lTime;
+ pSekaijuDoc->m_lTempTrackIndex = 0;
+ pSekaijuDoc->m_pTempTrack = pSekaijuDoc->GetTrack (0);
+ pSekaijuDoc->m_pTempEvent = NULL;
+ pSekaijuDoc->m_pTempTempoEvent = NULL;
+ pSekaijuDoc->m_pTempTimeSignatureEvent = NULL;
+ pSekaijuDoc->m_pTempKeySignatureEvent = NULL;
+ pSekaijuDoc->m_pTempMarkerEvent = NULL;
+ MIDIEvent* pTempEvent;
+ forEachEvent (pSekaijuDoc->m_pTempTrack, pTempEvent) {
+ if (MIDIEvent_GetTime (pTempEvent) > lTime) {
+ break;
+ }
+ if (MIDIEvent_IsTempo (pTempEvent)) {
+ pSekaijuDoc->m_pTempTempoEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsTimeSignature (pTempEvent)) {
+ pSekaijuDoc->m_pTempTimeSignatureEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsKeySignature (pTempEvent)) {
+ pSekaijuDoc->m_pTempKeySignatureEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsMarker (pTempEvent)) {
+ pSekaijuDoc->m_pTempMarkerEvent = pTempEvent;
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU10));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pPianoRollFrame);
+}
+
+// マウス左ボタン離されたとき
+void CPianoRollTimeScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), 0);
+ point += CSize (pPianoRollFrame->GetTimeScrollPos (), 0);
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+ // キャプタ−中の場合
+ if (GetCapture () == this) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ KillTimer (0x21);
+ ReleaseCapture ();
+
+ long lMinTime = __min (m_lDownTime, m_lCurTime);
+ long lMaxTime = __max (m_lDownTime, m_lCurTime);
+
+ // 該当範囲にあるノートイベントの及び各種グラフイベントの選択
+ long i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // ノートイベントの場合
+ if ((MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent)) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ // テンポイベントの場合
+ else if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ // テンポが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (0)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // ノートイベントの場合
+ else if ((MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent)) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ // ベロシティが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (1)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // チャンネルアフタータッチイベントの場合
+ else if (MIDIEvent_IsChannelAftertouch (pMIDIEvent)) {
+ // チャンネルアフタータッチが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (2)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // ピッチベンドイベントの場合
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ // ピッチベンドが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (3)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // コントロールチェンジの場合
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ // 指定ナンバー(CC#)のコントロールチェンジが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (4 + lNumber)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CPianoRollTimeScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CPianoRollTimeScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), 0);
+ point += CSize (pPianoRollFrame->GetTimeScrollPos (), 0);
+
+ // キャプタ−中の場合
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ m_lCurTime = pPianoRollFrame->XtoTime (point.x) / m_lTempSnap * m_lTempSnap;
+ m_lDownTime = pPianoRollFrame->XtoTime (m_ptMouseDown.x) / m_lTempSnap * m_lTempSnap;
+ m_lOldTime = pPianoRollFrame->XtoTime (m_ptMouseMove.x) / m_lTempSnap * m_lTempSnap;
+ // 前回のタイムと今回のタイムが異なる場合のみ
+ if (m_lOldTime != m_lCurTime) {
+ // 目盛り再描画
+ Invalidate (TRUE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CPianoRollTimeScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CPianoRollTimeScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CPianoRollTimeScaleView::OnTimer (UINT nIDEvent) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理
+ if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), 0);
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldTimeScrollPos = pPianoRollFrame->GetTimeScrollPos ();
+ if (m_ptMouseMove.x < rcClient.left) {
+ pPianoRollFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pPianoRollFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.x >= rcClient.right) {
+ pPianoRollFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pPianoRollFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x - lOldTimeScrollPos);
+ WORD wY = (WORD)(m_ptMouseMove.y);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+// マウスホイールが回された時
+void CPianoRollTimeScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lKeyScrollPos = pPianoRollFrame->GetKeyScrollPos ();
+ long lKeyZoom = pPianoRollFrame->GetKeyZoom ();
+ lKeyScrollPos -= lKeyZoom * lDelta / WHEELDELTA;
+ pPianoRollFrame->SetKeyScrollPos (lKeyScrollPos);
+ }
+}
diff --git a/src/PianoRollTimeScaleView.h b/src/PianoRollTimeScaleView.h
new file mode 100644
index 0000000..b512eb4
--- /dev/null
+++ b/src/PianoRollTimeScaleView.h
@@ -0,0 +1,80 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールタイムスケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLTIMESCALEVIEW_H_
+#define _PIANOROLLTIMESCALEVIEW_H_
+
+class CPianoRollTimeScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CPianoRollTimeScaleView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollTimeScaleView(); // コンストラクタ
+ virtual ~CPianoRollTimeScaleView(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lDownTime; // マウスが押されたときの時のタイム(0〜)[tick]
+ long m_lOldTime; // マウスが動かされたときの前回のタイム(0〜)[tick]
+ long m_lCurTime; // マウスが動かされたときの現在のタイム(0〜)[tick]
+ long m_lTempSnap; // 一時的なスナップタイム(1〜)[tick]
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual void DrawFlagAndText (CDC* pDC, long lTime, LPCTSTR lpszText, long lColor);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif
diff --git a/src/PianoRollVelScaleView.cpp b/src/PianoRollVelScaleView.cpp
new file mode 100644
index 0000000..b018e4d
--- /dev/null
+++ b/src/PianoRollVelScaleView.cpp
@@ -0,0 +1,530 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールベロシティスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "PianoRollVelScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE(CPianoRollVelScaleView, CView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CPianoRollVelScaleView, CView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollVelScaleView::CPianoRollVelScaleView () {
+}
+
+// デストラクタ
+CPianoRollVelScaleView::~CPianoRollVelScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動
+void CPianoRollVelScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ pDC->SetWindowOrg (0, pPianoRollFrame->GetVelScrollPos ());
+}
+
+// 描画
+void CPianoRollVelScaleView::OnDraw (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+
+
+ // 背景の塗りつぶし
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+
+ // 目盛り横線の描画
+ CPen penKey (PS_SOLID, 1, RGB (0, 0, 0));
+ CPen penOctave (PS_SOLID, 1, RGB (0, 0, 0));
+ CPen* pOldPen = pDC->SelectObject (&penKey);
+ long i;
+ for (i = 0; i <= 8; i++) {
+ if (i != 4) {
+ pDC->SelectObject (&penKey);
+ }
+ else {
+ pDC->SelectObject (&penOctave);
+ }
+ long y = pPianoRollFrame->VeltoY (i * 16);
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+
+ // ベロシティ・チャンネルアフター・コントロールチェンジ値の描画
+ BOOL bControlChangeVisible = FALSE;
+ CString strText;
+ CRect rcText (rcClient);
+ pDC->SelectObject (&(pPianoRollFrame->m_theFont));
+ for (i = 4; i < 4 + 127; i++) {
+ if (pPianoRollFrame->IsGraphVisible (i)) {
+ bControlChangeVisible = TRUE;
+ break;
+ }
+ }
+ // ベロシティ値又はチャンネルアフタータッチ値又はコントロールチェンジ値の描画(0〜64〜127)
+ if (pPianoRollFrame->GetCurGraphKind () == 1 ||
+ pPianoRollFrame->GetCurGraphKind () == 2 ||
+ pPianoRollFrame->GetCurGraphKind () >= 4) {
+ for (i = 0; i <= 8; i++) {
+ strText.Format (_T("%d"), CLIP (0, (i * 16), 127));
+ long y = pPianoRollFrame->VeltoY (i * 16);
+ rcText.top = y - 8;
+ rcText.bottom = y + 8;
+ pDC->DrawText (strText, rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ }
+ }
+ // ピッチベンド値の描画(-8192〜0〜8191)
+ else if (pPianoRollFrame->GetCurGraphKind () == 3) {
+ for (i = 0; i <= 8; i++) {
+ strText.Format (_T("%d"), CLIP (-8192, (i - 4) * 2048, 8191));
+ long y = pPianoRollFrame->VeltoY (i * 16);
+ rcText.top = y - 8;
+ rcText.bottom = y + 8;
+ pDC->DrawText (strText, rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ }
+ }
+ // テンポの描画(0〜256)
+ else if (pPianoRollFrame->GetCurGraphKind () == 0) {
+ for (i = 0; i <= 8; i++) {
+ strText.Format (_T("%d"), CLIP (0, (i * 32), 256));
+ long y = pPianoRollFrame->VeltoY (i * 16);
+ rcText.top = y - 8;
+ rcText.bottom = y + 8;
+ pDC->DrawText (strText, rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ }
+ }
+
+ // 選択範囲の反転(キャプタ−中のみ)
+ if (GetCapture () == this) {
+ long lDownY = m_ptMouseDown.y;//pPianoRollFrame->KeytoY (m_lDownKey);
+ long lCurY = m_ptMouseMove.y;//pPianoRollFrame->KeytoY (m_lCurKey);
+ long lTop = __min (lDownY, lCurY) - 1;
+ long lBottom = __max (lDownY, lCurY);
+ long w = rcClient.right;
+ CRect rect (0, lTop, w, lBottom);
+ pDC->SetROP2 (R2_NOT);
+ pDC->Rectangle (&rect);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+ pDC->SelectObject (pOldPen);
+
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CPianoRollVelScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キーが押された時
+void CPianoRollVelScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ switch (nChar) {
+ // Deleteキー
+ case VK_DELETE:
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ break;
+ // デフォルト
+ default:
+ pPianoRollFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+// マウス左ボタン押された時
+void CPianoRollVelScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetVelScrollPos ());
+ point += CSize (0, pPianoRollFrame->GetVelScrollPos ());
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+
+ m_lOldTempoBPM = pPianoRollFrame->YtoTempoBPM (m_ptMouseDown.y);
+ m_lDownTempoBPM = pPianoRollFrame->YtoTempoBPM (point.y);
+ m_lCurTempoBPM = pPianoRollFrame->YtoTempoBPM (point.y);
+ m_lOldVel = pPianoRollFrame->YtoVel (m_ptMouseDown.y);
+ m_lDownVel = pPianoRollFrame->YtoVel (point.y);
+ m_lCurVel = pPianoRollFrame->YtoVel (point.y);
+ m_lOldPitchBend = pPianoRollFrame->YtoPitchBend (m_ptMouseDown.y);
+ m_lDownPitchBend = pPianoRollFrame->YtoPitchBend (point.y);
+ m_lCurPitchBend = pPianoRollFrame->YtoPitchBend (point.y);
+
+
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ Invalidate ();
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CPianoRollVelScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+}
+
+// マウス左ボタン離されたとき
+void CPianoRollVelScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetVelScrollPos ());
+ point += CSize (0, pPianoRollFrame->GetVelScrollPos ());
+
+ if (GetCapture () == this) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ KillTimer (0x21);
+ ReleaseCapture ();
+
+ long lMinTempoBPM = __min (m_lDownTempoBPM, m_lCurTempoBPM);
+ long lMaxTempoBPM = __max (m_lDownTempoBPM, m_lCurTempoBPM);
+ long lMinVel = __min (m_lDownVel, m_lCurVel);
+ long lMaxVel = __max (m_lDownVel, m_lCurVel);
+ long lMinPitchBend = __min (m_lDownPitchBend, m_lCurPitchBend);
+ long lMaxPitchBend = __max (m_lDownPitchBend, m_lCurPitchBend);
+ long i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ // このトラックが可視の場合
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // テンポイベントの場合
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ // テンポが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (0)) {
+ long lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ long lTempoBPM = 60000000 / lTempo;
+ if (lMinTempoBPM <= lTempoBPM && lTempoBPM <= lMaxTempoBPM) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // ノートイベントの場合
+ else if ((MIDIEvent_IsNoteOn (pMIDIEvent) ||
+ MIDIEvent_IsNoteOff (pMIDIEvent)) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ // ベロシティが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (1)) {
+ long lVel = MIDIEvent_GetVelocity (pMIDIEvent);
+ if (lMinVel <= lVel && lVel <= lMaxVel) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // チャンネルアフタータッチイベントの場合
+ else if (MIDIEvent_IsChannelAftertouch (pMIDIEvent)) {
+ // チャンネルアフタータッチが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (2)) {
+ long lVel = MIDIEvent_GetValue (pMIDIEvent);
+ if (lMinVel <= lVel && lVel <= lMaxVel) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // ピッチベンドイベントの場合
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ // ピッチベンドが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (3)) {
+ long lPitchBend = MIDIEvent_GetValue (pMIDIEvent);
+ if (lMinPitchBend <= lPitchBend && lPitchBend <= lMaxPitchBend) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // コントロールチェンジの場合
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ // 指定ナンバー(CC#)のコントロールチェンジが可視の場合
+ if (pPianoRollFrame->IsGraphVisible (4 + lNumber)) {
+ long lVel = MIDIEvent_GetValue (pMIDIEvent);
+ if (lMinVel <= lVel && lVel <= lMaxVel) {
+ if (pSekaijuDoc->IsEventSelected (pMIDIEvent) == 0) {
+ MIDIEvent* pCloneEvent =
+ pSekaijuDoc->SelectEvent
+ (pMIDIEvent, 1, pCurHistoryUnit);
+ ASSERT (pCloneEvent);
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CPianoRollVelScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CPianoRollVelScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetVelScrollPos ());
+ point += CSize (0, pPianoRollFrame->GetVelScrollPos ());
+
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lCurTempoBPM = pPianoRollFrame->YtoTempoBPM (point.y);
+ m_lDownTempoBPM = pPianoRollFrame->YtoTempoBPM (m_ptMouseDown.y);
+ m_lOldTempoBPM = pPianoRollFrame->YtoTempoBPM (m_ptMouseMove.y);
+ m_lCurVel = pPianoRollFrame->YtoVel (point.y);
+ m_lDownVel = pPianoRollFrame->YtoVel (m_ptMouseDown.y);
+ m_lOldVel = pPianoRollFrame->YtoVel (m_ptMouseMove.y);
+ m_lCurPitchBend = pPianoRollFrame->YtoPitchBend (point.y);
+ m_lDownPitchBend = pPianoRollFrame->YtoPitchBend (m_ptMouseDown.y);
+ m_lOldPitchBend = pPianoRollFrame->YtoPitchBend (m_ptMouseMove.y);
+ if (m_lOldTempoBPM != m_lCurTempoBPM ||
+ m_lOldVel != m_lCurVel ||
+ m_lOldPitchBend != m_lCurPitchBend) {
+ Invalidate (TRUE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CPianoRollVelScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CPianoRollVelScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CPianoRollVelScaleView::OnTimer (UINT nIDEvent) {
+
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pPianoRollFrame->GetVelScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldVelScrollPos = pPianoRollFrame->GetVelScrollPos ();
+ if (m_ptMouseMove.y < rcClient.top) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pPianoRollFrame->m_wndVelScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y >= rcClient.bottom) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pPianoRollFrame->m_wndVelScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldVelScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+
+// マウスホイールが回された時
+void CPianoRollVelScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lVelScrollPos = pPianoRollFrame->GetVelScrollPos ();
+ long lVelZoom = pPianoRollFrame->GetKeyZoom ();
+ lVelScrollPos -= lVelZoom * lDelta / WHEELDELTA;
+ pPianoRollFrame->SetVelScrollPos (lVelScrollPos);
+ }
+}
+
diff --git a/src/PianoRollVelScaleView.h b/src/PianoRollVelScaleView.h
new file mode 100644
index 0000000..598a743
--- /dev/null
+++ b/src/PianoRollVelScaleView.h
@@ -0,0 +1,83 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールベロシティスケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLVELSCALEVIEW_H_
+#define _PIANOROLLVELSCALEVIEW_H_
+
+class CPianoRollVelScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CPianoRollVelScaleView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lDownTempoBPM; // マウスが押された位置のテンポ[BPM]
+ long m_lCurTempoBPM; // マウスが動かされた現在の位置のテンポ[BPM]
+ long m_lOldTempoBPM; // マウスが動かされた前回の位置のテンポ[BPM]
+ long m_lDownVel; // マウスが押された位置のベロシティ又は値(0〜127)
+ long m_lCurVel; // マウスが動かされた現在の位置のベロシティ又は値(0〜127)
+ long m_lOldVel; // マウスが動かされた前回の位置のベロシティ又は値(0〜127)
+ long m_lDownPitchBend; // マウスが押された位置のピッチベンド
+ long m_lCurPitchBend; // マウスが動かされた現在の位置のピッチベンド
+ long m_lOldPitchBend; // マウスが動かされた前回の位置のピッチベンド
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollVelScaleView (); // コンストラクタ
+ virtual ~CPianoRollVelScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/PianoRollVelTimeView.cpp b/src/PianoRollVelTimeView.cpp
new file mode 100644
index 0000000..1b6cdef
--- /dev/null
+++ b/src/PianoRollVelTimeView.cpp
@@ -0,0 +1,1976 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールベロシティタイムビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "PianoRollFrame.h"
+#include "SekaijuView.h"
+#include "PianoRollVelTimeView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE (CPianoRollVelTimeView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CPianoRollVelTimeView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_TIMER ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CPianoRollVelTimeView::CPianoRollVelTimeView () {
+ m_lCurTime = m_lOldTime = 0;
+ m_lOldY1 = m_lOldY2 = 0;
+ m_bOldDraw = TRUE;
+ m_pTempEvent = NULL;
+ m_lTempMode = 0;
+ m_pLastEvent = NULL; //TODO:20080802
+ m_lLastInsertedTempoBPM = -1;
+ m_lLastInsertedPitchBend = -1;
+ m_lLastInsertedValue = -1;
+}
+
+// デストラクタ
+CPianoRollVelTimeView::~CPianoRollVelTimeView () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 旧位置の縦線消去
+void CPianoRollVelTimeView::EraseOldLine (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+ if (rcClient.left <= m_lOldX && m_lOldX <= rcClient.right && m_bOldDraw == TRUE) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_lOldX, m_lOldY1);
+ pDC->LineTo (m_lOldX, m_lOldY2);
+ }
+}
+
+// 現在位置の縦線描画
+void CPianoRollVelTimeView::DrawCurLine (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+ long x = pPianoRollFrame->TimetoX (m_lCurTime);
+ if (rcClient.left <= x && x <= rcClient.right) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ m_bOldDraw = TRUE;
+ m_lOldTime = m_lCurTime;
+ m_lOldX = x;
+ m_lOldY1 = rcClient.top;
+ m_lOldY2 = rcClient.bottom;
+ }
+ else {
+ m_bOldDraw = FALSE;
+ }
+}
+
+
+
+// 原点の移動
+void CPianoRollVelTimeView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ pDC->SetWindowOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+}
+
+// 描画
+void CPianoRollVelTimeView::OnDraw (CDC* pDC) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[1]);
+ CPen penBeat (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen penKey (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+ CPen penOctave (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[1]);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ long x, y, lTime;
+ long lVisibleLeftTime = pPianoRollFrame->GetVisibleLeftTime ();
+ long lVisibleRightTime = pPianoRollFrame->GetVisibleRightTime ();
+ long lLeftMeasure, lLeftBeat, lLeftTick;
+ long lRightMeasure, lRightBeat, lRightTick;
+ long lnn, ldd, lcc, lbb;
+ long lUnitTick;
+
+ // 背景の描画
+ pDC->FillSolidRect (rcClient, pSekaijuApp->m_theColorOption.m_lBackColor[0]);
+
+ // 横線の描画
+ CPen* pOldPen = pDC->SelectObject (&penKey);
+ long i, j;
+ for (i = 0; i <= 8; i++) {
+ if (i != 4) {
+ pDC->SelectObject (&penKey);
+ }
+ else {
+ pDC->SelectObject (&penOctave);
+ }
+ y = pPianoRollFrame->VeltoY (i * 16);
+ pDC->MoveTo (rcClient.left, y);
+ pDC->LineTo (rcClient.right, y);
+ }
+
+ // 縦線の描画
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ MIDIData_BreakTime (GetDocument()->m_pMIDIData, lVisibleLeftTime, &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_BreakTime (GetDocument()->m_pMIDIData, lVisibleRightTime, &lRightMeasure, &lRightBeat, &lRightTick);
+ for (i = lLeftMeasure; i <= lRightMeasure; i++) {
+ // 小節線の描画
+ MIDIData_MakeTimeEx (GetDocument()->m_pMIDIData, i, 0, 0, &lTime, &lnn, &ldd, &lcc, &lbb);
+ x = pPianoRollFrame->TimetoX (lTime);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ // 拍線の描画
+ pDC->SelectObject (&penBeat);
+ lUnitTick = lTimeResolution * 4 / (1 << ldd);
+ for (j = 1; j < lnn; j++) {
+ x = pPianoRollFrame->TimetoX (lTime + j * lUnitTick);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ }
+ }
+ }
+ else {
+ long lLeftFrameNumber = lVisibleLeftTime / lTimeResolution;
+ long lRightFrameNumber = lVisibleRightTime / lTimeResolution;
+ for (i = lLeftFrameNumber; i <= lRightFrameNumber; i++) {
+ // フレーム境界線の描画
+ lTime = i * lTimeResolution;
+ x = pPianoRollFrame->TimetoX (lTime);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // グラフの描画
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ long lValue;
+ long lGraphLineWidth = pSekaijuApp->m_thePianoRollOption.m_lGraphLineWidth;
+ i = 0;
+ // すべてのトラックに対して
+ forEachTrack (pMIDIData, pMIDITrack) {
+ // そのトラックが可視状態であれば
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ long lOldTempo = 60000000 / 100;
+ long lOldTempoTime = 0;
+ long lTrackColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lSelectedColor = RGB (0, 0, 0);
+ CPen penControl (PS_SOLID, lGraphLineWidth, lTrackColor);
+ CPen penSelected (PS_SOLID, lGraphLineWidth, lSelectedColor);
+ CPen* pOldPen = NULL;
+ CPen* pLastTempoPen = NULL;
+ // そのトラック内のすべてのイベントに対して
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ lTime = MIDIEvent_GetTime (pMIDIEvent);
+ // イベント時刻がクライアント領域内にあれば
+ if (lVisibleLeftTime <= lTime && lTime < lVisibleRightTime) {
+ // ベロシティの描画
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (1)) {
+ pOldPen = pDC->SelectObject
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? &penSelected : &penControl);
+ x = pPianoRollFrame->TimetoX (lTime);
+ lValue = MIDIEvent_GetVelocity (pMIDIEvent);
+ y = pPianoRollFrame->VeltoY (lValue);
+ long y0 = pPianoRollFrame->VeltoY (0);
+ //pDC->MoveTo (x, y);
+ //pDC->LineTo (x, y0);
+ pDC->FillSolidRect (x, y, lGraphLineWidth, y0 - y,
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? lSelectedColor : lTrackColor));
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // チャンネルアフタータッチの描画
+ else if (MIDIEvent_IsChannelAftertouch (pMIDIEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (2)) {
+ pOldPen = pDC->SelectObject
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? &penSelected : &penControl);
+ x = pPianoRollFrame->TimetoX (lTime);
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ y = pPianoRollFrame->VeltoY (lValue);
+ long y0 = pPianoRollFrame->VeltoY (0);
+ //pDC->MoveTo (x, y);
+ //pDC->LineTo (x, y0);
+ pDC->FillSolidRect (x, y, lGraphLineWidth, y0 - y,
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? lSelectedColor : lTrackColor));
+ if (lValue == 0) {
+ long r = 1 + lGraphLineWidth;
+ pDC->Ellipse (x - r, y0 - r, x + r, y0 + r);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // ピッチベンドの描画
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (3)) {
+ pOldPen = pDC->SelectObject
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? &penSelected : &penControl);
+ x = pPianoRollFrame->TimetoX (lTime);
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ y = pPianoRollFrame->PitchBendtoY (lValue);
+ long yc = pPianoRollFrame->PitchBendtoY (8192);
+ //pDC->MoveTo (x, y);
+ //pDC->LineTo (x, yc);
+ pDC->FillSolidRect (x, y, lGraphLineWidth, yc - y,
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? lSelectedColor : lTrackColor));
+ if (lValue == 8192) {
+ long r = 1 + lGraphLineWidth;
+ pDC->Ellipse (x - r, yc - r, x + r, yc + r);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // コントロールチェンジの描画
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ if (pPianoRollFrame->IsGraphVisible (4 + lNumber)) {
+ pOldPen = pDC->SelectObject
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? &penSelected : &penControl);
+ x = pPianoRollFrame->TimetoX (lTime);
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ y = pPianoRollFrame->VeltoY (lValue);
+ long y0 = pPianoRollFrame->VeltoY (0);
+ //pDC->MoveTo (x, y);
+ //pDC->LineTo (x, y0);
+ pDC->FillSolidRect (x, y, lGraphLineWidth, y0 - y,
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? lSelectedColor : lTrackColor));
+ if (lValue == 0) {
+ long r = 1 + lGraphLineWidth;
+ pDC->Ellipse (x - r, y0 - r, x + r, y0 + r);
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ }
+ // テンポの描画(トラック0のみ)
+ if (MIDIEvent_IsTempo (pMIDIEvent) && i == 0) {
+ if (pPianoRollFrame->IsGraphVisible (0)) {
+ pOldPen = pDC->SelectObject
+ (pSekaijuDoc->IsEventSelected (pMIDIEvent) ? &penSelected : &penControl);
+ x = pPianoRollFrame->TimetoX (lTime);
+ long xold = pPianoRollFrame->TimetoX (lOldTempoTime);
+ lValue = MIDIEvent_GetTempo (pMIDIEvent);
+ lValue = CLIP (1, lValue, 60000000);
+ y = pPianoRollFrame->TempoBPMtoY (60000000 / lValue);
+ long yold = pPianoRollFrame->TempoBPMtoY (60000000 / lOldTempo);
+ pDC->MoveTo (xold, yold);
+ pDC->LineTo (x, yold);
+ pDC->LineTo (x, y);
+ lOldTempo = lValue;
+ lOldTempoTime = lTime;
+ pLastTempoPen = pDC->SelectObject (pOldPen);
+ }
+ }
+ }
+ // テンポの最終横線を描画する(トラック0のみ)
+ if (pPianoRollFrame->IsGraphVisible (0) && i == 0) {
+ if (pLastTempoPen) {
+ pOldPen = pDC->SelectObject (pLastTempoPen);
+ }
+ else {
+ pOldPen = pDC->SelectObject (&penControl);
+ }
+ lTime = MIDIData_GetEndTime (pMIDIData);
+ x = pPianoRollFrame->TimetoX (lTime);
+ long xold = pPianoRollFrame->TimetoX (lOldTempoTime);
+ long yold = pPianoRollFrame->TempoBPMtoY (60000000 / lOldTempo);
+ pDC->MoveTo (xold, yold);
+ pDC->LineTo (x, yold);
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ i++;
+ }
+
+ // 現在位置の描画
+ DrawCurLine (pDC);
+
+ // キャプター中の場合のみ
+ if (GetCapture () == this) {
+ // マウストラッカーが必要な場合、マウストラッカーの描画
+ if (m_lTempMode == 0x0401) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseDown.y);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseMove.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseDown.x, m_ptMouseMove.y);
+ pDC->MoveTo (m_ptMouseMove.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+ // ライントラッカーが必要な場合、ライントラッカーの描画
+ else if (m_lTempMode == 0x0201) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_ptMouseDown.x, m_ptMouseDown.y);
+ pDC->LineTo (m_ptMouseMove.x, m_ptMouseMove.y);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ Sleep (0);
+}
+
+// ビューの更新
+void CPianoRollVelTimeView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ PostMessage (WM_TIMER, 0x11, NULL);
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+// ウィンドウクラスの変更
+BOOL CPianoRollVelTimeView::PreCreateWindow (CREATESTRUCT& cs) {
+ CView::PreCreateWindow (cs);
+ cs.lpszClass = AfxRegisterWndClass
+ (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS,
+ NULL, // デフォルトカーソル無し
+ (HBRUSH)::GetStockObject (WHITE_BRUSH), // デフォルト背景ブラシ
+ NULL); // デフォルトアイコン無し
+ return TRUE;
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CPianoRollVelTimeView::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+ SetTimer (0x11, 55, NULL);
+ return CSekaijuView::OnCreate (lpCreateStruct);
+
+}
+
+// ウィンドウ破棄時
+void CPianoRollVelTimeView::OnDestroy () {
+ KillTimer (0x11);
+ CSekaijuView::OnDestroy ();
+}
+
+// タイマー呼び出し時
+void CPianoRollVelTimeView::OnTimer (UINT nIDEvent) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ // 現在演奏位置縦線の描画処理
+ if (nIDEvent == 0x11) {
+ if (pSekaijuDoc->m_pMIDIData && pSekaijuDoc->m_pMIDIClock) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CDC* pDC = GetDC ();
+ OnPrepareDC (pDC, NULL);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+ m_lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ // 前回描画した時刻と異なっている場合のみ
+ if (m_lOldTime != m_lCurTime) {
+ EraseOldLine (pDC);
+ DrawCurLine (pDC);
+ }
+ ReleaseDC (pDC);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理
+ else if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ long lOldTimeScrollPos = pPianoRollFrame->GetTimeScrollPos ();
+ long lOldVelScrollPos = pPianoRollFrame->GetVelScrollPos ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (m_ptMouseMove.x < rcClient.left) {
+ pPianoRollFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pPianoRollFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.x > rcClient.right) {
+ pPianoRollFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pPianoRollFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ if (m_ptMouseMove.y < rcClient.top) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pPianoRollFrame->m_wndVelScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y > rcClient.bottom) {
+ pPianoRollFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pPianoRollFrame->m_wndVelScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x - lOldTimeScrollPos);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldVelScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+// キーが押された時
+void CPianoRollVelTimeView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ switch (nChar) {
+ // ESC
+ case VK_ESCAPE:
+ // キャプター中の場合
+ if (GetCapture () == this) {
+ if (m_lTempMode = 0x0201) {
+ m_pTempEvent = NULL;
+ m_lTempMode = 0;
+ KillTimer (0x21);
+ ReleaseCapture ();
+ //::SetCursor (pSekaijuApp->m_hCursorArrow);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ // Deleteキー
+ case VK_DELETE:
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ break;
+ // デフォルト
+ default:
+ pPianoRollFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+// マウス左ボタン押された時
+void CPianoRollVelTimeView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+ point += sizWndOrg;
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += sizWndOrg;
+ ASSERT (m_pTempEvent == NULL);
+ ASSERT (m_lTempMode == 0);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ m_lTempTrackIndex = pPianoRollFrame->GetCurTrackIndex ();
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ m_lTempTime = pPianoRollFrame->XtoTime (point.x);
+ m_lTempTool = pPianoRollFrame->m_lCurTool;
+ m_lTempChannel = pPianoRollFrame->GetCurChannel ();
+ m_lTempChannel = CLIP (0, m_lTempChannel, 15);
+ m_lTempVelocity = pPianoRollFrame->GetCurVelocity ();
+ m_lTempVelocity = CLIP (1, m_lTempVelocity, 127);
+ m_lTempSnap = pPianoRollFrame->GetCurSnap ();
+ m_lTempSnap = CLIP (1, m_lTempSnap, MIDIData_GetTimeResolution (pMIDIData));
+ m_lTempGraphKind = pPianoRollFrame->GetCurGraphKind ();
+ m_lTempGraphSnap = pPianoRollFrame->GetCurGraphSnap ();
+ m_lTempPortIndex = MIDITrack_GetOutputPort (pMIDITrack);
+ m_pTempEvent = NULL;
+ m_pLastEvent = NULL;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pPrevEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIOutStatus = NULL;
+ long lNewVel = pPianoRollFrame->YtoVel (point.y);
+ long lNewValue = pPianoRollFrame->YtoVel (point.y);
+ long lNewPitchBend = pPianoRollFrame->YtoPitchBend (point.y);
+ long lNewTempoBPM = pPianoRollFrame->YtoTempoBPM (point.y);
+ long lNewTime = pPianoRollFrame->XtoTime (point.x);
+ CRect rcRegion;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ switch (m_lTempTool) {
+ // ペン
+ case ID_PIANOROLL_PEN:
+ // フォーマット1のMIDIデータで最初のトラックにグラフを置くのを禁止
+ if (lFormat == 1 && m_lTempTrackIndex == 0 && m_lTempGraphKind != 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_GRAPHEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_GRAPH));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // グラフの種類がテンポの場合は強制的にトラック0に描画させる。
+ if (m_lTempGraphKind == 0) {
+ pTempTrack = pSekaijuDoc->GetTrack (0);
+ if (pPianoRollFrame->IsTrackVisible (0) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (0);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ }
+ // グラフの種類がテンポ以外の場合は、現在選択中のトラックに描画させる。
+ else {
+ pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ if (pPianoRollFrame->IsTrackVisible (m_lTempTrackIndex) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (m_lTempTrackIndex);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ }
+ // 描画するグラフ種類の表示がOFF担っている場合ONにする。
+ if (pPianoRollFrame->IsGraphVisible (m_lTempGraphKind) == FALSE) {
+ pPianoRollFrame->SetGraphVisible (m_lTempGraphKind);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ // マウス設置点に既に同種グラフがある場合
+ ASSERT (pTempTrack);
+ pTempEvent = pTempTrack->m_pFirstEvent;
+ while (pTempEvent) {
+ long lTempTime = MIDIEvent_GetTime (pTempEvent);
+ // このイベントは時刻が一致している
+ if (lTempTime == lNewTime) {
+ // テンポの削除
+ if (MIDIEvent_IsTempo (pTempEvent) &&
+ m_lTempGraphKind == 0) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ベロシティの変更
+ else if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ MIDIEvent_IsNote (pTempEvent) &&
+ m_lTempGraphKind == 1) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ lNewVel = CLIP (1, lNewVel, 127);
+ MIDIEvent_SetVelocity (pCloneEvent, lNewVel);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ pTempEvent = pCloneEvent->m_pNextEvent;
+ }
+ // チャンネルアフタータッチの削除
+ else if (MIDIEvent_IsChannelAftertouch (pTempEvent) &&
+ m_lTempGraphKind == 2) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ピッチベンドの削除
+ else if (MIDIEvent_IsPitchBend (pTempEvent) &&
+ m_lTempGraphKind == 3) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // コントロールチェンジの削除
+ else if (MIDIEvent_IsControlChange (pTempEvent) &&
+ m_lTempGraphKind >= 4) {
+ if (MIDIEvent_GetNumber (pTempEvent) ==
+ m_lTempGraphKind - 4) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // どれにも該当しない。
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // このイベントは時刻が一致していない
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ pTempEvent = NULL;
+ pLastEvent = NULL;
+
+ // テンポの挿入
+ if (m_lTempGraphKind == 0) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ if (m_lTempGraphSnap == 1) {
+ lNewTime = CLIP (0, lNewTime, 0x7FFF0000);
+ lNewTempoBPM = CLIP (1, lNewTempoBPM, 60000000);
+ VERIFY (pTempEvent = MIDIEvent_CreateTempo (lNewTime, 60000000 / lNewTempoBPM));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedTempoBPM = lNewTempoBPM;
+ }
+ }
+ // チャンネルアフタータッチの挿入
+ else if (m_lTempGraphKind == 2) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ if (m_lTempGraphSnap == 1) {
+ lNewTime = CLIP (0, lNewTime, 0x7FFF0000);
+ lNewValue = CLIP (0, lNewValue, 127);
+ VERIFY (pTempEvent = MIDIEvent_CreateChannelAftertouch (lNewTime, m_lTempChannel, lNewValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedValue = lNewValue;
+ }
+ }
+ // ピッチベンドの挿入
+ else if (m_lTempGraphKind == 3) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ if (m_lTempGraphSnap == 1) {
+ lNewTime = CLIP (0, lNewTime, 0x7FFF0000);
+ lNewPitchBend = CLIP (0, lNewPitchBend, 16383);
+ VERIFY (pTempEvent = MIDIEvent_CreatePitchBend (lNewTime, m_lTempChannel, lNewPitchBend));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedPitchBend = lNewPitchBend;
+ }
+ }
+ // コントロールチェンジの挿入
+ else if (m_lTempGraphKind >= 4) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ if (m_lTempGraphSnap == 1) {
+ lNewTime = CLIP (0, lNewTime, 0x7FFF0000);
+ lNewValue = CLIP (0, lNewValue, 127);
+ VERIFY (pTempEvent = MIDIEvent_CreateControlChange
+ (lNewTime, m_lTempChannel, m_lTempGraphKind - 4, lNewValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedValue = lNewValue;
+ }
+ }
+ rcRegion = CRect (point.x, rcClient.top, point.x + 1, rcClient.bottom);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ m_lTempMode = 0x0101;
+ ::SetCursor (pSekaijuApp->m_hCursorDraw);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ // 線
+ case ID_PIANOROLL_LINE:
+ // フォーマット1のMIDIデータで最初のトラックにグラフを置くのを禁止
+ if (lFormat == 1 && m_lTempTrackIndex == 0 && m_lTempGraphKind != 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_GRAPHEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_GRAPH));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // グラフの種類がテンポの場合は強制的にトラック0に描画させる。
+ if (m_lTempGraphKind == 0) {
+ pTempTrack = pSekaijuDoc->GetTrack (0);
+ if (pPianoRollFrame->IsTrackVisible (0) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (0);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ }
+ // グラフの種類がテンポ以外の場合は、現在選択中のトラックに描画させる。
+ else {
+ pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ if (pPianoRollFrame->IsTrackVisible (m_lTempTrackIndex) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (m_lTempTrackIndex);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ }
+ // 描画するグラフ種類の表示がOFF担っている場合ONにする。
+ if (pPianoRollFrame->IsGraphVisible (m_lTempGraphKind) == FALSE) {
+ pPianoRollFrame->SetGraphVisible (m_lTempGraphKind);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ m_lTempMode = 0x0201;
+ ::SetCursor (pSekaijuApp->m_hCursorLine);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ // フォーマット1のMIDIデータで最初のトラックにグラフを消すのを禁止
+ if (lFormat == 1 && m_lTempTrackIndex == 0 && m_lTempGraphKind != 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_DELETE_GRAPHEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ break;
+ }
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_GRAPH));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // グラフの種類がテンポの場合は強制的にトラック0に描画させる。
+ if (m_lTempGraphKind == 0) {
+ pTempTrack = pSekaijuDoc->GetTrack (0);
+ if (pPianoRollFrame->IsTrackVisible (0) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (0);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ }
+ // グラフの種類がテンポ以外の場合は、現在選択中のトラックに描画させる。
+ else {
+ pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ if (pPianoRollFrame->IsTrackVisible (m_lTempTrackIndex) == FALSE) {
+ pPianoRollFrame->SetTrackVisible (m_lTempTrackIndex);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ }
+ // 描画するグラフ種類の表示がOFF担っている場合ONにする。
+ if (pPianoRollFrame->IsGraphVisible (m_lTempGraphKind) == FALSE) {
+ pPianoRollFrame->SetGraphVisible (m_lTempGraphKind);
+ pPianoRollFrame->m_pKeyScaleView->Invalidate ();
+ pPianoRollFrame->m_pKeyTimeView->Invalidate ();
+ pPianoRollFrame->m_pVelScaleView->Invalidate ();
+ pPianoRollFrame->m_pVelTimeView->Invalidate ();
+ }
+ // マウス設置点に既に同種グラフがある場合
+ ASSERT (pTempTrack);
+ pTempEvent = pTempTrack->m_pFirstEvent;
+ while (pTempEvent) {
+ long lTempTime = MIDIEvent_GetTime (pTempEvent);
+ // このイベントは時刻が一致している
+ if (lTempTime == lNewTime) {
+ // テンポの削除
+ if (MIDIEvent_IsTempo (pTempEvent) &&
+ m_lTempGraphKind == 0) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ベロシティの変更
+ else if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ MIDIEvent_IsNote (pTempEvent) &&
+ m_lTempGraphKind == 1) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ lNewVel = CLIP (1, lNewVel, 127);
+ MIDIEvent_SetVelocity (pTempEvent, lNewVel);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ pTempEvent = pCloneEvent->m_pNextEvent;
+ }
+ // チャンネルアフタータッチの削除
+ else if (MIDIEvent_IsChannelAftertouch (pTempEvent) &&
+ m_lTempGraphKind == 2) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ピッチベンドの削除
+ else if (MIDIEvent_IsPitchBend (pTempEvent) &&
+ m_lTempGraphKind == 3) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // コントロールチェンジの削除
+ else if (MIDIEvent_IsControlChange (pTempEvent) &&
+ m_lTempGraphKind >= 4) {
+ if (MIDIEvent_GetNumber (pTempEvent) ==
+ m_lTempGraphKind - 4) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // いずれにも該当しない
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // このイベントは時刻が一致していない
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ m_lTempMode = 0x0301;
+ ::SetCursor (pSekaijuApp->m_hCursorEraser);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT_GRAPH));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+ Invalidate ();
+ m_lTempMode = 0x0401;
+ dc.SetROP2 (R2_NOT);
+ dc.SetPixel (point, RGB (0, 0, 0));
+ dc.SetROP2 (R2_COPYPEN);
+ ::SetCursor (pSekaijuApp->m_hCursorSelect);
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+
+ // スクラブ
+ case ID_PIANOROLL_SPEAKER:
+ m_lTempMode = 0x0501;
+ if (pSekaijuApp->m_bPlaying) {
+ pPianoRollFrame->SendMessage (WM_COMMAND, (WPARAM)ID_CONTROL_PLAY, (LPARAM)0);
+ }
+ if (pSekaijuApp->m_thePianoRollOption.m_bSpeakerModeVisibleTrack) {
+ long i = 0;
+ long lTempOutputOn[MAXMIDITRACKNUM];
+ forEachTrack (pMIDIData, pTempTrack) {
+ lTempOutputOn[i] = MIDITrack_GetOutputOn (pTempTrack);
+ MIDITrack_SetOutputOn (pTempTrack, pPianoRollFrame->IsTrackVisible (i));
+ i++;
+ }
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ MIDITrack_SetOutputOn (pTempTrack, lTempOutputOn[i]);
+ i++;
+ }
+ }
+ else {
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ }
+ pPianoRollFrame->m_bAutoPageUpdate = FALSE;
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CPianoRollVelTimeView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+}
+
+// マウス左ボタン離されたとき
+void CPianoRollVelTimeView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+ point += sizWndOrg;
+ long lDownVel = pPianoRollFrame->YtoVel (m_ptMouseDown.y);
+ long lOldVel = pPianoRollFrame->YtoVel (m_ptMouseMove.y);
+ long lDownValue = pPianoRollFrame->YtoVel (m_ptMouseDown.y);
+ long lOldValue = pPianoRollFrame->YtoVel (m_ptMouseMove.y);
+ long lDownTempoBPM = pPianoRollFrame->YtoTempoBPM (m_ptMouseDown.y);
+ long lOldTempoBPM = pPianoRollFrame->YtoTempoBPM (m_ptMouseMove.y);
+ long lDownPitchBend = pPianoRollFrame->YtoPitchBend (m_ptMouseDown.y);
+ long lOldPitchBend = pPianoRollFrame->YtoPitchBend (m_ptMouseMove.y);
+ long lDownTime = pPianoRollFrame->XtoTime (m_ptMouseDown.x);
+ long lOldTime = pPianoRollFrame->XtoTime (m_ptMouseMove.x);
+ CRect rcRegion;
+ // キャプター中
+ if (GetCapture () == this) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTempTime = 0;
+ long lMinTime = __min (lDownTime, lOldTime);
+ long lMaxTime = __max (lDownTime, lOldTime);
+ long lTempX = 0;
+ long lMinX = __min (m_ptMouseDown.x, m_ptMouseMove.x);
+ long lMaxX = __max (m_ptMouseDown.x, m_ptMouseMove.x);
+ long lMinValue = __min (lDownValue, lOldValue);
+ long lMaxValue = __max (lDownValue, lOldValue);
+ long lMinTempoBPM = __min (lDownTempoBPM, lOldTempoBPM);
+ long lMaxTempoBPM = __max (lDownTempoBPM, lOldTempoBPM);
+ long lMinPitchBend = __min (lDownPitchBend, lOldPitchBend);
+ long lMaxPitchBend = __max (lDownPitchBend, lOldPitchBend);
+ long i = 0;
+ long j = 0;
+ long jMin = lMinTime / m_lTempGraphSnap;
+ long jMax = lMaxTime / m_lTempGraphSnap;
+
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pPrevEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ switch (m_lTempTool) {
+ // ペン
+ case ID_PIANOROLL_PEN:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ if (m_pLastEvent) { // TODO:20080802 m_pLastEvent==0xcdcdcdcd
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ break;
+ // 線
+ case ID_PIANOROLL_LINE:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ if (m_lTempGraphKind == 0) {
+ pTempTrack = pSekaijuDoc->GetTrack (0);
+ }
+ else {
+ pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ }
+ ASSERT (pTempTrack);
+ // グラフの種類がベロシティ以外の場合EOTの履歴記録準備
+ m_pLastEvent = NULL;
+ if (m_lTempGraphKind != 1) {
+ pLastEvent = MIDITrack_GetLastEvent (pTempTrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ m_pLastEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ }
+ // 開始点〜終了点にある同種のグラフを削除
+ //pTempEvent = pTempTrack->m_pLastEvent;
+ // すべてのイベントに対して(後方から評価)
+ pTempEvent = pTempTrack->m_pFirstEvent;
+ while (pTempEvent) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ lTempTime = MIDIEvent_GetTime (pTempEvent);
+ // このイベントは時刻が開始点〜終了点間にある場合
+ if (lMinTime <= lTempTime && lTempTime <= lMaxTime) {
+ // テンポの削除
+ if (MIDIEvent_IsTempo (pTempEvent) &&
+ m_lTempGraphKind == 0) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // チャンネルアフタータッチの削除
+ else if (MIDIEvent_IsChannelAftertouch (pTempEvent) &&
+ m_lTempGraphKind == 2) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ピッチベンドの削除
+ else if (MIDIEvent_IsPitchBend (pTempEvent) &&
+ m_lTempGraphKind == 3) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // コントロールチェンジの削除
+ else if (MIDIEvent_IsControlChange (pTempEvent) &&
+ m_lTempGraphKind >= 4) {
+ if (MIDIEvent_GetNumber (pTempEvent) ==
+ m_lTempGraphKind - 4) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // いずれにも該当しない
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // このイベントは時刻が開始点〜終了点の外側にある場合
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // テンポの直線追加
+ if (m_lTempGraphKind == 0) {
+ long lTempTempoBPM = 0;
+ long lTempOldTempoBPM = -1;
+ if (m_lTempGraphSnap == 1) {
+ for (lTempX = lMinX; lTempX <= lMaxX; lTempX++) {
+ lTempTime = pPianoRollFrame->XtoTime (lTempX);
+ if (lOldTime == lDownTime) {
+ lTempTempoBPM = lOldTempoBPM;
+ }
+ else {
+ lTempTempoBPM = lDownTempoBPM + (lTempTime - lDownTime) *
+ (lOldTempoBPM - lDownTempoBPM) / (lOldTime - lDownTime);
+ }
+ lTempTempoBPM = CLIP (1, lTempTempoBPM, 60000000);
+ if (lTempTempoBPM != lTempOldTempoBPM) {
+ VERIFY (pTempEvent = MIDIEvent_CreateTempo (lTempTime, 60000000 / lTempTempoBPM));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldTempoBPM = lTempOldTempoBPM;
+ }
+ }
+ else if (m_lTempGraphSnap >= 2) {
+ for (j = jMin; j <= jMax + 1; j++) {
+ lTempTime = j * m_lTempGraphSnap;
+ if (lMinTime <= lTempTime && lTempTime <= lMaxTime) {
+ if (lOldTime == lDownTime) {
+ lTempTempoBPM = lOldTempoBPM;
+ }
+ else {
+ lTempTempoBPM = lDownTempoBPM + (lTempTime - lDownTime) *
+ (lOldTempoBPM - lDownTempoBPM) / (lOldTime - lDownTime);
+ }
+ lTempTempoBPM = CLIP (1, lTempTempoBPM, 60000000);
+ if (lTempTempoBPM != lTempOldTempoBPM) {
+ VERIFY (pTempEvent = MIDIEvent_CreateTempo (lTempTime, 60000000 / lTempTempoBPM));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldTempoBPM = lTempOldTempoBPM;
+ }
+ }
+ }
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ }
+ // ベロシティの直線修正
+ else if (m_lTempGraphKind == 1) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ long lTempTime = MIDIEvent_GetTime (pTempEvent);
+ if (lMinTime <= lTempTime && lTempTime <= lMaxTime) {
+ //if (MIDIEvent_IsNoteOn (pTempEvent) && MIDIEvent_IsNote (pTempEvent)) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) && pTempEvent->m_pPrevCombinedEvent == NULL) {
+ long lTempVel = 0;
+ if (lOldTime == lDownTime) {
+ lTempVel = lOldVel;
+ }
+ else {
+ lTempVel = lDownVel + (lTempTime - lDownTime) *
+ (lOldVel - lDownVel) / (lOldTime - lDownTime);
+ }
+ lTempVel = CLIP (1, lTempVel, 127);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ MIDIEvent_SetVelocity (pCloneEvent, lTempVel);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // チャンネルアフタータッチの直線追加
+ else if (m_lTempGraphKind == 2) {
+ long lTempValue = 0;
+ long lTempOldValue = -1;
+ if (m_lTempGraphSnap == 1) {
+ for (lTempX = lMinX; lTempX <= lMaxX; lTempX++) {
+ lTempTime = pPianoRollFrame->XtoTime (lTempX);
+ if (lOldTime == lDownTime) {
+ lTempValue = lOldValue;
+ }
+ else {
+ lTempValue = lDownValue + (lTempTime - lDownTime) *
+ (lOldValue - lDownValue) / (lOldTime - lDownTime);
+ }
+ lTempValue = CLIP (0, lTempValue, 127);
+ if (lTempValue != lTempOldValue) {
+ VERIFY (pTempEvent = MIDIEvent_CreateChannelAftertouch
+ (lTempTime, m_lTempChannel, lTempValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldValue = lTempValue;
+ }
+ }
+ else if (m_lTempGraphSnap >= 2) {
+ for (j = jMin; j <= jMax + 1; j++) {
+ lTempTime = j * m_lTempGraphSnap;
+ if (lMinTime <= lTempTime && lTempTime <= lMaxTime) {
+ if (lOldTime == lDownTime) {
+ lTempValue = lOldValue;
+ }
+ else {
+ lTempValue = lDownValue + (lTempTime - lDownTime) *
+ (lOldValue - lDownValue) / (lOldTime - lDownTime);
+ }
+ lTempValue = CLIP (0, lTempValue, 127);
+ if (lTempValue != lTempOldValue) {
+ VERIFY (pTempEvent = MIDIEvent_CreateChannelAftertouch
+ (lTempTime, m_lTempChannel, lTempValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldValue = lTempValue;
+ }
+ }
+ }
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ }
+ // ピッチベンドの直線追加
+ else if (m_lTempGraphKind == 3) {
+ long lTempPitchBend = 0;
+ long lTempOldPitchBend = -1;
+ if (m_lTempGraphSnap == 1) {
+ for (lTempX = lMinX; lTempX <= lMaxX; lTempX++) {
+ lTempTime = pPianoRollFrame->XtoTime (lTempX);
+ if (lOldTime == lDownTime) {
+ lTempPitchBend = lOldPitchBend;
+ }
+ else {
+ lTempPitchBend = lDownPitchBend + (lTempTime - lDownTime) *
+ (lOldPitchBend - lDownPitchBend) / (lOldTime - lDownTime);
+ }
+ lTempPitchBend = CLIP (0, lTempPitchBend, 16483);
+ if (lTempPitchBend != lTempOldPitchBend) {
+ VERIFY (pTempEvent = MIDIEvent_CreatePitchBend
+ (lTempTime, m_lTempChannel, lTempPitchBend));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldPitchBend = lTempPitchBend;
+ }
+ }
+ else if (m_lTempGraphSnap >= 2) {
+ for (j = jMin; j <= jMax + 1; j++) {
+ lTempTime = j * m_lTempGraphSnap;
+ if (lMinTime <= lTempTime && lTempTime <= lMaxTime) {
+ if (lOldTime == lDownTime) {
+ lTempPitchBend = lOldPitchBend;
+ }
+ else {
+ lTempPitchBend = lDownPitchBend + (lTempTime - lDownTime) *
+ (lOldPitchBend - lDownPitchBend) / (lOldTime - lDownTime);
+ }
+ lTempPitchBend = CLIP (0, lTempPitchBend, 16483);
+ if (lTempPitchBend != lTempOldPitchBend) {
+ VERIFY (pTempEvent = MIDIEvent_CreatePitchBend
+ (lTempTime, m_lTempChannel, lTempPitchBend));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldPitchBend = lTempPitchBend;
+ }
+ }
+ }
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ }
+ // CCイベントの直線追加
+ else if (m_lTempGraphKind >= 4) {
+ long lTempValue = 0;
+ long lTempOldValue = -1;
+ if (m_lTempGraphSnap == 1) {
+ for (lTempX = lMinX; lTempX <= lMaxX; lTempX++) {
+ lTempTime = pPianoRollFrame->XtoTime (lTempX);
+ if (lOldTime == lDownTime) {
+ lTempValue = lOldValue;
+ }
+ else {
+ lTempValue = lDownValue + (lTempTime - lDownTime) *
+ (lOldValue - lDownValue) / (lOldTime - lDownTime);
+ }
+ lTempValue = CLIP (0, lTempValue, 127);
+ if (lTempValue != lTempOldValue) {
+ VERIFY (pTempEvent = MIDIEvent_CreateControlChange
+ (lTempTime, m_lTempChannel, m_lTempGraphKind - 4, lTempValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldValue = lTempValue;
+ }
+ }
+ else if (m_lTempGraphSnap >= 2) {
+ for (j = jMin; j <= jMax + 1; j++) {
+ lTempTime = j * m_lTempGraphSnap;
+ if (lMinTime <= lTempTime && lTempTime <= lMaxTime) {
+ if (lOldTime == lDownTime) {
+ lTempValue = lOldValue;
+ }
+ else {
+ lTempValue = lDownValue + (lTempTime - lDownTime) *
+ (lOldValue - lDownValue) / (lOldTime - lDownTime);
+ }
+ lTempValue = CLIP (0, lTempValue, 127);
+ if (lTempValue != lTempOldValue) {
+ VERIFY (pTempEvent = MIDIEvent_CreateControlChange
+ (lTempTime, m_lTempChannel, m_lTempGraphKind - 4, lTempValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ lTempOldValue = lTempValue;
+ }
+ }
+ }
+ if (m_pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (m_pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, m_pLastEvent);
+ }
+ }
+ }
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ break;
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ break;
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ // 新規矩形内部選択(左→右ドラッグ)
+ if (m_ptMouseMove.x >= m_ptMouseDown.x) {
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ long lTime = MIDIEvent_GetTime (pTempEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (MIDIEvent_IsTempo (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (0)) {
+ long lTempoBPM = 60000000 / MIDIEvent_GetTempo (pTempEvent);
+ if (lMinTempoBPM <= lTempoBPM && lTempoBPM <= lMaxTempoBPM) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsNoteOn (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (1)) {
+ long lValue = MIDIEvent_GetVelocity (pTempEvent);
+ if (lMinValue <= lValue && lValue <= lMaxValue) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsChannelAftertouch (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (2)) {
+ long lValue = MIDIEvent_GetValue (pTempEvent);
+ if (lMinValue <= lValue && lValue <= lMaxValue) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsPitchBend (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (3)) {
+ long lPitchBend = MIDIEvent_GetValue (pTempEvent);
+ if (lMinPitchBend <= lPitchBend && lPitchBend <= lMaxPitchBend) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsControlChange (pTempEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pTempEvent);
+ if (pPianoRollFrame->IsGraphVisible (lNumber + 4)) {
+ long lValue = MIDIEvent_GetValue (pTempEvent);
+ if (lMinValue <= lValue && lValue <= lMaxValue) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+ }
+ // 新規矩形接触選択(右→左ドラッグ) // 20100503追加
+ else {
+ forEachTrack (pMIDIData, pTempTrack) {
+ if (pPianoRollFrame->IsTrackVisible (i)) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ long lTime = MIDIEvent_GetTime (pTempEvent);
+ if (lMinTime <= lTime && lTime <= lMaxTime) {
+ if (MIDIEvent_IsTempo (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (0)) {
+ long lTempoBPM = 60000000 / MIDIEvent_GetTempo (pTempEvent);
+ if (lTempoBPM >= lMinTempoBPM) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsNoteOn (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (1)) {
+ long lValue = MIDIEvent_GetVelocity (pTempEvent);
+ if (lValue >= lMinValue) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsChannelAftertouch (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (2)) {
+ long lValue = MIDIEvent_GetValue (pTempEvent);
+ if (lValue >= lMinValue) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsPitchBend (pTempEvent)) {
+ if (pPianoRollFrame->IsGraphVisible (3)) {
+ long lPitchBend = MIDIEvent_GetValue (pTempEvent);
+ if (lPitchBend >= lMinPitchBend) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ else if (MIDIEvent_IsControlChange (pTempEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pTempEvent);
+ if (pPianoRollFrame->IsGraphVisible (lNumber + 4)) {
+ long lValue = MIDIEvent_GetValue (pTempEvent);
+ if (lValue >= lMinValue) {
+ pCloneEvent = pSekaijuDoc->SelectEvent
+ (pTempEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ i++;
+ }
+ }
+ break;
+ // スクラブ
+ case ID_PIANOROLL_SPEAKER:
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllSoundOff ();
+ break;
+ }
+ m_pTempEvent = NULL;
+ m_lTempMode = 0;
+ KillTimer (0x21);
+ ReleaseCapture ();
+ //::SetCursor (pSekaijuApp->m_hCursorArrow);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// マウス右ボタン離されたとき
+void CPianoRollVelTimeView::OnRButtonUp (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+}
+
+// マウスが動かされたとき
+void CPianoRollVelTimeView::OnMouseMove (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pPianoRollFrame->GetTimeScrollPos (), pPianoRollFrame->GetVelScrollPos ());
+ point += sizWndOrg;
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += sizWndOrg;
+ long lOldVel = pPianoRollFrame->YtoVel (m_ptMouseMove.y);
+ long lNewVel = pPianoRollFrame->YtoVel (point.y);
+ long lOldValue = pPianoRollFrame->YtoVel (m_ptMouseMove.y);
+ long lNewValue = pPianoRollFrame->YtoVel (point.y);
+ long lOldPitchBend = pPianoRollFrame->YtoPitchBend (m_ptMouseMove.y);
+ long lNewPitchBend = pPianoRollFrame->YtoPitchBend (point.y);
+ long lOldTempoBPM = pPianoRollFrame->YtoTempoBPM (m_ptMouseMove.y);
+ long lNewTempoBPM = pPianoRollFrame->YtoTempoBPM (point.y);
+ long lOldTime = pPianoRollFrame->XtoTime (m_ptMouseMove.x);
+ long lNewTime = pPianoRollFrame->XtoTime (point.x);
+ CRect rcRegion;
+ // キャプター中
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDIEvent* pPrevEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIOutStatus = NULL;
+ if (0 <= m_lTempPortIndex && m_lTempPortIndex < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[m_lTempPortIndex];
+ pMIDIOutStatus = pSekaijuApp->m_pMIDIOutStatus[m_lTempPortIndex];
+ }
+ long i = 0;
+ long lTime = lNewTime;
+ // ツール別の操作
+ switch (m_lTempTool) {
+ // ペン
+ case ID_PIANOROLL_PEN:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ if (m_lTempGraphKind == 0) {
+ pTempTrack = pSekaijuDoc->GetTrack (0);
+ }
+ else {
+ pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ }
+ ASSERT (pTempTrack);
+ // すべてのイベントに対して
+ pTempEvent = pTempTrack->m_pFirstEvent;
+ while (pTempEvent) {
+ long lTempTime = MIDIEvent_GetTime (pTempEvent);
+ if (lNewTime > lOldTime &&
+ lOldTime < lTempTime && lTempTime <= lNewTime ||
+ lNewTime < lOldTime &&
+ lNewTime <= lTempTime && lTempTime < lOldTime ||
+ lNewTime == lOldTime && lTempTime == lNewTime) {
+ // テンポの削除
+ if (MIDIEvent_IsTempo (pTempEvent) &&
+ m_lTempGraphKind == 0) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ベロシティの変更
+ else if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ MIDIEvent_IsNote (pTempEvent) &&
+ m_lTempGraphKind == 1) {
+ lNewVel = CLIP (1, lNewVel, 127);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ lNewVel = CLIP (1, lNewVel, 127);
+ MIDIEvent_SetVelocity (pCloneEvent, lNewVel);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ pTempEvent = pCloneEvent->m_pNextEvent;
+ }
+ // チャンネルアフタータッチの削除
+ else if (MIDIEvent_IsChannelAftertouch (pTempEvent) &&
+ m_lTempGraphKind == 2) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ピッチベンドの削除
+ else if (MIDIEvent_IsPitchBend (pTempEvent) &&
+ m_lTempGraphKind == 3) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // コントロールチェンジの削除
+ else if (MIDIEvent_IsControlChange (pTempEvent) &&
+ m_lTempGraphKind >= 4) {
+ if (MIDIEvent_GetNumber (pTempEvent) ==
+ m_lTempGraphKind - 4) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // どれにも該当しない。
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // このイベントは時刻が一致していない
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // 単一イベントの挿入
+ lOldTime = CLIP (0, lOldTime, 0x7FFF0000);
+ lNewTime = CLIP (0, lNewTime, 0x7FFF0000);
+ lOldTempoBPM = CLIP (1, lOldTempoBPM, 60000000);
+ lNewTempoBPM = CLIP (1, lNewTempoBPM, 60000000);
+ lOldValue = CLIP (0, lOldValue, 127);
+ lNewValue = CLIP (0, lNewValue, 127);
+ lOldPitchBend = CLIP (0, lOldPitchBend, 16383);
+ lNewPitchBend = CLIP (0, lNewPitchBend, 16383);
+ lTime = lNewTime;
+ if (m_lTempGraphSnap >= 2) {
+ lTime = (lNewTime / m_lTempGraphSnap) * m_lTempGraphSnap;
+ }
+ // 挿入時刻がマウス移動区間内にある場合のみ
+ if (lOldTime < lTime && lTime <= lNewTime ||
+ lNewTime <= lTime && lTime < lOldTime ||
+ lNewTime == lTime && lOldTime == lTime) {
+ // テンポの挿入
+ if (m_lTempGraphKind == 0) {
+ if (lNewTempoBPM != m_lLastInsertedTempoBPM) {
+ VERIFY (pTempEvent = MIDIEvent_CreateTempo (lTime, 60000000 / lNewTempoBPM));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedTempoBPM = lNewTempoBPM;
+ }
+ }
+ // チャンネルアフタータッチの挿入
+ else if (m_lTempGraphKind == 2) {
+ if (lNewValue != m_lLastInsertedValue) {
+ VERIFY (pTempEvent = MIDIEvent_CreateChannelAftertouch (lTime, m_lTempChannel, lNewValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedValue = lNewValue;
+ }
+ }
+ // ピッチベンドの挿入
+ else if (m_lTempGraphKind == 3) {
+ if (lNewPitchBend != m_lLastInsertedPitchBend) {
+ VERIFY (pTempEvent = MIDIEvent_CreatePitchBend (lTime, m_lTempChannel, lNewPitchBend));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedPitchBend = lNewPitchBend;
+ }
+ }
+ // コントロールチェンジの挿入
+ else if (m_lTempGraphKind >= 4) {
+ if (lNewValue != m_lLastInsertedValue) {
+ VERIFY (pTempEvent = MIDIEvent_CreateControlChange
+ (lTime, m_lTempChannel, m_lTempGraphKind - 4, lNewValue));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ m_lLastInsertedValue = lNewValue;
+ }
+ }
+ }
+ rcRegion = CRect (m_ptMouseMove.x, rcClient.top, point.x, rcClient.bottom);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ break;
+
+ // 線
+ case ID_PIANOROLL_LINE:
+ rcRegion = CRect (m_ptMouseDown, m_ptMouseMove);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown, point);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ break;
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ();
+ if (m_lTempGraphKind == 0) {
+ pTempTrack = pSekaijuDoc->GetTrack (0);
+ }
+ else {
+ pTempTrack = pSekaijuDoc->GetTrack (m_lTempTrackIndex);
+ }
+ ASSERT (pTempTrack);
+ pTempEvent = pTempTrack->m_pFirstEvent;
+ //pTempEvent = pTempTrack->m_pLastEvent;
+ // すべてのイベントに対して(後方から評価)
+ while (pTempEvent) {
+ //pPrevEvent = pTempEvent->m_pPrevEvent;
+ long lTempTime = MIDIEvent_GetTime (pTempEvent);
+ if (lNewTime > lOldTime &&
+ lOldTime < lTempTime && lTempTime <= lNewTime ||
+ lNewTime < lOldTime &&
+ lNewTime <= lTempTime && lTempTime < lOldTime ||
+ lNewTime == lOldTime && lTempTime == lNewTime) {
+ // テンポの削除
+ if (MIDIEvent_IsTempo (pTempEvent) &&
+ m_lTempGraphKind == 0) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // チャンネルアフターの削除
+ else if (MIDIEvent_IsChannelAftertouch (pTempEvent) &&
+ m_lTempGraphKind == 2) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // ピッチベンドの削除
+ else if (MIDIEvent_IsPitchBend (pTempEvent) &&
+ m_lTempGraphKind == 3) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ // コントロールチェンジの削除
+ else if (MIDIEvent_IsControlChange (pTempEvent) &&
+ m_lTempGraphKind >= 4) {
+ if (MIDIEvent_GetNumber (pTempEvent) ==
+ m_lTempGraphKind - 4) {
+ pPrevEvent = pTempEvent->m_pPrevEvent;
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ MIDITrack_RemoveEvent (pTempTrack, pTempEvent);
+ pTempEvent = pPrevEvent ? pPrevEvent->m_pNextEvent : pTempTrack->m_pFirstEvent;
+ }
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // いずれにも該当しない
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ // このイベントは時刻が一致していない
+ else {
+ pTempEvent = pTempEvent->m_pNextEvent;
+ }
+ }
+ rcRegion = CRect (m_ptMouseMove.x, rcClient.top, point.x, rcClient.bottom);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ break;
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ // 案B(選択矩形はちらつくが内部はちらつかない)
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseMove.x, m_ptMouseDown.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseMove.y, m_ptMouseMove.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseDown.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseMove.x, m_ptMouseDown.y, m_ptMouseMove.x, m_ptMouseMove.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, point.x, m_ptMouseDown.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, point.y, point.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_ptMouseDown.x, m_ptMouseDown.y, m_ptMouseDown.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (point.x, m_ptMouseDown.y, point.x, point.y);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ break;
+
+ // スクラブ
+ case ID_PIANOROLL_SPEAKER:
+ m_lTempTime = pPianoRollFrame->XtoTime (point.x);
+ if (pSekaijuApp->m_thePianoRollOption.m_bSpeakerModeVisibleTrack) {
+ long i = 0;
+ long lTempOutputOn[MAXMIDITRACKNUM];
+ forEachTrack (pMIDIData, pTempTrack) {
+ lTempOutputOn[i] = MIDITrack_GetOutputOn (pTempTrack);
+ MIDITrack_SetOutputOn (pTempTrack, pPianoRollFrame->IsTrackVisible (i));
+ i++;
+ }
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ i = 0;
+ forEachTrack (pMIDIData, pTempTrack) {
+ MIDITrack_SetOutputOn (pTempTrack, lTempOutputOn[i]);
+ i++;
+ }
+ }
+ else {
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ }
+ break;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ // 非キャプター中
+ // 非キャプター中(カーソルの種類だけ変更)
+ else {
+ long i = 0;
+ switch (pPianoRollFrame->m_lCurTool) {
+ // 描画
+ case ID_PIANOROLL_PEN:
+ ::SetCursor (pSekaijuApp->m_hCursorDraw);
+ break;
+ // 線
+ case ID_PIANOROLL_LINE:
+ ::SetCursor (pSekaijuApp->m_hCursorLine);
+ break;
+ // 消しゴム
+ case ID_PIANOROLL_ERASER:
+ ::SetCursor (pSekaijuApp->m_hCursorEraser);
+ break;
+ // 選択
+ case ID_PIANOROLL_SELECT:
+ ::SetCursor (pSekaijuApp->m_hCursorSelect);
+ break;
+ // スピーカー
+ case ID_PIANOROLL_SPEAKER:
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ break;
+ // 不明
+ default:
+ //::SetCursor (pSekaijuApp->m_hCursorArrow);
+ break;
+ }
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+}
+
+// マウスホイールが回された時
+void CPianoRollVelTimeView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CPianoRollFrame* pPianoRollFrame = (CPianoRollFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pPianoRollFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lVelScrollPos = pPianoRollFrame->GetVelScrollPos ();
+ long lVelZoom = pPianoRollFrame->GetKeyZoom ();
+ lVelScrollPos -= lVelZoom * lDelta / WHEELDELTA;
+ pPianoRollFrame->SetVelScrollPos (lVelScrollPos);
+ }
+}
diff --git a/src/PianoRollVelTimeView.h b/src/PianoRollVelTimeView.h
new file mode 100644
index 0000000..f28f653
--- /dev/null
+++ b/src/PianoRollVelTimeView.h
@@ -0,0 +1,103 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ピアノロールベロシティタイムビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PIANOROLLVELTIMEVIEW_H_
+#define _PIANOROLLVELTIMEVIEW_H_
+
+class CPianoRollVelTimeView : public CSekaijuView {
+ DECLARE_DYNCREATE(CPianoRollVelTimeView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPianoRollVelTimeView(); // コンストラクタ
+ virtual ~CPianoRollVelTimeView(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+
+ // カレントポジション縦線描画用
+protected:
+ long m_lCurTime; // 現在の描画タイム[tick]
+ long m_lOldTime; // 前回の描画タイム[tick]
+ long m_lOldX; // 前回の縦線x座標[pixel]
+ long m_lOldY1; // 前回の縦線y上座標[pixel]
+ long m_lOldY2; // 前回の縦線y下座標[pixel]
+ BOOL m_bOldDraw; // 前回縦線を描画したか?
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lTempTool; // 一時的なツール
+ long m_lTempTrackIndex; // 一時的なトラック番号(0〜65535)
+ long m_lTempSnap; // 一時的なスナップ(1〜)[tick]
+ long m_lTempVelocity; // 一時的なベロシティ(1〜127)
+ long m_lTempPortIndex; // 一時的なポート番号(0〜15)
+ long m_lTempChannel; // 一時的なチャンネル(0〜15)
+ long m_lTempGraphKind; // 一時的なグラフの種類
+ long m_lTempGraphSnap; // 一時的なグラフのスナップ(1〜)[tick]
+ long m_lTempTime; // 一時的なタイム(0〜)[tick]
+ long m_lTempTimeNoteOn; // 一時的なノートオンタイム(0〜)[tick]
+ MIDIEvent* m_pTempEvent; // 一時的なイベントへのポインタ
+ MIDIEvent* m_pLastEvent; // 一時的な最後のイベントへのポインタ
+ long m_lTempMode; // 一時的なモード
+ long m_lLastInsertedValue;
+ long m_lLastInsertedTempoBPM;
+ long m_lLastInsertedPitchBend;
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+protected:
+ virtual void EraseOldLine (CDC* pDC);
+ virtual void DrawCurLine (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif
+
+
diff --git a/src/PropertyKeySignatureDlg.cpp b/src/PropertyKeySignatureDlg.cpp
new file mode 100644
index 0000000..64d4513
--- /dev/null
+++ b/src/PropertyKeySignatureDlg.cpp
@@ -0,0 +1,103 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティ調性記号ダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "PropertyKeySignatureDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//******************************************************************************
+// 構築と破壊
+//******************************************************************************
+
+// コンストラクタ
+CPropertyKeySignatureDlg::CPropertyKeySignatureDlg () : CDialog (CPropertyKeySignatureDlg::IDD) {
+ m_strTime = _T("");
+ m_nSFIndex = 0;
+ m_nMiIndex = 0;
+}
+
+//******************************************************************************
+// オペレーション
+//******************************************************************************
+
+// #又はbの数コンボボックス充満
+BOOL CPropertyKeySignatureDlg::FillSFIndexCombo () {
+ long i = 0;
+ CString strSign;
+ VERIFY (strSign.LoadString (IDS_FLAT));
+ for (i = 7; i > 0; i--) {
+ CString strItem;
+ strItem.Format (_T("%d%s"), i, strSign);
+ ((CComboBox*)GetDlgItem (IDC_PROPERTYKEYSIGNATURE_SFINDEX))->AddString (strItem);
+ }
+ VERIFY (strSign.LoadString (IDS_SHARP));
+ for (i = 0; i <= 7; i++) {
+ CString strItem;
+ strItem.Format (_T("%d%s"), i, strSign);
+ ((CComboBox*)GetDlgItem (IDC_PROPERTYKEYSIGNATURE_SFINDEX))->AddString (strItem);
+ }
+ return TRUE;
+}
+
+// 長調or短調コンボボックス充満
+BOOL CPropertyKeySignatureDlg::FillMiIndexCombo () {
+ CString strSign;
+ VERIFY (strSign.LoadString (IDS_MAJOR));
+ ((CComboBox*)GetDlgItem (IDC_PROPERTYKEYSIGNATURE_MIINDEX))->AddString (strSign);
+ VERIFY (strSign.LoadString (IDS_MINOR));
+ ((CComboBox*)GetDlgItem (IDC_PROPERTYKEYSIGNATURE_MIINDEX))->AddString (strSign);
+ return TRUE;
+}
+
+//******************************************************************************
+// オーバーライド
+//******************************************************************************
+
+// データエクスチェンジ
+void CPropertyKeySignatureDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_PROPERTYKEYSIGNATURE_TIME, m_strTime);
+ DDX_CBIndex (pDX, IDC_PROPERTYKEYSIGNATURE_SFINDEX, m_nSFIndex);
+ DDX_CBIndex (pDX, IDC_PROPERTYKEYSIGNATURE_MIINDEX, m_nMiIndex);
+}
+
+// ダイアログ初期化
+BOOL CPropertyKeySignatureDlg::OnInitDialog () {
+ FillSFIndexCombo ();
+ FillMiIndexCombo ();
+ BOOL bRet = CDialog::OnInitDialog ();
+ return bRet;
+}
+
+
+//******************************************************************************
+// メッセージマップ
+//******************************************************************************
+
+BEGIN_MESSAGE_MAP (CPropertyKeySignatureDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
diff --git a/src/PropertyKeySignatureDlg.h b/src/PropertyKeySignatureDlg.h
new file mode 100644
index 0000000..eeb6fa6
--- /dev/null
+++ b/src/PropertyKeySignatureDlg.h
@@ -0,0 +1,62 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティ調性記号ダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PROPERTYKEYSIGNATUREDLG_H_
+#define _PROPERTYKEYSIGNATUREDLG_H_
+
+class CPropertyKeySignatureDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strTime; // タイム
+ int m_nSFIndex; // #又はbの数(0=7b...7=0#...14=7#)
+ int m_nMiIndex; // 長調or短調(0=major,1=minor)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPropertyKeySignatureDlg(); // コンストラクタ
+ enum {IDD = IDD_PROPERTYKEYSIGNATURE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL CPropertyKeySignatureDlg::FillSFIndexCombo ();
+ BOOL CPropertyKeySignatureDlg::FillMiIndexCombo ();
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ();
+};
+
+#endif \ No newline at end of file
diff --git a/src/PropertyMarkerDlg.cpp b/src/PropertyMarkerDlg.cpp
new file mode 100644
index 0000000..3fa220d
--- /dev/null
+++ b/src/PropertyMarkerDlg.cpp
@@ -0,0 +1,71 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティマーカーダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "PropertyMarkerDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//******************************************************************************
+// 構築と破壊
+//******************************************************************************
+
+// コンストラクタ
+CPropertyMarkerDlg::CPropertyMarkerDlg () : CDialog (CPropertyMarkerDlg::IDD) {
+ m_strTime = _T("");
+ m_strText = _T("");
+}
+
+//******************************************************************************
+// オペレーション
+//******************************************************************************
+
+
+//******************************************************************************
+// オーバーライド
+//******************************************************************************
+
+// データエクスチェンジ
+void CPropertyMarkerDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_PROPERTYMARKER_TIME, m_strTime);
+ DDX_Text (pDX, IDC_PROPERTYMARKER_TEXT, m_strText);
+}
+
+// ダイアログ初期化
+BOOL CPropertyMarkerDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ return bRet;
+}
+
+
+//******************************************************************************
+// メッセージマップ
+//******************************************************************************
+
+BEGIN_MESSAGE_MAP (CPropertyMarkerDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
diff --git a/src/PropertyMarkerDlg.h b/src/PropertyMarkerDlg.h
new file mode 100644
index 0000000..ba5fd0d
--- /dev/null
+++ b/src/PropertyMarkerDlg.h
@@ -0,0 +1,58 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティマーカーダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PROPERTYMARKERDLG_H_
+#define _PROPERTYMARKERDLG_H_
+
+class CPropertyMarkerDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strTime; // タイム
+ CString m_strText; // 文字列
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPropertyMarkerDlg(); // コンストラクタ
+ enum {IDD = IDD_PROPERTYMARKER};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ();
+};
+
+#endif
diff --git a/src/PropertyNoteDlg.cpp b/src/PropertyNoteDlg.cpp
new file mode 100644
index 0000000..51f8f74
--- /dev/null
+++ b/src/PropertyNoteDlg.cpp
@@ -0,0 +1,168 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティノートダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "PropertyNoteDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//******************************************************************************
+// 構築と破壊
+//******************************************************************************
+
+// コンストラクタ
+CPropertyNoteDlg::CPropertyNoteDlg () : CDialog (CPropertyNoteDlg::IDD) {
+ m_bTrackZeroOrigin = FALSE;
+ m_bNoteOnNoteOn0 = FALSE;
+ m_nTrackIndex = 0;
+ m_strTime = _T("");
+ m_nChannel = 0;
+ m_nKey = 0;
+ m_nOnVelocity = 0;
+ m_nOffVelocity = 0;
+ m_nDuration = 0;
+}
+
+//******************************************************************************
+// オペレーション
+//******************************************************************************
+
+// チャンネル可変範囲設定
+BOOL CPropertyNoteDlg::SetChannelRange () {
+ CString strValue;
+ GetDlgItem (IDC_PROPERTYNOTE_CHANNEL)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_CHANNELSP))->SetRange (1, 16);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_CHANNELSP))->SetPos (CLIP (1, lValue, 16));
+ return TRUE;
+}
+
+// 打鍵ベロシティ可変範囲設定
+BOOL CPropertyNoteDlg::SetOnVelocityRange () {
+ CString strValue;
+ GetDlgItem (IDC_PROPERTYNOTE_ONVELOCITY)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_ONVELOCITYSP))->SetRange (1, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_ONVELOCITYSP))->SetPos (CLIP (1, lValue, 127));
+ return TRUE;
+}
+
+// 離鍵ベロシティ可変範囲設定
+BOOL CPropertyNoteDlg::SetOffVelocityRange () {
+ CString strValue;
+ GetDlgItem (IDC_PROPERTYNOTE_OFFVELOCITY)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_OFFVELOCITYSP))->SetRange (0, 127);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_OFFVELOCITYSP))->SetPos (CLIP (0, lValue, 127));
+ return TRUE;
+}
+
+// 音長さ可変範囲設定
+BOOL CPropertyNoteDlg::SetDurationRange () {
+ CString strValue;
+ GetDlgItem (IDC_PROPERTYNOTE_DURATION)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_DURATIONSP))->SetRange (1, 32767);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYNOTE_DURATIONSP))->SetPos (CLIP (1, lValue, 32767));
+ return TRUE;
+}
+
+// トラックインデックスコンボボックス充満
+BOOL CPropertyNoteDlg::FillTrackIndexCombo () {
+ long i = 0;
+ for (i = 0; i < m_theTrackNameArray.GetSize (); i++) {
+ CString strItem;
+ strItem.Format (_T("%d-%s"), i + (m_bTrackZeroOrigin ? 0 : 1), m_theTrackNameArray.GetAt (i));
+ ((CComboBox*)GetDlgItem (IDC_PROPERTYNOTE_TRACKINDEX))->AddString (strItem);
+ }
+ return TRUE;
+}
+
+// キーコンボボックス充満
+BOOL CPropertyNoteDlg::FillKeyCombo () {
+ long i = 0;
+ for (i = 0; i < m_theKeyNameArray.GetSize (); i++) {
+ CString strItem;
+ strItem.Format (_T("%d-%s"), i, m_theKeyNameArray.GetAt (i));
+ ((CComboBox*)GetDlgItem (IDC_PROPERTYNOTE_KEY))->AddString (strItem);
+ }
+ return TRUE;
+}
+
+//******************************************************************************
+// オーバーライド
+//******************************************************************************
+
+// データエクスチェンジ
+void CPropertyNoteDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_CBIndex (pDX, IDC_PROPERTYNOTE_TRACKINDEX, m_nTrackIndex);
+ DDX_Text (pDX, IDC_PROPERTYNOTE_TIME, m_strTime);
+ DDX_Text (pDX, IDC_PROPERTYNOTE_CHANNEL, m_nChannel);
+ DDV_MinMaxInt (pDX, m_nChannel, 1, 16);
+ DDX_CBIndex (pDX, IDC_PROPERTYNOTE_KEY, m_nKey);
+ DDX_Text (pDX, IDC_PROPERTYNOTE_ONVELOCITY, m_nOnVelocity);
+ DDV_MinMaxInt (pDX, m_nOnVelocity, 1, 127);
+ DDX_Text (pDX, IDC_PROPERTYNOTE_OFFVELOCITY, m_nOffVelocity);
+ DDV_MinMaxInt (pDX, m_nOffVelocity, 0, 127);
+ DDX_Text (pDX, IDC_PROPERTYNOTE_DURATION, m_nDuration);
+ DDV_MinMaxInt (pDX, m_nDuration, 1, 65535);
+}
+
+// ダイアログ初期化
+BOOL CPropertyNoteDlg::OnInitDialog () {
+ FillTrackIndexCombo ();
+ FillKeyCombo ();
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetChannelRange ();
+ SetOnVelocityRange ();
+ SetOffVelocityRange ();
+ SetDurationRange ();
+ if (m_bNoteOnNoteOn0) {
+ GetDlgItem (IDC_PROPERTYNOTE_OFFVELOCITY)->EnableWindow (FALSE);
+ GetDlgItem (IDC_PROPERTYNOTE_OFFVELOCITYSP)->EnableWindow (FALSE);
+ }
+ return bRet;
+}
+
+
+//******************************************************************************
+// メッセージマップ
+//******************************************************************************
+
+BEGIN_MESSAGE_MAP (CPropertyNoteDlg, CDialog)
+ ON_CBN_SELENDOK (IDC_PROPERTYNOTE_TRACKINDEX, OnTrackIndexSelEndOK)
+END_MESSAGE_MAP ()
+
+void CPropertyNoteDlg::OnTrackIndexSelEndOK () {
+ int nTrackIndex = ((CComboBox*)GetDlgItem (IDC_PROPERTYNOTE_TRACKINDEX))->GetCurSel ();
+ long lTrackOutputChannel = (long)m_theTrackOutputChannelArray.GetAt (nTrackIndex);
+ if (0 <= lTrackOutputChannel && lTrackOutputChannel < 16) {
+ CString strChannel;
+ strChannel.Format (_T("%d"), lTrackOutputChannel + 1);
+ GetDlgItem (IDC_PROPERTYNOTE_CHANNEL)->SetWindowText (strChannel);
+ }
+}
+
diff --git a/src/PropertyNoteDlg.h b/src/PropertyNoteDlg.h
new file mode 100644
index 0000000..22a6920
--- /dev/null
+++ b/src/PropertyNoteDlg.h
@@ -0,0 +1,75 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティノートダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PROPERTYNOTEDLG_H_
+#define _PROPERTYNOTEDLG_H_
+
+class CPropertyNoteDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ BOOL m_bTrackZeroOrigin; // トラック番号を0から数えるか
+ BOOL m_bNoteOnNoteOn0; // ノートオン+ノートオン(ベロシティ0)か
+ CStringArray m_theTrackNameArray; // トラック名配列
+ CDWordArray m_theTrackOutputChannelArray;// 出力チャンネル配列
+ CStringArray m_theKeyNameArray; // キー名配列
+ int m_nTrackIndex; // トラック
+ CString m_strTime; // タイム
+ int m_nChannel; // チャンネル
+ int m_nKey; // キー
+ int m_nOnVelocity; // 打鍵ベロシティ
+ int m_nOffVelocity; // 離鍵ベロシティ
+ int m_nDuration; // 音長さ
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPropertyNoteDlg(); // コンストラクタ
+ enum {IDD = IDD_PROPERTYNOTE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL SetChannelRange (); // チャンネルの可変範囲設定
+ BOOL SetOnVelocityRange (); // 打鍵ベロシティの可変範囲設定
+ BOOL SetOffVelocityRange (); // 離鍵ベロシティの可変範囲設定
+ BOOL SetDurationRange (); // 音長さの可変範囲設定
+ BOOL FillTrackIndexCombo (); // トラックインデックスコンボボックス充満
+ BOOL FillKeyCombo (); // キーインデックスコンボボックス充満
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void CPropertyNoteDlg::OnTrackIndexSelEndOK ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif \ No newline at end of file
diff --git a/src/PropertyTempoDlg.cpp b/src/PropertyTempoDlg.cpp
new file mode 100644
index 0000000..fb9c5db
--- /dev/null
+++ b/src/PropertyTempoDlg.cpp
@@ -0,0 +1,71 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティテンポダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "PropertyTempoDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//******************************************************************************
+// 構築と破壊
+//******************************************************************************
+
+// コンストラクタ
+CPropertyTempoDlg::CPropertyTempoDlg () : CDialog (CPropertyTempoDlg::IDD) {
+ m_strTime = _T("");
+ //m_dTempoBPM = 120.00;
+ m_strTempoBPM = _T("120.00");
+}
+
+//******************************************************************************
+// オペレーション
+//******************************************************************************
+
+//******************************************************************************
+// オーバーライド
+//******************************************************************************
+
+// データエクスチェンジ
+void CPropertyTempoDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_PROPERTYTEMPO_TIME, m_strTime);
+ DDX_Text (pDX, IDC_PROPERTYTEMPO_TEMPOBPM, m_strTempoBPM);
+}
+
+// ダイアログ初期化
+BOOL CPropertyTempoDlg::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ return bRet;
+}
+
+
+//******************************************************************************
+// メッセージマップ
+//******************************************************************************
+
+BEGIN_MESSAGE_MAP (CPropertyTempoDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
diff --git a/src/PropertyTempoDlg.h b/src/PropertyTempoDlg.h
new file mode 100644
index 0000000..3af99a0
--- /dev/null
+++ b/src/PropertyTempoDlg.h
@@ -0,0 +1,58 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティテンポダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PROPERTYTEMPODLG_H_
+#define _PROPERTYTEMPODLG_H_
+
+class CPropertyTempoDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strTime; // タイム
+ CString m_strTempoBPM; // テンポ[BPM]
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPropertyTempoDlg(); // コンストラクタ
+ enum {IDD = IDD_PROPERTYTEMPO};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ();
+};
+
+#endif \ No newline at end of file
diff --git a/src/PropertyTimeSignatureDlg.cpp b/src/PropertyTimeSignatureDlg.cpp
new file mode 100644
index 0000000..ed86e86
--- /dev/null
+++ b/src/PropertyTimeSignatureDlg.cpp
@@ -0,0 +1,125 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティ拍子記号ダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include "resource.h"
+#include "PropertyTimeSignatureDlg.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//******************************************************************************
+// 構築と破壊
+//******************************************************************************
+
+// コンストラクタ
+CPropertyTimeSignatureDlg::CPropertyTimeSignatureDlg () : CDialog (CPropertyTimeSignatureDlg::IDD) {
+ m_strTime = _T("");
+ m_lNN = 4;
+ m_nDDIndex = 2;
+ m_lCC = 24;
+ m_lBB = 8;
+}
+
+//******************************************************************************
+// オペレーション
+//******************************************************************************
+
+// 分子可変範囲設定
+BOOL CPropertyTimeSignatureDlg::SetNNRange () {
+ CString strValue;
+ GetDlgItem (IDC_PROPERTYTIMESIGNATURE_NN)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYTIMESIGNATURE_NNSP))->SetRange (1, 255);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYTIMESIGNATURE_NNSP))->SetPos (CLIP (1, lValue, 255));
+ return TRUE;
+}
+
+// 分母コンボボックス充満(1,2,4,8,16,32とする)
+BOOL CPropertyTimeSignatureDlg::FillDDIndexCombo () {
+ long i = 0;
+ for (i = 0; i <= 5; i++) {
+ CString strItem;
+ strItem.Format (_T("%d"), 1 << i);
+ ((CComboBox*)GetDlgItem (IDC_PROPERTYTIMESIGNATURE_DDINDEX))->AddString (strItem);
+ }
+ return TRUE;
+}
+
+// 4分音符当たりのクロック数可変範囲設定
+BOOL CPropertyTimeSignatureDlg::SetCCRange () {
+ CString strValue;
+ GetDlgItem (IDC_PROPERTYTIMESIGNATURE_CC)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYTIMESIGNATURE_CCSP))->SetRange (1, 255);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYTIMESIGNATURE_CCSP))->SetPos (CLIP (1, lValue, 255));
+ return TRUE;
+}
+
+// 4分音符当たりの32分音符の数可変範囲設定
+BOOL CPropertyTimeSignatureDlg::SetBBRange () {
+ CString strValue;
+ GetDlgItem (IDC_PROPERTYTIMESIGNATURE_BB)->GetWindowText (strValue);
+ long lValue = _ttol (strValue);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYTIMESIGNATURE_BBSP))->SetRange (1, 255);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_PROPERTYTIMESIGNATURE_BBSP))->SetPos (CLIP (1, lValue, 255));
+ return TRUE;
+}
+
+
+//******************************************************************************
+// オーバーライド
+//******************************************************************************
+
+// データエクスチェンジ
+void CPropertyTimeSignatureDlg::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_CBIndex (pDX, IDC_PROPERTYTIMESIGNATURE_DDINDEX, m_nDDIndex);
+ DDX_Text (pDX, IDC_PROPERTYTIMESIGNATURE_TIME, m_strTime);
+ DDX_Text (pDX, IDC_PROPERTYTIMESIGNATURE_NN, m_lNN);
+ DDV_MinMaxLong (pDX, m_lNN, 1, 255);
+ DDX_Text (pDX, IDC_PROPERTYTIMESIGNATURE_CC, m_lCC);
+ DDV_MinMaxLong (pDX, m_lCC, 1, 255);
+ DDX_Text (pDX, IDC_PROPERTYTIMESIGNATURE_BB, m_lBB);
+ DDV_MinMaxLong (pDX, m_lBB, 1, 255);
+}
+
+// ダイアログ初期化
+BOOL CPropertyTimeSignatureDlg::OnInitDialog () {
+ FillDDIndexCombo ();
+ BOOL bRet = CDialog::OnInitDialog ();
+ SetNNRange ();
+ SetCCRange ();
+ SetBBRange ();
+ return bRet;
+}
+
+
+//******************************************************************************
+// メッセージマップ
+//******************************************************************************
+
+BEGIN_MESSAGE_MAP (CPropertyTimeSignatureDlg, CDialog)
+END_MESSAGE_MAP ()
+
+
diff --git a/src/PropertyTimeSignatureDlg.h b/src/PropertyTimeSignatureDlg.h
new file mode 100644
index 0000000..9a9c267
--- /dev/null
+++ b/src/PropertyTimeSignatureDlg.h
@@ -0,0 +1,65 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// プロパティ拍子記号ダイアログクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _PROPERTYTIMESIGNATUREDLG_H_
+#define _PROPERTYTIMESIGNATUREDLG_H_
+
+class CPropertyTimeSignatureDlg : public CDialog {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strTime; // タイム
+ long m_lNN; // 分子(1〜255)
+ int m_nDDIndex; // 分母(0=1,2=2,3=4,4=8,5=16,6=32)
+ long m_lCC; // 4分音符当たりのクロック数(常に24,1〜255)
+ long m_lBB; // 4分音符当たりの32分音符の数(常に8,1〜255)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CPropertyTimeSignatureDlg(); // コンストラクタ
+ enum {IDD = IDD_PROPERTYTIMESIGNATURE};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ BOOL CPropertyTimeSignatureDlg::SetNNRange ();
+ BOOL CPropertyTimeSignatureDlg::FillDDIndexCombo ();
+ BOOL CPropertyTimeSignatureDlg::SetCCRange ();
+ BOOL CPropertyTimeSignatureDlg::SetBBRange ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog (); // ダイアログの初期化
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ();
+};
+
+#endif \ No newline at end of file
diff --git a/src/Resource.h b/src/Resource.h
new file mode 100644
index 0000000..920e37b
--- /dev/null
+++ b/src/Resource.h
@@ -0,0 +1,1796 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// リソースID定義ヘッダーファイル
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+//-----------------------------------------------------------------------------
+// ツールバー・カーソル・ビットマップ・アイコン・アクセラレーター共通 0x0000〜0x0FFF
+//-----------------------------------------------------------------------------
+
+#define IDR_MAINFRAME 0x0001
+#define IDR_SEKAIJUTYPE 0x0002
+#define IDR_MAINFRAME1 0x0011
+#define IDR_MAINFRAME2 0x0012
+#define IDR_TRACKLIST 0x0020
+#define IDR_TRACKLIST1 0x0021
+#define IDR_PIANOROLL 0x0030
+#define IDR_PIANOROLL1 0x0031
+#define IDR_EVENTLIST 0x0040
+#define IDR_EVENTLIST1 0x0041
+#define IDR_MUSICALSCORE 0x0050
+#define IDR_MUSICALSCORE1 0x0051
+#define IDC_SIZEALLCOPY 0x0301
+#define IDC_RESIZEWE 0x0302
+#define IDC_RESIZENS 0x0303
+#define IDC_RESIZEALL 0x0304
+#define IDC_DRAW 0x0305
+#define IDC_LINE 0x0306
+#define IDC_ERASER 0x0307
+#define IDC_SELECT 0x0308
+#define IDC_SELECTADD 0x0309
+#define IDC_SELECT2 0x030A
+#define IDC_SELECTADD2 0x030B
+#define IDC_SPEAKER 0x031C
+#define IDR_POPUPMENU00 0x0800
+#define IDR_POPUPMENU01 0x0801
+#define IDR_POPUPMENU02 0x0802
+#define IDR_POPUPMENU03 0x0803
+#define IDR_POPUPMENU10 0x0810
+#define IDR_POPUPMENU11 0x0811
+#define IDR_POPUPMENU13 0x0813
+#define IDR_POPUPMENU15 0x0815
+#define IDR_POPUPMENU20 0x0820
+#define IDR_POPUPMENU21 0x0821
+#define IDR_POPUPMENU23 0x0823
+#define IDR_POPUPMENU24 0x0824
+#define IDR_POPUPMENU30 0x0830
+#define IDR_POPUPMENU31 0x0831
+#define IDR_POPUPMENU33 0x0833
+
+
+//-----------------------------------------------------------------------------
+// MIDI用語専用文字列 0x1000〜0x1FFF
+//-----------------------------------------------------------------------------
+
+#define IDS_EVENTKIND_00 0x1000
+#define IDS_EVENTKIND_01 0x1001
+#define IDS_EVENTKIND_02 0x1002
+#define IDS_EVENTKIND_03 0x1003
+#define IDS_EVENTKIND_04 0x1004
+#define IDS_EVENTKIND_05 0x1005
+#define IDS_EVENTKIND_06 0x1006
+#define IDS_EVENTKIND_07 0x1007
+#define IDS_EVENTKIND_08 0x1008
+#define IDS_EVENTKIND_09 0x1009
+#define IDS_EVENTKIND_0A 0x100A
+#define IDS_EVENTKIND_0B 0x100B
+#define IDS_EVENTKIND_0C 0x100C
+#define IDS_EVENTKIND_0D 0x100D
+#define IDS_EVENTKIND_0E 0x100E
+#define IDS_EVENTKIND_0F 0x100F
+
+#define IDS_EVENTKIND_10 0x1010
+#define IDS_EVENTKIND_11 0x1011
+#define IDS_EVENTKIND_12 0x1012
+#define IDS_EVENTKIND_13 0x1013
+#define IDS_EVENTKIND_14 0x1014
+#define IDS_EVENTKIND_15 0x1015
+#define IDS_EVENTKIND_16 0x1016
+#define IDS_EVENTKIND_17 0x1017
+#define IDS_EVENTKIND_18 0x1018
+#define IDS_EVENTKIND_19 0x1019
+#define IDS_EVENTKIND_1A 0x101A
+#define IDS_EVENTKIND_1B 0x101B
+#define IDS_EVENTKIND_1C 0x101C
+#define IDS_EVENTKIND_1D 0x101D
+#define IDS_EVENTKIND_1E 0x101E
+#define IDS_EVENTKIND_1F 0x101F
+
+#define IDS_EVENTKIND_20 0x1020
+#define IDS_EVENTKIND_21 0x1021
+#define IDS_EVENTKIND_22 0x1022
+#define IDS_EVENTKIND_23 0x1023
+#define IDS_EVENTKIND_24 0x1024
+#define IDS_EVENTKIND_25 0x1025
+#define IDS_EVENTKIND_26 0x1026
+#define IDS_EVENTKIND_27 0x1027
+#define IDS_EVENTKIND_28 0x1028
+#define IDS_EVENTKIND_29 0x1029
+#define IDS_EVENTKIND_2A 0x102A
+#define IDS_EVENTKIND_2B 0x102B
+#define IDS_EVENTKIND_2C 0x102C
+#define IDS_EVENTKIND_2D 0x102D
+#define IDS_EVENTKIND_2E 0x102E
+#define IDS_EVENTKIND_2F 0x102F
+
+#define IDS_EVENTKIND_30 0x1030
+#define IDS_EVENTKIND_31 0x1031
+#define IDS_EVENTKIND_32 0x1032
+#define IDS_EVENTKIND_33 0x1033
+#define IDS_EVENTKIND_34 0x1034
+#define IDS_EVENTKIND_35 0x1035
+#define IDS_EVENTKIND_36 0x1036
+#define IDS_EVENTKIND_37 0x1037
+#define IDS_EVENTKIND_38 0x1038
+#define IDS_EVENTKIND_39 0x1039
+#define IDS_EVENTKIND_3A 0x103A
+#define IDS_EVENTKIND_3B 0x103B
+#define IDS_EVENTKIND_3C 0x103C
+#define IDS_EVENTKIND_3D 0x103D
+#define IDS_EVENTKIND_3E 0x103E
+#define IDS_EVENTKIND_3F 0x103F
+
+#define IDS_EVENTKIND_40 0x1040
+#define IDS_EVENTKIND_41 0x1041
+#define IDS_EVENTKIND_42 0x1042
+#define IDS_EVENTKIND_43 0x1043
+#define IDS_EVENTKIND_44 0x1044
+#define IDS_EVENTKIND_45 0x1045
+#define IDS_EVENTKIND_46 0x1046
+#define IDS_EVENTKIND_47 0x1047
+#define IDS_EVENTKIND_48 0x1048
+#define IDS_EVENTKIND_49 0x1049
+#define IDS_EVENTKIND_4A 0x104A
+#define IDS_EVENTKIND_4B 0x104B
+#define IDS_EVENTKIND_4C 0x104C
+#define IDS_EVENTKIND_4D 0x104D
+#define IDS_EVENTKIND_4E 0x104E
+#define IDS_EVENTKIND_4F 0x104F
+
+#define IDS_EVENTKIND_50 0x1050
+#define IDS_EVENTKIND_51 0x1051
+#define IDS_EVENTKIND_52 0x1052
+#define IDS_EVENTKIND_53 0x1053
+#define IDS_EVENTKIND_54 0x1054
+#define IDS_EVENTKIND_55 0x1055
+#define IDS_EVENTKIND_56 0x1056
+#define IDS_EVENTKIND_57 0x1057
+#define IDS_EVENTKIND_58 0x1058
+#define IDS_EVENTKIND_59 0x1059
+#define IDS_EVENTKIND_5A 0x105A
+#define IDS_EVENTKIND_5B 0x105B
+#define IDS_EVENTKIND_5C 0x105C
+#define IDS_EVENTKIND_5D 0x105D
+#define IDS_EVENTKIND_5E 0x105E
+#define IDS_EVENTKIND_5F 0x105F
+
+#define IDS_EVENTKIND_60 0x1060
+#define IDS_EVENTKIND_61 0x1061
+#define IDS_EVENTKIND_62 0x1062
+#define IDS_EVENTKIND_63 0x1063
+#define IDS_EVENTKIND_64 0x1064
+#define IDS_EVENTKIND_65 0x1065
+#define IDS_EVENTKIND_66 0x1066
+#define IDS_EVENTKIND_67 0x1067
+#define IDS_EVENTKIND_68 0x1068
+#define IDS_EVENTKIND_69 0x1069
+#define IDS_EVENTKIND_6A 0x106A
+#define IDS_EVENTKIND_6B 0x106B
+#define IDS_EVENTKIND_6C 0x106C
+#define IDS_EVENTKIND_6D 0x106D
+#define IDS_EVENTKIND_6E 0x106E
+#define IDS_EVENTKIND_6F 0x106F
+
+#define IDS_EVENTKIND_70 0x1070
+#define IDS_EVENTKIND_71 0x1071
+#define IDS_EVENTKIND_72 0x1072
+#define IDS_EVENTKIND_73 0x1073
+#define IDS_EVENTKIND_74 0x1074
+#define IDS_EVENTKIND_75 0x1075
+#define IDS_EVENTKIND_76 0x1076
+#define IDS_EVENTKIND_77 0x1077
+#define IDS_EVENTKIND_78 0x1078
+#define IDS_EVENTKIND_79 0x1079
+#define IDS_EVENTKIND_7A 0x107A
+#define IDS_EVENTKIND_7B 0x107B
+#define IDS_EVENTKIND_7C 0x107C
+#define IDS_EVENTKIND_7D 0x107D
+#define IDS_EVENTKIND_7E 0x107E
+#define IDS_EVENTKIND_7F 0x107F
+
+#define IDS_EVENTKIND_80 0x1080
+#define IDS_EVENTKIND_81 0x1081
+#define IDS_EVENTKIND_82 0x1082
+#define IDS_EVENTKIND_83 0x1083
+#define IDS_EVENTKIND_84 0x1084
+#define IDS_EVENTKIND_85 0x1085
+#define IDS_EVENTKIND_86 0x1086
+#define IDS_EVENTKIND_87 0x1087
+#define IDS_EVENTKIND_88 0x1088
+#define IDS_EVENTKIND_89 0x1089
+#define IDS_EVENTKIND_8A 0x108A
+#define IDS_EVENTKIND_8B 0x108B
+#define IDS_EVENTKIND_8C 0x108C
+#define IDS_EVENTKIND_8D 0x108D
+#define IDS_EVENTKIND_8E 0x108E
+#define IDS_EVENTKIND_8F 0x108F
+
+
+#define IDS_EVENTKIND_90 0x1090
+#define IDS_EVENTKIND_91 0x1091
+#define IDS_EVENTKIND_92 0x1092
+#define IDS_EVENTKIND_93 0x1093
+#define IDS_EVENTKIND_94 0x1094
+#define IDS_EVENTKIND_95 0x1095
+#define IDS_EVENTKIND_96 0x1096
+#define IDS_EVENTKIND_97 0x1097
+#define IDS_EVENTKIND_98 0x1098
+#define IDS_EVENTKIND_99 0x1099
+#define IDS_EVENTKIND_9A 0x109A
+#define IDS_EVENTKIND_9B 0x109B
+#define IDS_EVENTKIND_9C 0x109C
+#define IDS_EVENTKIND_9D 0x109D
+#define IDS_EVENTKIND_9E 0x109E
+#define IDS_EVENTKIND_9F 0x109F
+
+#define IDS_EVENTKIND_A0 0x10A0
+#define IDS_EVENTKIND_A1 0x10A1
+#define IDS_EVENTKIND_A2 0x10A2
+#define IDS_EVENTKIND_A3 0x10A3
+#define IDS_EVENTKIND_A4 0x10A4
+#define IDS_EVENTKIND_A5 0x10A5
+#define IDS_EVENTKIND_A6 0x10A6
+#define IDS_EVENTKIND_A7 0x10A7
+#define IDS_EVENTKIND_A8 0x10A8
+#define IDS_EVENTKIND_A9 0x10A9
+#define IDS_EVENTKIND_AA 0x10AA
+#define IDS_EVENTKIND_AB 0x10AB
+#define IDS_EVENTKIND_AC 0x10AC
+#define IDS_EVENTKIND_AD 0x10AD
+#define IDS_EVENTKIND_AE 0x10AE
+#define IDS_EVENTKIND_AF 0x10AF
+
+#define IDS_EVENTKIND_B0 0x10B0
+#define IDS_EVENTKIND_B1 0x10B1
+#define IDS_EVENTKIND_B2 0x10B2
+#define IDS_EVENTKIND_B3 0x10B3
+#define IDS_EVENTKIND_B4 0x10B4
+#define IDS_EVENTKIND_B5 0x10B5
+#define IDS_EVENTKIND_B6 0x10B6
+#define IDS_EVENTKIND_B7 0x10B7
+#define IDS_EVENTKIND_B8 0x10B8
+#define IDS_EVENTKIND_B9 0x10B9
+#define IDS_EVENTKIND_BA 0x10BA
+#define IDS_EVENTKIND_BB 0x10BB
+#define IDS_EVENTKIND_BC 0x10BC
+#define IDS_EVENTKIND_BD 0x10BD
+#define IDS_EVENTKIND_BE 0x10BE
+#define IDS_EVENTKIND_BF 0x10BF
+
+#define IDS_EVENTKIND_C0 0x10C0
+#define IDS_EVENTKIND_C1 0x10C1
+#define IDS_EVENTKIND_C2 0x10C2
+#define IDS_EVENTKIND_C3 0x10C3
+#define IDS_EVENTKIND_C4 0x10C4
+#define IDS_EVENTKIND_C5 0x10C5
+#define IDS_EVENTKIND_C6 0x10C6
+#define IDS_EVENTKIND_C7 0x10C7
+#define IDS_EVENTKIND_C8 0x10C8
+#define IDS_EVENTKIND_C9 0x10C9
+#define IDS_EVENTKIND_CA 0x10CA
+#define IDS_EVENTKIND_CB 0x10CB
+#define IDS_EVENTKIND_CC 0x10CC
+#define IDS_EVENTKIND_CD 0x10CD
+#define IDS_EVENTKIND_CE 0x10CE
+#define IDS_EVENTKIND_CF 0x10CF
+
+#define IDS_EVENTKIND_D0 0x10D0
+#define IDS_EVENTKIND_D1 0x10D1
+#define IDS_EVENTKIND_D2 0x10D2
+#define IDS_EVENTKIND_D3 0x10D3
+#define IDS_EVENTKIND_D4 0x10D4
+#define IDS_EVENTKIND_D5 0x10D5
+#define IDS_EVENTKIND_D6 0x10D6
+#define IDS_EVENTKIND_D7 0x10D7
+#define IDS_EVENTKIND_D8 0x10D8
+#define IDS_EVENTKIND_D9 0x10D9
+#define IDS_EVENTKIND_DA 0x10DA
+#define IDS_EVENTKIND_DB 0x10DB
+#define IDS_EVENTKIND_DC 0x10DC
+#define IDS_EVENTKIND_DD 0x10DD
+#define IDS_EVENTKIND_DE 0x10DE
+#define IDS_EVENTKIND_DF 0x10DF
+
+#define IDS_EVENTKIND_E0 0x10E0
+#define IDS_EVENTKIND_E1 0x10E1
+#define IDS_EVENTKIND_E2 0x10E2
+#define IDS_EVENTKIND_E3 0x10E3
+#define IDS_EVENTKIND_E4 0x10E4
+#define IDS_EVENTKIND_E5 0x10E5
+#define IDS_EVENTKIND_E6 0x10E6
+#define IDS_EVENTKIND_E7 0x10E7
+#define IDS_EVENTKIND_E8 0x10E8
+#define IDS_EVENTKIND_E9 0x10E9
+#define IDS_EVENTKIND_EA 0x10EA
+#define IDS_EVENTKIND_EB 0x10EB
+#define IDS_EVENTKIND_EC 0x10EC
+#define IDS_EVENTKIND_ED 0x10ED
+#define IDS_EVENTKIND_EE 0x10EE
+#define IDS_EVENTKIND_EF 0x10EF
+
+#define IDS_EVENTKIND_F0 0x10F0
+#define IDS_EVENTKIND_F1 0x10F1
+#define IDS_EVENTKIND_F2 0x10F2
+#define IDS_EVENTKIND_F3 0x10F3
+#define IDS_EVENTKIND_F4 0x10F4
+#define IDS_EVENTKIND_F5 0x10F5
+#define IDS_EVENTKIND_F6 0x10F6
+#define IDS_EVENTKIND_F7 0x10F7
+#define IDS_EVENTKIND_F8 0x10F8
+#define IDS_EVENTKIND_F9 0x10F9
+#define IDS_EVENTKIND_FA 0x10FA
+#define IDS_EVENTKIND_FB 0x10FB
+#define IDS_EVENTKIND_FC 0x10FC
+#define IDS_EVENTKIND_FD 0x10FD
+#define IDS_EVENTKIND_FE 0x10FE
+#define IDS_EVENTKIND_FF 0x10FF
+
+#define IDS_NOTEKEY_0S00 0x1100
+#define IDS_NOTEKEY_0S01 0x1101
+#define IDS_NOTEKEY_0S02 0x1102
+#define IDS_NOTEKEY_0S03 0x1103
+#define IDS_NOTEKEY_0S04 0x1104
+#define IDS_NOTEKEY_0S05 0x1105
+#define IDS_NOTEKEY_0S06 0x1106
+#define IDS_NOTEKEY_0S07 0x1107
+#define IDS_NOTEKEY_0S08 0x1108
+#define IDS_NOTEKEY_0S09 0x1109
+#define IDS_NOTEKEY_0S10 0x110A
+#define IDS_NOTEKEY_0S11 0x110B
+#define IDS_NOTEKEY_0S12 0x110C
+#define IDS_NOTEKEY_0S13 0x110D
+#define IDS_NOTEKEY_0S14 0x110E
+#define IDS_NOTEKEY_0S15 0x110F
+
+#define IDS_NOTEKEY_1S00 0x1110
+#define IDS_NOTEKEY_1S01 0x1111
+#define IDS_NOTEKEY_1S02 0x1112
+#define IDS_NOTEKEY_1S03 0x1113
+#define IDS_NOTEKEY_1S04 0x1114
+#define IDS_NOTEKEY_1S05 0x1115
+#define IDS_NOTEKEY_1S06 0x1116
+#define IDS_NOTEKEY_1S07 0x1117
+#define IDS_NOTEKEY_1S08 0x1118
+#define IDS_NOTEKEY_1S09 0x1119
+#define IDS_NOTEKEY_1S10 0x111A
+#define IDS_NOTEKEY_1S11 0x111B
+#define IDS_NOTEKEY_1S12 0x111C
+#define IDS_NOTEKEY_1S13 0x111D
+#define IDS_NOTEKEY_1S14 0x111E
+#define IDS_NOTEKEY_1S15 0x111F
+
+#define IDS_NOTEKEY_2S00 0x1120
+#define IDS_NOTEKEY_2S01 0x1121
+#define IDS_NOTEKEY_2S02 0x1122
+#define IDS_NOTEKEY_2S03 0x1123
+#define IDS_NOTEKEY_2S04 0x1124
+#define IDS_NOTEKEY_2S05 0x1125
+#define IDS_NOTEKEY_2S06 0x1126
+#define IDS_NOTEKEY_2S07 0x1127
+#define IDS_NOTEKEY_2S08 0x1128
+#define IDS_NOTEKEY_2S09 0x1129
+#define IDS_NOTEKEY_2S10 0x112A
+#define IDS_NOTEKEY_2S11 0x112B
+#define IDS_NOTEKEY_2S12 0x112C
+#define IDS_NOTEKEY_2S13 0x112D
+#define IDS_NOTEKEY_2S14 0x112E
+#define IDS_NOTEKEY_2S15 0x112F
+
+#define IDS_NOTEKEY_3S00 0x1130
+#define IDS_NOTEKEY_3S01 0x1131
+#define IDS_NOTEKEY_3S02 0x1132
+#define IDS_NOTEKEY_3S03 0x1133
+#define IDS_NOTEKEY_3S04 0x1134
+#define IDS_NOTEKEY_3S05 0x1135
+#define IDS_NOTEKEY_3S06 0x1136
+#define IDS_NOTEKEY_3S07 0x1137
+#define IDS_NOTEKEY_3S08 0x1138
+#define IDS_NOTEKEY_3S09 0x1139
+#define IDS_NOTEKEY_3S10 0x113A
+#define IDS_NOTEKEY_3S11 0x113B
+#define IDS_NOTEKEY_3S12 0x113C
+#define IDS_NOTEKEY_3S13 0x113D
+#define IDS_NOTEKEY_3S14 0x113E
+#define IDS_NOTEKEY_3S15 0x113F
+
+#define IDS_NOTEKEY_4S00 0x1140
+#define IDS_NOTEKEY_4S01 0x1141
+#define IDS_NOTEKEY_4S02 0x1142
+#define IDS_NOTEKEY_4S03 0x1143
+#define IDS_NOTEKEY_4S04 0x1144
+#define IDS_NOTEKEY_4S05 0x1145
+#define IDS_NOTEKEY_4S06 0x1146
+#define IDS_NOTEKEY_4S07 0x1147
+#define IDS_NOTEKEY_4S08 0x1148
+#define IDS_NOTEKEY_4S09 0x1149
+#define IDS_NOTEKEY_4S10 0x114A
+#define IDS_NOTEKEY_4S11 0x114B
+#define IDS_NOTEKEY_4S12 0x114C
+#define IDS_NOTEKEY_4S13 0x114D
+#define IDS_NOTEKEY_4S14 0x114E
+#define IDS_NOTEKEY_4S15 0x114F
+
+#define IDS_NOTEKEY_5S00 0x1150
+#define IDS_NOTEKEY_5S01 0x1151
+#define IDS_NOTEKEY_5S02 0x1152
+#define IDS_NOTEKEY_5S03 0x1153
+#define IDS_NOTEKEY_5S04 0x1154
+#define IDS_NOTEKEY_5S05 0x1155
+#define IDS_NOTEKEY_5S06 0x1156
+#define IDS_NOTEKEY_5S07 0x1157
+#define IDS_NOTEKEY_5S08 0x1158
+#define IDS_NOTEKEY_5S09 0x1159
+#define IDS_NOTEKEY_5S10 0x115A
+#define IDS_NOTEKEY_5S11 0x115B
+#define IDS_NOTEKEY_5S12 0x115C
+#define IDS_NOTEKEY_5S13 0x115D
+#define IDS_NOTEKEY_5S14 0x115E
+#define IDS_NOTEKEY_5S15 0x115F
+
+#define IDS_NOTEKEY_6S00 0x1160
+#define IDS_NOTEKEY_6S01 0x1161
+#define IDS_NOTEKEY_6S02 0x1162
+#define IDS_NOTEKEY_6S03 0x1163
+#define IDS_NOTEKEY_6S04 0x1164
+#define IDS_NOTEKEY_6S05 0x1165
+#define IDS_NOTEKEY_6S06 0x1166
+#define IDS_NOTEKEY_6S07 0x1167
+#define IDS_NOTEKEY_6S08 0x1168
+#define IDS_NOTEKEY_6S09 0x1169
+#define IDS_NOTEKEY_6S10 0x116A
+#define IDS_NOTEKEY_6S11 0x116B
+#define IDS_NOTEKEY_6S12 0x116C
+#define IDS_NOTEKEY_6S13 0x116D
+#define IDS_NOTEKEY_6S14 0x116E
+#define IDS_NOTEKEY_6S15 0x116F
+
+#define IDS_NOTEKEY_7S00 0x1170
+#define IDS_NOTEKEY_7S01 0x1171
+#define IDS_NOTEKEY_7S02 0x1172
+#define IDS_NOTEKEY_7S03 0x1173
+#define IDS_NOTEKEY_7S04 0x1174
+#define IDS_NOTEKEY_7S05 0x1175
+#define IDS_NOTEKEY_7S06 0x1176
+#define IDS_NOTEKEY_7S07 0x1177
+#define IDS_NOTEKEY_7S08 0x1178
+#define IDS_NOTEKEY_7S09 0x1179
+#define IDS_NOTEKEY_7S10 0x117A
+#define IDS_NOTEKEY_7S11 0x117B
+#define IDS_NOTEKEY_7S12 0x117C
+#define IDS_NOTEKEY_7S13 0x117D
+#define IDS_NOTEKEY_7S14 0x117E
+#define IDS_NOTEKEY_7S15 0x117F
+
+#define IDS_NOTEKEY_8F00 0x1180
+#define IDS_NOTEKEY_8F01 0x1181
+#define IDS_NOTEKEY_8F02 0x1182
+#define IDS_NOTEKEY_8F03 0x1183
+#define IDS_NOTEKEY_8F04 0x1184
+#define IDS_NOTEKEY_8F05 0x1185
+#define IDS_NOTEKEY_8F06 0x1186
+#define IDS_NOTEKEY_8F07 0x1187
+#define IDS_NOTEKEY_8F08 0x1188
+#define IDS_NOTEKEY_8F09 0x1189
+#define IDS_NOTEKEY_8F10 0x118A
+#define IDS_NOTEKEY_8F11 0x118B
+#define IDS_NOTEKEY_8F12 0x118C
+#define IDS_NOTEKEY_8F13 0x118D
+#define IDS_NOTEKEY_8F14 0x118E
+#define IDS_NOTEKEY_8F15 0x118F
+
+#define IDS_NOTEKEY_7F00 0x1190
+#define IDS_NOTEKEY_7F01 0x1191
+#define IDS_NOTEKEY_7F02 0x1192
+#define IDS_NOTEKEY_7F03 0x1193
+#define IDS_NOTEKEY_7F04 0x1194
+#define IDS_NOTEKEY_7F05 0x1195
+#define IDS_NOTEKEY_7F06 0x1196
+#define IDS_NOTEKEY_7F07 0x1197
+#define IDS_NOTEKEY_7F08 0x1198
+#define IDS_NOTEKEY_7F09 0x1199
+#define IDS_NOTEKEY_7F10 0x119A
+#define IDS_NOTEKEY_7F11 0x119B
+#define IDS_NOTEKEY_7F12 0x119C
+#define IDS_NOTEKEY_7F13 0x119D
+#define IDS_NOTEKEY_7F14 0x119E
+#define IDS_NOTEKEY_7F15 0x119F
+
+#define IDS_NOTEKEY_6F00 0x11A0
+#define IDS_NOTEKEY_6F01 0x11A1
+#define IDS_NOTEKEY_6F02 0x11A2
+#define IDS_NOTEKEY_6F03 0x11A3
+#define IDS_NOTEKEY_6F04 0x11A4
+#define IDS_NOTEKEY_6F05 0x11A5
+#define IDS_NOTEKEY_6F06 0x11A6
+#define IDS_NOTEKEY_6F07 0x11A7
+#define IDS_NOTEKEY_6F08 0x11A8
+#define IDS_NOTEKEY_6F09 0x11A9
+#define IDS_NOTEKEY_6F10 0x11AA
+#define IDS_NOTEKEY_6F11 0x11AB
+#define IDS_NOTEKEY_6F12 0x11AC
+#define IDS_NOTEKEY_6F13 0x11AD
+#define IDS_NOTEKEY_6F14 0x11AE
+#define IDS_NOTEKEY_6F15 0x11AF
+
+#define IDS_NOTEKEY_5F00 0x11B0
+#define IDS_NOTEKEY_5F01 0x11B1
+#define IDS_NOTEKEY_5F02 0x11B2
+#define IDS_NOTEKEY_5F03 0x11B3
+#define IDS_NOTEKEY_5F04 0x11B4
+#define IDS_NOTEKEY_5F05 0x11B5
+#define IDS_NOTEKEY_5F06 0x11B6
+#define IDS_NOTEKEY_5F07 0x11B7
+#define IDS_NOTEKEY_5F08 0x11B8
+#define IDS_NOTEKEY_5F09 0x11B9
+#define IDS_NOTEKEY_5F10 0x11BA
+#define IDS_NOTEKEY_5F11 0x11BB
+#define IDS_NOTEKEY_5F12 0x11BC
+#define IDS_NOTEKEY_5F13 0x11BD
+#define IDS_NOTEKEY_5F14 0x11BE
+#define IDS_NOTEKEY_5F15 0x11BF
+
+#define IDS_NOTEKEY_4F00 0x11C0
+#define IDS_NOTEKEY_4F01 0x11C1
+#define IDS_NOTEKEY_4F02 0x11C2
+#define IDS_NOTEKEY_4F03 0x11C3
+#define IDS_NOTEKEY_4F04 0x11C4
+#define IDS_NOTEKEY_4F05 0x11C5
+#define IDS_NOTEKEY_4F06 0x11C6
+#define IDS_NOTEKEY_4F07 0x11C7
+#define IDS_NOTEKEY_4F08 0x11C8
+#define IDS_NOTEKEY_4F09 0x11C9
+#define IDS_NOTEKEY_4F10 0x11CA
+#define IDS_NOTEKEY_4F11 0x11CB
+#define IDS_NOTEKEY_4F12 0x11CC
+#define IDS_NOTEKEY_4F13 0x11CD
+#define IDS_NOTEKEY_4F14 0x11CE
+#define IDS_NOTEKEY_4F15 0x11CF
+
+#define IDS_NOTEKEY_3F00 0x11D0
+#define IDS_NOTEKEY_3F01 0x11D1
+#define IDS_NOTEKEY_3F02 0x11D2
+#define IDS_NOTEKEY_3F03 0x11D3
+#define IDS_NOTEKEY_3F04 0x11D4
+#define IDS_NOTEKEY_3F05 0x11D5
+#define IDS_NOTEKEY_3F06 0x11D6
+#define IDS_NOTEKEY_3F07 0x11D7
+#define IDS_NOTEKEY_3F08 0x11D8
+#define IDS_NOTEKEY_3F09 0x11D9
+#define IDS_NOTEKEY_3F10 0x11DA
+#define IDS_NOTEKEY_3F11 0x11DB
+#define IDS_NOTEKEY_3F12 0x11DC
+#define IDS_NOTEKEY_3F13 0x11DD
+#define IDS_NOTEKEY_3F14 0x11DE
+#define IDS_NOTEKEY_3F15 0x11DF
+
+#define IDS_NOTEKEY_2F00 0x11E0
+#define IDS_NOTEKEY_2F01 0x11E1
+#define IDS_NOTEKEY_2F02 0x11E2
+#define IDS_NOTEKEY_2F03 0x11E3
+#define IDS_NOTEKEY_2F04 0x11E4
+#define IDS_NOTEKEY_2F05 0x11E5
+#define IDS_NOTEKEY_2F06 0x11E6
+#define IDS_NOTEKEY_2F07 0x11E7
+#define IDS_NOTEKEY_2F08 0x11E8
+#define IDS_NOTEKEY_2F09 0x11E9
+#define IDS_NOTEKEY_2F10 0x11EA
+#define IDS_NOTEKEY_2F11 0x11EB
+#define IDS_NOTEKEY_2F12 0x11EC
+#define IDS_NOTEKEY_2F13 0x11ED
+#define IDS_NOTEKEY_2F14 0x11EE
+#define IDS_NOTEKEY_2F15 0x11EF
+
+#define IDS_NOTEKEY_1F00 0x11F0
+#define IDS_NOTEKEY_1F01 0x11F1
+#define IDS_NOTEKEY_1F02 0x11F2
+#define IDS_NOTEKEY_1F03 0x11F3
+#define IDS_NOTEKEY_1F04 0x11F4
+#define IDS_NOTEKEY_1F05 0x11F5
+#define IDS_NOTEKEY_1F06 0x11F6
+#define IDS_NOTEKEY_1F07 0x11F7
+#define IDS_NOTEKEY_1F08 0x11F8
+#define IDS_NOTEKEY_1F09 0x11F9
+#define IDS_NOTEKEY_1F10 0x11FA
+#define IDS_NOTEKEY_1F11 0x11FB
+#define IDS_NOTEKEY_1F12 0x11FC
+#define IDS_NOTEKEY_1F13 0x11FD
+#define IDS_NOTEKEY_1F14 0x11FE
+#define IDS_NOTEKEY_1F15 0x11FF
+
+#define IDS_KEYSIGNATURE_0MA 0x1200
+#define IDS_KEYSIGNATURE_1SMA 0x1201
+#define IDS_KEYSIGNATURE_2SMA 0x1202
+#define IDS_KEYSIGNATURE_3SMA 0x1203
+#define IDS_KEYSIGNATURE_4SMA 0x1204
+#define IDS_KEYSIGNATURE_5SMA 0x1205
+#define IDS_KEYSIGNATURE_6SMA 0x1206
+#define IDS_KEYSIGNATURE_7SMA 0x1207
+#define IDS_KEYSIGNATURE_8MA 0x1208
+#define IDS_KEYSIGNATURE_7FMA 0x1209
+#define IDS_KEYSIGNATURE_6FMA 0x120A
+#define IDS_KEYSIGNATURE_5FMA 0x120B
+#define IDS_KEYSIGNATURE_4FMA 0x120C
+#define IDS_KEYSIGNATURE_3FMA 0x120D
+#define IDS_KEYSIGNATURE_2FMA 0x120E
+#define IDS_KEYSIGNATURE_1FMA 0x120F
+
+#define IDS_KEYSIGNATURE_0MI 0x1210
+#define IDS_KEYSIGNATURE_1SMI 0x1211
+#define IDS_KEYSIGNATURE_2SMI 0x1212
+#define IDS_KEYSIGNATURE_3SMI 0x1213
+#define IDS_KEYSIGNATURE_4SMI 0x1214
+#define IDS_KEYSIGNATURE_5SMI 0x1215
+#define IDS_KEYSIGNATURE_6SMI 0x1216
+#define IDS_KEYSIGNATURE_7SMI 0x1217
+#define IDS_KEYSIGNATURE_8MI 0x1218
+#define IDS_KEYSIGNATURE_7FMI 0x1219
+#define IDS_KEYSIGNATURE_6FMI 0x121A
+#define IDS_KEYSIGNATURE_5FMI 0x121B
+#define IDS_KEYSIGNATURE_4FMI 0x121C
+#define IDS_KEYSIGNATURE_3FMI 0x121D
+#define IDS_KEYSIGNATURE_2FMI 0x121E
+#define IDS_KEYSIGNATURE_1FMI 0x121F
+
+
+
+//-----------------------------------------------------------------------------
+// 世界樹アプリケーション用文字列
+//-----------------------------------------------------------------------------
+
+#define IDS_TRACKLIST 0x1401
+#define IDS_PIANOROLL 0x1402
+#define IDS_EVENTLIST 0x1403
+#define IDS_MUSICALSCORE 0x1404
+
+#define IDS_CONTROL_SPEEDSLOW 0x1411
+#define IDS_CONTROL_SPEEDNORMAL 0x1412
+#define IDS_CONTROL_SPEEDFAST 0x1413
+
+#define IDS_DEFAULTFONTNAME 0x1421
+#define IDS_TIMEMEASUREFONTNAME 0x1422
+
+#define IDS_READMEFILENAME 0x1503
+#define IDS_READMEDIRNAME 0x1504
+#define IDS_LICENSEFILENAME 0x1505
+#define IDS_LICENSEDIRNAME 0x1506
+#define IDS_MANUALFILENAME 0x1507
+#define IDS_MANUALDIRNAME 0x1508
+#define IDS_INSTRUMENTFILENAME 0x1509
+#define IDS_INSTRUMENTDIRNAME 0x150A
+#define IDS_AUTOSAVEFILEFORMAT 0x150B
+#define IDS_AUTOSAVEFILENAME 0x150C
+#define IDS_AUTOSAVEDIRNAME 0x150D
+#define IDS_HOMEPAGEADDRESS 0x150E
+
+// アプリケーションクラス用
+#define IDS_NONE 0x15C1
+#define IDS_MIDI_MAPPER 0x15C2
+#define IDS_RECEIVE_MIDI_TIMING_CLOCK 0x15D1
+#define IDS_RECEIVE_SMPTE_MTC 0x15D2
+#define IDS_SEND_MIDI_TIMING_CLOCK 0x15D3
+#define IDS_SEND_SMPTE24_MTC 0x15D4
+#define IDS_SEND_SMPTE25_MTC 0x15D5
+#define IDS_SEND_SMPTE29P97_MTC 0x15D6
+#define IDS_SEND_SMPTE30_MTC 0x15D7
+#define IDS_MIDIDEVICE_AND_INSTRUMENT 0x15E1
+#define IDS_MIDISYNCMODE 0x15E2
+#define IDS_OPTIONS 0x15E3
+#define IDS_TICKS_PER_QUARTER_NOTE 0x15F1
+#define IDS_SUBFRAMES_PER_FRAME 0x15F2
+
+
+// CSekaijuAppクラス用メッセージ文字列
+#define IDS_INSUFFICIENT_MEMORY_FOR_EXEFILENAME 0x1601
+#define IDS_SHAREMEMORY_FOR_SEND_OPEN_ERROR 0x1602
+#define IDS_SHAREMEMORY_FOR_SEND_MAPPING_ERROR 0x1603
+#define IDS_SHAREMEMORY_FOR_RECV_OPEN_ERROR 0x1604
+#define IDS_SHAREMEMORY_FOR_RECV_MAPPING_ERROR 0x1605
+#define IDS_RECPLAYTHREAD_CREATE_ERROR 0x1606
+#define IDS_S_N_MIDIINSTDEF_D_FIND_FAILED 0x1607
+#define IDS_S_N_MIDIINDEVICE_D_OPEN_FAILED 0x1608
+#define IDS_S_N_MIDIOUTDEVICE_D_OPEN_FAILED 0x1609
+#define IDS_INSUFFICIENT_MEMORY_OR_INSUFFICIENT_RESOURCE 0x160A
+#define IDS_S_N_FILE_OPEN_FAILED 0x160B
+#define IDS_ARE_YOU_SURE_TO_DELETE_ALL_AUTOSAVEFILE_NOW_REALLY 0x1620
+#define IDS_LANGUAGE_WILL_BE_CHANGED_AT_THE_NEXT_STARTUP 0x1621
+
+// CSekaijuDocクラス用メッセージ文字列
+#define IDS_MIDIDATA_CREATE_FAILED 0x1701
+#define IDS_MIDICLOCK_CREATE_FAILED 0x1702
+#define IDS_S_N_FILE_LOAD_FAILED 0x1703
+#define IDS_THIS_MIDIDATA_IS_FORMAT0_N_CONVERT_TO_FORMAT1 0x1704
+#define IDS_S_N_INVALID_EXT_N_FILE_LOAD_FAILED 0x1705
+#define IDS_S_N_MIDIDATA_SAVE_FAILED 0x1706
+#define IDS_S_N_INVALID_EXT_N_FILE_SAVE_FAILED 0x1707
+#define IDS_D_MIDIEVENTS_CHANNEL_IS_CONFLICTED_N_CONVERT_TO_MIDITRACKS_CHANNEL 0x1708
+#define IDS_D_MIDIEVENTS_DURATION_IS_LESS_THAN_0_N_DELETE_THESE_MIDIEVENTS 0x1709
+#define IDS_D_ENDOFTRACKEVENT_IS_NOT_LAST_PLACE_N_DELETE_THESE_ENDOFTRACKEVENTS 0x170A
+#define IDS_D_MIDITRACK_DOESNT_HAVE_ENDOFTRACKEVENT_N_INSERT_ENDOFTRACKEVENTS 0x170B
+#define IDS_TIMEMODE_OF_CLIPBOARD_IS_ABNORMAL 0x1710
+#define IDS_INSUFFICIENT_MEMORY 0x1711
+#define IDS_05D_02D_03D_MEASURE_BEAT_TICK 0x1712
+#define IDS_08D_03D_FRAME_TICK 0x1713
+#define IDS_02D_02D_02D_03D_HOUR_MINUTE_SECOND_MILLISEC 0x1714
+#define IDS_UNABLE_TO_UNDO_ANYMORE 0x1715
+#define IDS_UNABLE_TO_UNDO_T_CTRL_Z 0x1716
+#define IDS_UNDO_02D_02D_02D_S_T_CTRL_Z 0x1717
+#define IDS_UNABLE_TO_REDO_ANYMORE 0x1718
+#define IDS_UNABLE_TO_REDO_T_CTRL_Y 0x1719
+#define IDS_REDO_02D_02D_02D_S_T_CTRL_Y 0x171A
+#define IDS_INITIALIZE_HISTORY 0x171B
+#define IDS_UNABLE_TO_WRITE_TO_CLIPBOARD 0x171C
+#define IDS_UNABLE_TO_READ_FROM_CLIPBOARD 0x171D
+#define IDS_NO_AVAILABLE_MIDIDATA_IN_THE_CLIPBOARD 0x171E
+#define IDS_PASTE_FAILED 0x171F
+#define IDS_D_MIDIEVENTS_WERE_INSERTED 0x1720
+#define IDS_D_MIDIEVENTS_TRACKINDEX_ISNT_CHANGED 0x1721
+#define IDS_UNABLE_TO_BEATSCAN_WITH_FORMAT0_MIDIDATA 0x1722
+#define IDS_UNABLE_TO_BEATSCAN_WITH_SMPTEBASE_MIDIDATA 0x1723
+#define IDS_SELECTED_NOTEEVENT_IS_TOO_FEW_IN_THE_SPECIFIED_TRACK 0x1724
+#define IDS_D_NOTEVENT_IS_DETECTED_IN_THE_SPECIFIED_TRACK_CONTINUE 0x1725
+#define IDS_ABNORMAL_FORMAT_MIDIDATA_IN_THE_CLIPBOARD 0x1726
+#define IDS_D_MIDICHANNELEVENTS_ARE_IN_THE_FIRST_TRACK_ARE_YOU_SURE_TO_REPAIR_THEM 0x1731
+#define IDS_D_TEMPOEVENTS_ARE_IN_THE_SECOND_TRACK_ARE_YOU_SURE_TO_REPAIR_THEM 0x1732
+#define IDS_THIS_MIDIDATA_CANT_BE_EDITED_OR_SAVED_BECAUSE_IT_IS_ABNORMAL 0x1733
+#define IDS_UNABLE_TO_SAVE_SMPTE_BASE_SAVE_AS_MIDICSV 0x1734
+#define IDS_THIS_MIDIDATA_TIMERESOLUTION_IS_TOO_HIGH_D_N_MODIFY_TO_960 0x1735
+
+// トラックリストウィンドウ用列名文字列
+#define IDS_NAME 0x1800
+#define IDS_COLOR 0x1801
+#define IDS_INPUTON 0x1802
+#define IDS_INPUTPORT 0x1803
+#define IDS_INPUTCHANNEL 0x1804
+#define IDS_OUTPUTON 0x1805
+#define IDS_OUTPUTPORT 0x1806
+#define IDS_OUTPUTCHANNEL 0x1807
+#define IDS_VIEWMODE 0x1808
+#define IDS_CC_0 0x1809
+#define IDS_CC_32 0x180A
+#define IDS_PROGRAM_NUMBER 0x180B
+#define IDS_VOLUME 0x180C
+#define IDS_PAN 0x180D
+#define IDS_REVERB 0x180E
+#define IDS_CHORUS 0x180F
+#define IDS_DELAY 0x1810
+#define IDS_TIMEPLUS 0x1811
+#define IDS_KEYPLUS 0x1812
+#define IDS_VELPLUS 0x1813
+#define IDS_NUMEVENT 0x1814
+
+// トラックリストウィンドウ用固定文字列
+#define IDS_SHOW 0x1820
+#define IDS_HIDE 0x1821
+#define IDS_ENABLE 0x1822
+#define IDS_LOCK 0x1823
+#define IDS_ON 0x1824
+#define IDS_OFF 0x1825
+#define IDS_DRUM 0x1826
+#define IDS_NORM 0x1827
+#define IDS_N_A 0x1828
+
+// トラックリストウィンドウ用メッセージボックス文字列
+#define IDS_UNABLE_TO_ADD_TRACK_IN_FORMAT0_MIDIDATA 0x1840
+#define IDS_UNABLE_TO_ADD_TRACK_BEFORE_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1841
+#define IDS_UNABLE_TO_ADD_TRACK_ANY_MORE 0x1842
+#define IDS_UNABLE_TO_DUPLICATE_TRACK_IN_FORMAT0_MIDIDATA 0x1843
+#define IDS_UNABLE_TO_DUPLICATE_THE_FIRST_TRACK_IN_FORMAT1_MIDIATA 0x1844
+#define IDS_THE_SOURCE_TRACK_IS_EMPTY 0x1845
+#define IDS_UNABLE_TO_DELETE_THE_FIRST_TRACK 0x1846
+#define IDS_THE_SPECIFIED_TRACK_IS_EMPTY 0x1847
+#define IDS_NO_TRACK_IS_SELECTED_TO_BE_MOVED 0x1848
+#define IDS_UNABLE_TO_MOVE_TRACK_IN_FORMAT0_MIDIDATA 0x1849
+#define IDS_UNABLE_TO_MOVE_UP_THE_FIRST_AND_THE_SECOND_TRACK_IN_FORMAT1_MIDIDATA 0x184A
+#define IDS_UNABLE_TO_MOVE_UP_THE_FIRST_TRACK_IN_FORMAT2_MIDIDATA 0x184B
+#define IDS_TRACK_MOVE_FAILED 0x184C
+#define IDS_UNABLE_TO_MOVE_DOWN_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x184D
+#define IDS_UNABLE_TO_MOVE_DOWN_THIS_TRACK_ANY_MORE 0x184E
+#define IDS_CURRENT_VIEW_IS_NOT_EXIST 0x184F
+#define IDS_INPUT_HALF_WIDTH_NUMBER_FROM_1_TO_16 0x1860
+#define IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_16 0x1861
+#define IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1862
+#define IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1863
+#define IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_127 0x1864
+#define IDS_INPUT_HALF_WIDTH_NUMBER_FROM_M127_TO_127 0x1865
+#define IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA 0x1866
+//#define IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1867
+//#define IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1868
+#define IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1869
+#define IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x186A
+#define IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x186B
+
+
+
+
+// イベントリストウィンドウ用列名文字列
+#define IDS_TRACK 0x1900
+#define IDS_HOUR_MINUTE_SECOND_MILLISEC 0x1901
+#define IDS_MEASURE_BEAT_TICK 0x1902
+#define IDS_EVENT_KIND 0x1903
+#define IDS_CHANNEL 0x1904
+#define IDS_VALUE1 0x1905
+#define IDS_VALUE2 0x1906
+#define IDS_VALUE3 0x1907
+#define IDS_FRAME_SUBFRAME 0x1908
+
+// イベントリストウィンドウ用固定文字列
+#define IDS_INCLUDING_VELOCITY0_NOTEON 0x1921
+#define IDS_UNKNOWN_EVENT_KIND 0x1922
+#define IDS_1P2LF_BPM_EQ_D_MICROSEC_PER_QUARTER_NOTE 0x1923
+#define IDS_S_FPS_D_HOUR_D_MINUTE_D_SEC_D_FRAME_D_SUBFRAME 0x1924
+#define IDS_24 0x1925
+#define IDS_25 0x1926
+#define IDS_29P97 0x1927
+#define IDS_30 0x1928
+#define IDS_ERROR 0x1929
+#define IDS_D_PER_D_D_CLOCK_PER_BEAT_D_32DIVNOTE_PER_BEAT 0x192A
+#define IDS_SHARP 0x192B
+#define IDS_FLAT 0x192C
+#define IDS_MAJOR 0x192D
+#define IDS_MINOR 0x192E
+#define IDS_D_S_S_EQ_S 0x192F
+
+
+
+// イベントリスト用メッセージボックス文字列
+#define IDS_A_SEPARATOR_BETWEEN_MEASURE_AND_BEAT_IS_NOT_FOUND 0x1940
+#define IDS_MEASURE_MUST_BE_HALF_WIDTH_NUMBER 0x1941
+#define IDS_MEASURE_VALUE_IS_OUT_OF_RANGE 0x1942
+#define IDS_A_SEPARATOR_BETWEEN_BEAT_AND_TICK_IS_NOT_FOUND 0x1943
+#define IDS_BEAT_MUST_BE_HALF_WIDTH_NUMBER 0x1944
+#define IDS_BEAT_VALUE_IS_OUT_OF_RANGE 0x1945
+#define IDS_TICK_MUST_BE_HALF_WIDTH_NUMBER 0x1946
+#define IDS_TICK_VALUE_IS_OUT_OF_RANGE 0x1947
+#define IDS_UNABLE_TO_INSERT_THE_EVENT_TO_THIS_TRACK 0x1948
+#define IDS_UNABLE_TO_INSERT_ENDOFTRACK_TO_THIS_TRACK_ANY_MORE 0x1949
+#define IDS_UNABLE_TO_INSERT_THIS_EVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x194A
+#define IDS_UNABLE_TO_INSERT_THIS_EVENT_TO_THE_SECOND_TRACK_IN_FORMAT1_MIDIDATA 0x194B
+#define IDS_INSERT_EVENT_FAILED 0x194C
+#define IDS_CURRENT_MIDIEVENT_IS_EMPTY 0x194D
+#define IDS_MIDIEVENT_DUPLICATE_FAILED 0x194E
+#define IDS_UNABLE_TO_DELETE_THE_LAST_ENDOFTRACK_IN_A_TRACK 0x194F
+#define IDS_TRACK_MUST_BE_HALF_WIDTH_NUMBER 0x1950
+#define IDS_TRACK_VALUE_IS_OUT_OF_RANGE 0x1951
+#define IDS_UNABLE_TO_MOVE_THE_LAST_ENDOFTRACK_TO_THE_OTHER_TRACK 0x1952
+#define IDS_MODIFY_EVENT_TRACK_FAILED 0x1953
+#define IDS_A_SEPARATOR_BETWEEN_FRAME_AND_TICK_IS_NOT_FOUND 0x1954
+#define IDS_FRAME_MUST_BE_HALF_WIDTH_NUMBER 0x1955
+#define IDS_FRAME_VALUE_IS_OUT_OF_RANGE 0x1956
+#define IDS_SUBFRAME_MUST_BE_HALF_WIDTH_NUMBER 0x1957
+#define IDS_SUBFRAME_VALUE_IS_OUT_OF_RANGE 0x1958
+#define IDS_UNABLE_TO_MODIFY_THE_LAST_ENDOFTRADK 0x1959
+#define IDS_FAILED_TO_MODIFY_EVENT_KIND 0x195A
+#define IDS_ARE_YOU_SURE_TO_MOVE_THIS_EVENT_TO_THE_FIRST_TRACK 0x195B
+#define IDS_UNEXPECTED_EVENT_KIND 0x195C
+#define IDS_UNABLE_TO_SPECIFIY_EVENT_CHANNEL_OF_THIS_EVENT 0x195D
+#define IDS_CHANNEL_MUST_BE_HALF_WIDTH_NUMBER_FROM_1_TO_16 0x195E
+#define IDS_SEQUENCENUMBER_MUST_BE_HALF_WIDTH_NUMBER_FROM_0_TO_65535 0x195F
+#define IDS_CHANNELPREFIX_MUST_BE_HALF_WIDTH_NUMBER_FROM_1_TO_16 0x1960
+#define IDS_PORTPREFIX_MUST_BE_HALF_WIDTH_NUMBER_FROM_0_TO_255 0x1961
+#define IDS_ENDOFTRACK_HAS_NO_VALUE 0x1962
+#define IDS_A_SEPARATOR_IS_NOT_FOUND 0x1963
+#define IDS_FPS_MUST_BE_24_OR_25_OR_29P97_OR_30 0x1964
+#define IDS_HOUR_MUST_BE_HALF_WIDTH_NUMBER 0x1965
+#define IDS_MINUTE_MUST_BE_HALF_WIDTH_NUMBER 0x1966
+#define IDS_SECOND_MUST_BE_HALF_WIDTH_NUMBER 0x1967
+//#define IDS_FRAME_MUST_BE_HALF_WIDTH_NUMBER 0x1968
+#define IDS_NUMERATOR_MUST_BE_HALF_WIDTH_NUMBER 0x1969
+#define IDS_DENOMINATOR_MUST_BE_HALF_WIDTH_NUMBER 0x196A
+#define IDS_A_SEPARATOR_BETWEEN_NUMERATOR_AND_DENOMINATOR_IS_NOT_FOUND 0x196B
+#define IDS_DENOMINATOR_MUST_BE_1_OR_2_OR_4_OR_8_OR_16_OR_32 0x196C
+#define IDS_CLOCKSPERBEAT_MUST_BE_HALF_WIDTH_NUMBER 0x196D
+#define IDS_32DIVNOTEPERBEAT_MUST_BE_HALF_WIDTH_NUMBER 0x196E
+#define IDS_KEYSIGNATURE_MUST_BE_7B_6B_5B_4B_3B_2B_1B_0_1S_2S_3S_4S_5S_6S_7S 0x196F
+#define IDS_KEYSCALE_MUST_BE_MAJOR_OR_MINOR 0x1970
+#define IDS_SYSEX_DATA_MUST_BEGIN_WITH_F0 0x1971
+#define IDS_SYSEX_DATA_BETWEE_F0_AND_F7_MUST_BE_FROM_00_TO_7F 0x1972
+#define IDS_SYSEX_DATA_MUST_END_WITH_F7 0x1973
+#define IDS_UNABLE_TO_MODIFY_UNDEFINED_EVENT 0x1974
+
+// ピアノロール用固定文字列
+#define IDS_TEMPO 0x1A20
+#define IDS_VELOCITY 0x1A21
+#define IDS_CHANNELAFTERTOUCH 0x1A22
+#define IDS_PITCHBEND 0x1A23
+#define IDS_CC_D_S 0x1A24
+#define IDS_D_4DIVNOTE 0x1A25
+#define IDS_D_8DIVNOTE 0x1A26
+#define IDS_D_12DIVNOTE 0x1A27
+#define IDS_D_16DIVNOTE 0x1A28
+#define IDS_D_24DIVNOTE 0x1A29
+#define IDS_D_32DIVNOTE 0x1A2A
+#define IDS_D_48DIVNOTE 0x1A2B
+#define IDS_D_FREE 0x1A2C
+#define IDS_D_1FRAME 0x1A2D
+#define IDS_D_2DIVFRAME 0x1A2E
+#define IDS_D_3DIVFRAME 0x1A2F
+#define IDS_D_4DIVFRAME 0x1A30
+#define IDS_D_6DIVFRAME 0x1A31
+#define IDS_D_8DIVFRAME 0x1A32
+#define IDS_D_12DIVFRAME 0x1A33
+
+// ピアノロール用メッセージ文字列
+#define IDS_UNABLE_TO_INSERT_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1A40
+#define IDS_UNABLE_TO_INSERT_NOTEEVENT_ANY_MORE_BEACUSE_OF_INSUFFICIENT_MEMORY 0x1A41
+#define IDS_UNABLE_TO_DELETE_NOTEEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1A42
+#define IDS_UNABLE_TO_INSERT_GRAPHEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1A43
+#define IDS_UNABLE_TO_DELETE_GRAPHEVENT_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA 0x1A44
+
+
+// ファイルダイアログ用文字列
+#define IDS_ALL_MIDI_SEQUENCE_AD_SKJ_AD_CHY_AD_MID_AD_VSQ 0x1E00
+#define IDS_AD_SKJ_AD_CHY_AD_MID_AD_VSQ 0x1E01
+#define IDS_SEKAIJU_SEQUENCE_FILES_AD_SKJ 0x1E10
+#define IDS_AD_SKJ 0x1E11
+#define IDS_D_SKJ 0x1E12
+#define IDS_CHERRY_SEQUENCE_FILES_AD_CHY 0x1E20
+#define IDS_AD_CHY 0x1E21
+#define IDS_D_CHY 0x1E22
+#define IDS_STANDARD_MIDI_FILES_AD_MID 0x1E30
+#define IDS_AD_MID 0x1E31
+#define IDS_D_MID 0x1E32
+#define IDS_MIDI_CSV_FILES_AD_CSV 0x1E40
+#define IDS_AD_CSV 0x1E41
+#define IDS_D_CSV 0x1E42
+#define IDS_VOCALOID2_FILES_AD_VSQ 0x1E50
+#define IDS_AD_VSQ 0x1E51
+#define IDS_D_VSQ 0x1E52
+#define IDS_ALL_FILES_AD_A 0x1E60
+#define IDS_AD_A 0x1E61
+#define IDS_COMMA_SEPARATED_TEXT_FILES_AD_CSV 0x1E80
+//#define IDS_AD_CSV 0x1E81
+//#define IDS_D_CSV 0x1E82
+#define IDS_TAB_SEPARATED_TEXT_FILES_AD_TXT 0x1E90
+#define IDS_AD_TXT 0x1E91
+#define IDS_D_TXT 0x1E92
+
+// 履歴名称用文字列
+#define IDS_MODIFY_MIDICHANNEL 0x1F00
+#define IDS_DELETE_NOTEEVENT 0x1F01
+#define IDS_DELETE_ENDOFTRACKEVENT 0x1F02
+#define IDS_ADD_ENDOFTRACKEVENT 0x1F03
+#define IDS_FILE_MODIFY_PROPERTY 0x1F04
+#define IDS_EDIT_CUT 0x1F08
+#define IDS_EDIT_COPY 0x1F09
+#define IDS_EDIT_PASTE 0x1F0A
+#define IDS_EDIT_DELETE 0x1F0B
+#define IDS_EDIT_SELECT_ALL 0x1F10
+#define IDS_EDIT_DESELECT_ALL 0x1F11
+#define IDS_EDIT_SELECT_BEFORE 0x1F12
+#define IDS_EDIT_DESELECT_BEFORE 0x1F13
+#define IDS_EDIT_SELECT_AFTER 0x1F14
+#define IDS_EDIT_DESELECT_AFTER 0x1F15
+#define IDS_EDIT_MODIFY_TRACKINDEX 0x1F18
+#define IDS_EDIT_MODIFY_TIME 0x1F19
+#define IDS_EDIT_MODIFY_CHANNEL 0x1F1A
+#define IDS_EDIT_MODIFY_KEY 0x1F1B
+#define IDS_EDIT_MODIFY_VELOCITY 0x1F1C
+#define IDS_EDIT_MODIFY_DURATION 0x1F1D
+#define IDS_EDIT_MODIFY_VALUE 0x1F1E
+#define IDS_EDIT_BREAKUP_AND_TRILL 0x1F20
+#define IDS_EDIT_QUANTIZE 0x1F21
+#define IDS_EDIT_BEATSCAN 0x1F22
+#define IDS_EDIT_INSERTMEASURE 0x1F23
+#define IDS_EDIT_REMOVEMEASURE 0x1F24
+#define IDS_ONLY_THIS_TRACK_INPUT_ON 0x1F28
+#define IDS_ONLY_THIS_TRACK_INPUT_OFF 0x1F29
+#define IDS_ALL_TRACK_INPUT_ON 0x1F2A
+#define IDS_ONLY_THIS_TRACK_OUTPUT_ON 0x1F2B
+#define IDS_ONLY_THIS_TRACK_OUTPUT_OFF 0x1F2C
+#define IDS_ALL_TRACK_OUTPUT_ON 0x1F2D
+#define IDS_INSERT_TRACK 0x1F40
+#define IDS_DUPLICATE_TRACK 0x1F41
+#define IDS_DELETE_TRACK 0x1F42
+#define IDS_MOVE_TRACK 0x1F43
+#define IDS_INSERT_EVENT 0x1F44
+#define IDS_DUPLICATE_EVENT 0x1F45
+#define IDS_DELETE_EVENT 0x1F46
+#define IDS_MOVE_EVENT 0x1F47
+#define IDS_MODIFY_COLOR 0x1F50
+#define IDS_MODIFY_TRACKNAME 0x1F51
+#define IDS_MODIFY_INPUTPORT 0x1F52
+#define IDS_MODIFY_INPUTCHANNEL 0x1F53
+#define IDS_MODIFY_OUTPUTPORT 0x1F54
+#define IDS_MODIFY_OUTPUTCHANNEL 0x1F55
+#define IDS_SET_VALUE 0x1F56
+#define IDS_MODIFY_CONTROLCHANGE 0x1F57
+#define IDS_MODIFY_PROGRAMCHANGE 0x1F58
+#define IDS_SWITCH_VALUE 0x1F59
+#define IDS_MODIFY_TIMEPLUS 0x1F60
+#define IDS_MODIFY_KEYPLUS 0x1F61
+#define IDS_MODIFY_VELPLUS 0x1F62
+#define IDS_MODIFY_VISIBLE_ON_OFF 0x1F63
+#define IDS_MODIFY_ENABLE_ON_OFF 0x1F64
+#define IDS_MODIFY_INPUT_ON_OFF 0x1F65
+#define IDS_MODIFY_OUTPUT_ON_OFF 0x1F66
+#define IDS_MODIFY_VIEWMODE 0x1F67
+#define IDS_MODIFY_EVENT_TIME 0x1F80
+#define IDS_MODIFY_EVENT_CHANNEL 0x1F81
+#define IDS_MODIFY_EVENT_VALUE 0x1F82
+#define IDS_MODIFY_EVENT_TRACK 0x1F83
+#define IDS_MODIFY_EVENT_KIND 0x1F84
+#define IDS_MODIFY_SEQUENCENUMBER_VALUE 0x1F85
+#define IDS_MODIFY_TEXTEVENT_VALUE 0x1F86
+#define IDS_MODIFY_CHANNELPREFIX_VALUE 0x1F87
+#define IDS_MODIFY_PORTPREFIX_VALUE 0x1F88
+#define IDS_MODIFY_TEMPO_VALUE 0x1F89
+#define IDS_MODIFY_SMPTEOFFSET_VALUE 0x1F8A
+#define IDS_MODIFY_TIMESIGNATURE 0x1F8B
+#define IDS_MODIFY_KEYSIGNATURE 0x1F8C
+#define IDS_MODIFY_SEQUENCERSPECIFIC 0x1F8D
+#define IDS_MODIFY_MIDIEVENT_VALUE 0x1F8E
+#define IDS_MODIFY_SYSEX_NORMAL 0x1F8F
+#define IDS_MODIFY_SYSEX_ARBITRARY 0x1F90
+#define IDS_SELECT_DESELECT 0x1FA0
+#define IDS_MODIFY_NOTE 0x1FA1
+#define IDS_INSERT_NOTE 0x1FA2
+#define IDS_DELETE_NOTE 0x1FA3
+#define IDS_DUPLICATE_NOTE 0x1FA4
+#define IDS_MOVE_NOTE 0x1FA5
+#define IDS_SELECT_DESELECT_NOTE 0x1FA6
+#define IDS_INSERT_GRAPH 0x1FA7
+#define IDS_DELETE_GRAPH 0x1FA8
+#define IDS_SELECT_DESELECT_GRAPH 0x1FA9
+#define IDS_DUPLICATE_MEASURE 0x1FAA
+#define IDS_MOVE_MEASURE 0x1FAB
+#define IDS_DELETE_MEASURE 0x1FAC
+#define IDS_MODIFY_EVENT 0x1FAD
+
+
+
+//-----------------------------------------------------------------------------
+// メニュー 0x2000〜0x2FFF
+//-----------------------------------------------------------------------------
+
+#define ID_FILE_PROPERTY 0x2011
+
+#define ID_EDIT_INITHISTORY 0x2111
+#define ID_EDIT_DELETE 0x2121
+#define ID_EDIT_SELECTALL 0x2131
+#define ID_EDIT_SELECTNONE 0x2132
+#define ID_EDIT_SELECTBEFORE 0x2133
+#define ID_EDIT_DESELECTBEFORE 0x2134
+#define ID_EDIT_SELECTAFTER 0x2135
+#define ID_EDIT_DESELECTAFTER 0x2136
+
+#define ID_EDIT_FINDNEXT 0x2142
+#define ID_EDIT_FINDPREV 0x2143
+#define ID_EDIT_FINDCLEAR 0x2144
+
+#define ID_EDIT_TRACK 0x2151
+#define ID_EDIT_TIME 0x2152
+#define ID_EDIT_CHANNEL 0x2153
+#define ID_EDIT_KEY 0x2154
+#define ID_EDIT_VELOCITY 0x2155
+#define ID_EDIT_DURATION 0x2156
+#define ID_EDIT_VALUE 0x2157
+#define ID_EDIT_QUANTIZE 0x2158
+#define ID_EDIT_UNQUANTIZE 0x2159
+#define ID_EDIT_BREAKUPANDTRILL 0x215A
+#define ID_EDIT_BEATSCAN 0x215B
+
+#define ID_EDIT_INSERTMEASURE 0x2161
+#define ID_EDIT_REMOVEMEASURE 0x2162
+
+#define ID_VIEW_REDRAW 0x2201
+#define ID_VIEW_TOOLBAR1 0x2211
+#define ID_VIEW_TOOLBAR2 0x2212
+#define ID_VIEW_TRACKLIST 0x2231
+#define ID_VIEW_PIANOROLL 0x2232
+#define ID_VIEW_EVENTLIST 0x2233
+#define ID_VIEW_MUSICALSCORE 0x2234
+
+#define ID_CONTROL_TOBEGIN 0x2301
+#define ID_CONTROL_PLAY 0x2302
+#define ID_CONTROL_RECORD 0x2303
+#define ID_CONTROL_TOEND 0x2304
+#define ID_CONTROL_PREVMEASURE 0x2305
+#define ID_CONTROL_NEXTMEASURE 0x2306
+#define ID_CONTROL_PREVBEAT 0x2307
+#define ID_CONTROL_NEXTBEAT 0x2308
+#define ID_CONTROL_SPEEDNONE 0x230A
+#define ID_CONTROL_SPEEDSLOW 0x230B
+#define ID_CONTROL_SPEEDNORMAL 0x230C
+#define ID_CONTROL_SPEEDFAST 0x230D
+#define ID_CONTROL_SPEEDSLAVE 0x230E
+#define ID_CONTROL_AUTOREPEAT 0x2311
+
+#define ID_TRACKLIST_INSERTTRACK 0x2401
+#define ID_TRACKLIST_DUPLICATETRACK 0x2402
+#define ID_TRACKLIST_DELETETRACK 0x2403
+#define ID_TRACKLIST_MOVEUPTRACK 0x2404
+#define ID_TRACKLIST_MOVEDOWNTRACK 0x2405
+#define ID_TRACKLIST_SELECT 0x2406
+#define ID_TRACKLIST_SPEAKER 0x2407
+#define ID_TRACKLIST_AUTOPAGEUPDATE 0x2421
+#define ID_TRACKLIST_SAVEAS 0x2422
+
+#define ID_PIANOROLL_PEN 0x2501
+#define ID_PIANOROLL_LINE 0x2502
+#define ID_PIANOROLL_ERASER 0x2503
+#define ID_PIANOROLL_SELECT 0x2504
+#define ID_PIANOROLL_SPEAKER 0x2505
+#define ID_PIANOROLL_ONLYCURTRACK 0x2511
+#define ID_PIANOROLL_SHOWALLTRACK 0x2512
+#define ID_PIANOROLL_ONLYCURGRAPH 0x2513
+#define ID_PIANOROLL_SHOWALLGRAPH 0x2514
+#define ID_PIANOROLL_AUTOPAGEUPDATE 0x2521
+
+#define ID_EVENTLIST_INSERTEVENT 0x2601
+#define ID_EVENTLIST_DUPLICATEEVENT 0x2602
+#define ID_EVENTLIST_DELETEEVENT 0x2603
+#define ID_EVENTLIST_DUMMY1 0x2604
+#define ID_EVENTLIST_DUMMY2 0x2605
+#define ID_EVENTLIST_DUMMY3 0x2606
+#define ID_EVENTLIST_ONLYCURTRACK 0x2611
+#define ID_EVENTLIST_SHOWALLTRACK 0x2612
+#define ID_EVENTLIST_ONLYCUREVENTKIND 0x2613
+#define ID_EVENTLIST_SHOWALLEVENTKIND 0x2614
+#define ID_EVENTLIST_AUTOPAGEUPDATE 0x2621
+#define ID_EVENTLIST_SAVEAS 0x2622
+
+#define ID_MUSICALSCORE_PEN 0x2701
+#define ID_MUSICALSCORE_LINE 0x2702
+#define ID_MUSICALSCORE_ERASER 0x2703
+#define ID_MUSICALSCORE_SELECT 0x2704
+#define ID_MUSICALSCORE_SPEAKER 0x2705
+#define ID_MUSICALSCORE_WHOLENOTE 0x2711
+#define ID_MUSICALSCORE_HALFNOTE 0x2712
+#define ID_MUSICALSCORE_QUARTERNOTE 0x2713
+#define ID_MUSICALSCORE_QUAVERNOTE 0x2714
+#define ID_MUSICALSCORE_SEMIQUAVERNOTE 0x2715
+#define ID_MUSICALSCORE_DEMISEMIQUAVERNOTE 0x2716
+#define ID_MUSICALSCORE_DOTTED 0x2717
+#define ID_MUSICALSCORE_TRIPLET 0x2718
+#define ID_MUSICALSCORE_ONLYCURTRACK 0x2721
+#define ID_MUSICALSCORE_SHOWALLTRACK 0x2722
+#define ID_MUSICALSCORE_ONLYCURGRAPH 0x2723
+#define ID_MUSICALSCORE_SHOWALLGRAPH 0x2724
+#define ID_MUSICALSCORE_AUTOPAGEUPDATE 0x2731
+
+#define ID_SETUP_MIDIDEVICE 0x2D01
+#define ID_SETUP_INSTRUMENT 0x2D02
+#define ID_SETUP_MIDISYNCMODE 0x2D03
+#define ID_SETUP_METRONOME 0x2D04
+#define ID_SETUP_AUTOSAVE 0x2D05
+#define ID_SETUP_LANGUAGE 0x2D06
+#define ID_SETUP_OPTIONS 0x2D07
+
+#define ID_HELP_README 0x2F02
+#define ID_HELP_LICENSE 0x2F03
+#define ID_HELP_MANUAL 0x2F04
+#define ID_HELP_PROJECTHOMEPAGE 0x2F06
+#define ID_HELP_ABOUT 0x2F10
+
+// メニュー(ポップアップ)
+#define ID_POPUP_SHOWTRACKLIST 0x3231
+#define ID_POPUP_SHOWPIANOROLL 0x3232
+#define ID_POPUP_SHOWEVENTLIST 0x3233
+#define ID_POPUP_SHOWMUSICALSCORE 0x3234
+
+#define ID_POPUP_TRACKINPUTON 0x3241
+#define ID_POPUP_TRACKINPUTOFF 0x3242
+#define ID_POPUP_TRACKINPUTALL 0x3243
+#define ID_POPUP_TRACKOUTPUTON 0x3251
+#define ID_POPUP_TRACKOUTPUTOFF 0x3252
+#define ID_POPUP_TRACKOUTPUTALL 0x3253
+
+#define ID_POPUP_TRACKVISIBLEON 0x3261
+#define ID_POPUP_TRACKVISIBLEOFF 0x3262
+#define ID_POPUP_TRACKVISIBLEALL 0x3263
+#define ID_POPUP_GRAPHKINDVISIBLEON 0x3264
+#define ID_POPUP_GRAPHKINDVISIBLEOFF 0x3265
+#define ID_POPUP_GRAPHKINDVISIBLEALL 0x3266
+#define ID_POPUP_EVENTKINDVISIBLEON 0x3267
+#define ID_POPUP_EVENTKINDVISIBLEOFF 0x3268
+#define ID_POPUP_EVENTKINDVISIBLEALL 0x3269
+
+#define ID_POPUP_CUT 0x3281
+#define ID_POPUP_COPY 0x3282
+#define ID_POPUP_PASTE 0x3283
+
+#define ID_POPUP_TRACKPROPERTY 0x3291
+#define ID_POPUP_EVENTPROPERTY 0x3292
+
+#define ID_POPUP_INSERTTEMPO 0x32A1
+#define ID_POPUP_INSERTTIMESIGNATURE 0x32A2
+#define ID_POPUP_INSERTKEYSIGNATURE 0x32A3
+#define ID_POPUP_INSERTMARKER 0x32A4
+#define ID_POPUP_MODIFYTEMPO 0x32B1
+#define ID_POPUP_MODIFYTIMESIGNATURE 0x32B2
+#define ID_POPUP_MODIFYKEYSIGNATURE 0x32B3
+#define ID_POPUP_MODIFYMARKER 0x32B4
+#define ID_POPUP_DELETETEMPO 0x32C1
+#define ID_POPUP_DELETETIMESIGNATURE 0x32C2
+#define ID_POPUP_DELETEKEYSIGNATURE 0x32C3
+#define ID_POPUP_DELETEMARKER 0x32C4
+
+// ステータスバー
+#define ID_INDICATOR_FORMAT 0x3F01
+#define ID_INDICATOR_NUMTRACKS 0x3F02
+#define ID_INDICATOR_TIMEBASE 0x3F03
+#define ID_INDICATOR_INPUTVELOCITY 0x3F04
+#define ID_INDICATOR_OUTPUTVELOCITY 0x3F05
+
+
+//-----------------------------------------------------------------------------
+// ダイアログ 0x4000〜0x4FFF
+//-----------------------------------------------------------------------------
+
+#define IDD_FILEPROPERTY 0x4001
+#define IDD_EDITTRACK 0x4151
+#define IDD_EDITTIME 0x4152
+#define IDD_EDITTIMESMP 0x4153
+#define IDD_EDITCHANNEL 0x4154
+#define IDD_EDITKEY 0x4155
+#define IDD_EDITVELOCITY 0x4156
+#define IDD_EDITDURATION 0x4157
+#define IDD_EDITVALUE 0x4158
+#define IDD_EDITBREAKUPANDTRILL 0x4159
+#define IDD_EDITQUANTIZE 0x415A
+#define IDD_EDITUNQUANTIZE 0x415B
+#define IDD_EDITBEATSCAN 0x415C
+#define IDD_EDITINSERTMEASURE 0x415D
+#define IDD_EDITREMOVEMEASURE 0x415E
+
+#define IDD_PROPERTYMARKER 0x4206
+#define IDD_PROPERTYTEMPO 0x4251
+#define IDD_PROPERTYTIMESIGNATURE 0x4258
+#define IDD_PROPERTYKEYSIGNATURE 0x4259
+#define IDD_PROPERTYNOTE 0x4290
+#define IDD_PROPERTYKEYAFTERTOUCH 0x42A0
+#define IDD_PROPERTYCONTROLCHANGE 0x42B0
+#define IDD_PROPERTYPROGRAMCHANGE 0x42C0
+#define IDD_PROPERTYCHANNELAFTERTOUCH 0x42D0
+#define IDD_PROPERTYPITCHBENC 0x42E0
+#define IDD_PROPERTYSYSEX 0x42F0
+
+#define IDD_MIDIINDEVICE 0x4333
+#define IDD_MIDIOUTDEVICE 0x4334
+#define IDD_MIDIINSTDEFNORM 0x4343
+#define IDD_MIDIINSTDEFDRUM 0x4344
+#define IDD_MIDIINSYNCMODE 0x4353
+#define IDD_MIDIOUTSYNCMODE 0x4354
+#define IDD_METRONOME 0x4501
+#define IDD_AUTOSAVE 0x4601
+#define IDD_LANGUAGE 0x4701
+#define IDD_GENERALOPTION 0x4801
+#define IDD_COLOROPTION 0x4802
+#define IDD_TRACKLISTOPTION1 0x4804
+#define IDD_TRACKLISTOPTION2 0x4805
+#define IDD_PIANOROLLOPTION 0x4806
+#define IDD_EVENTLISTOPTION 0x4807
+#define IDD_MUSICALSCOREOPTION 0x4808
+#define IDD_ABOUTBOX 0x4F01
+
+//-----------------------------------------------------------------------------
+// ツールバー上のコントロール 0x5000〜0x5FFF
+//-----------------------------------------------------------------------------
+
+#define IDC_TOOLBAR1 0x5100
+#define IDC_TOOLBAR2 0x5200
+#define IDC_MILLISECEDIT 0x5201
+#define IDC_TIMEEDIT 0x5202
+#define IDC_POSITIONSCROLL 0x5203
+#define IDC_MEASUREEDIT 0x5204
+#define IDC_TEMPOEDIT 0x5205
+#define IDC_PIANOROLL1 0x5300
+#define IDC_TRACKCOMBO 0x5301
+#define IDC_CHANNELCOMBO 0x5302
+#define IDC_SNAPCOMBO 0x5303
+#define IDC_VELOCITYCOMBO 0x5304
+#define IDC_DURATIONCOMBO 0x5305
+#define IDC_GRAPHKINDCOMBO 0x5306
+#define IDC_GRAPHSNAPCOMBO 0x5307
+#define IDC_RESOLUTIONCOMBO 0x5308
+#define IDC_EVENTLIST1 0x5400
+#define IDC_EVENTTRACKCOMBO 0x5401
+#define IDC_EVENTTIMEEDIT 0x5402
+#define IDC_EVENTKINDCOMBO 0x5403
+#define IDC_EVENTCHANNELCOMBO 0x5404
+
+//-----------------------------------------------------------------------------
+// ダイアログ上のコントロール 0x6000〜0x7FFF
+//-----------------------------------------------------------------------------
+
+#define IDC_NONE 0x0000
+
+#define IDC_FILEPROPERTY_TITLE 0x6001
+#define IDC_FILEPROPERTY_SUBTITLE 0x6002
+#define IDC_FILEPROPERTY_COPYRIGHT 0x6003
+#define IDC_FILEPROPERTY_COMMENT1 0x6004
+#define IDC_FILEPROPERTY_COMMENT2 0x6005
+#define IDC_FILEPROPERTY_COMMENT3 0x6006
+#define IDC_FILEPROPERTY_NUMTRACK 0x6008
+#define IDC_FILEPROPERTY_NUMEVENT 0x6009
+#define IDC_FILEPROPERTY_ENDMILLISEC 0x600A
+#define IDC_FILEPROPERTY_ENDTIME 0x600B
+#define IDC_FILEPROPERTY_SMFFORMAT 0x6010
+#define IDC_FILEPROPERTY_SMFFORMAT0 0x6011
+#define IDC_FILEPROPERTY_SMFFORMAT1 0x6012
+#define IDC_FILEPROPERTY_SMFFORMAT2 0x6013
+#define IDC_FILEPROPERTY_TIMEMODE 0x6020
+#define IDC_FILEPROPERTY_TPQNBASE 0x6021
+#define IDC_FILEPROPERTY_SMPTE24BASE 0x6022
+#define IDC_FILEPROPERTY_SMPTE25BASE 0x6023
+#define IDC_FILEPROPERTY_SMPTE29BASE 0x6024
+#define IDC_FILEPROPERTY_SMPTE30BASE 0x6025
+#define IDC_FILEPROPERTY_RESOLUTION 0x6026
+#define IDC_FILEPROPERTY_RESOLUTIONU 0x6027
+
+#define IDC_EDITTRACK_AMOUNT 0x6100
+#define IDC_EDITTRACK_AMOUNTSP 0x6101
+#define IDC_EDITTRACK_UNIT 0x6102
+#define IDC_EDITTRACK_ABSOLUTEUNIT 0x6103
+#define IDC_EDITTRACK_RELATIVEUNIT 0x6104
+#define IDC_EDITTRACK_FITCHANNEL 0x6105
+
+#define IDC_EDITTIME_AMOUNT 0x6200
+#define IDC_EDITTIME_AMOUNTSP 0x6201
+#define IDC_EDITTIME_UNIT 0x6202
+#define IDC_EDITTIME_TICKUNIT 0x6203
+#define IDC_EDITTIME_BEATUNIT 0x6204
+#define IDC_EDITTIME_MEASUREUNIT 0x6205
+#define IDC_EDITTIME_PERCENTUNIT 0x6206
+#define IDC_EDITTIME_RANDOMTICKUNIT 0x6207
+
+#define IDC_EDITTIMESMP_AMOUNT 0x6300
+#define IDC_EDITTIMESMP_AMOUNTSP 0x6301
+#define IDC_EDITTIMESMP_UNIT 0x6302
+#define IDC_EDITTIMESMP_TICKUNIT 0x6303
+#define IDC_EDITTIMESMP_FRAMEUNIT 0x6304
+#define IDC_EDITTIMESMP_PERCENTUNIT 0x6305
+#define IDC_EDITTIMESMP_RANDOMTICKUNIT 0x6306
+#define IDC_EDITTIMESMP_RANDOMFRAMEUNIT 0x6307
+
+#define IDC_EDITCHANNEL_AMOUNT 0x6400
+#define IDC_EDITCHANNEL_AMOUNTSP 0x6401
+#define IDC_EDITCHANNEL_UNIT 0x6402
+#define IDC_EDITCHANNEL_BYTRACKUNIT 0x6403
+#define IDC_EDITCHANNEL_ABSOLUTEUNIT 0x6404
+#define IDC_EDITCHANNEL_RELATIVEUNIT 0x6405
+
+#define IDC_EDITKEY_AMOUNT 0x6500
+#define IDC_EDITKEY_AMOUNTSP 0x6501
+#define IDC_EDITKEY_UNIT 0x6502
+#define IDC_EDITKEY_HALFUNIT 0x6503
+#define IDC_EDITKEY_OCTAVEUNIT 0x6504
+#define IDC_EDITKEY_RANDOMHALFUNIT 0x6505
+#define IDC_EDITKEY_RANDOMOCTAVEUNIT 0x6506
+#define IDC_EDITKEY_TARGET 0x6507
+#define IDC_EDITKEY_TARGETNOTE 0x6508
+#define IDC_EDITKEY_TARGETKEYAFTER 0x6509
+
+#define IDC_EDITVELOCITY_AMOUNT 0x6600
+#define IDC_EDITVELOCITY_AMOUNTSP 0x6601
+#define IDC_EDITVELOCITY_UNIT 0x6602
+#define IDC_EDITVELOCITY_ABSOLUTEUNIT 0x6603
+#define IDC_EDITVELOCITY_RELATIVEUNIT 0x6604
+#define IDC_EDITVELOCITY_PERCENTUNIT 0x6605
+#define IDC_EDITVELOCITY_RANDOMUPDOWNUNIT 0x6606
+#define IDC_EDITVELOCITY_TARGET 0x6607
+#define IDC_EDITVELOCITY_TARGETNOTEON 0x6608
+#define IDC_EDITVELOCITY_TARGETNOTEOFF 0x6609
+
+#define IDC_EDITDURATION_AMOUNT 0x6700
+#define IDC_EDITDURATION_AMOUNTSP 0x6701
+#define IDC_EDITDURATION_UNIT 0x6702
+#define IDC_EDITDURATION_ABSOLUTEUNIT 0x6703
+#define IDC_EDITDURATION_RELATIVEUNIT 0x6704
+#define IDC_EDITDURATION_PERCENTUNIT 0x6705
+#define IDC_EDITDURATION_RANDOMUPDOWNUNIT 0x6706
+
+#define IDC_EDITVALUE_AMOUNT 0x6800
+#define IDC_EDITVALUE_AMOUNTSP 0x6801
+#define IDC_EDITVALUE_UNIT 0x6802
+#define IDC_EDITVALUE_ABSOLUTEUNIT 0x6803
+#define IDC_EDITVALUE_RELATIVEUNIT 0x6804
+#define IDC_EDITVALUE_PERCENTUNIT 0x6805
+#define IDC_EDITVALUE_RANDOMUPDOWNUNIT 0x6806
+#define IDC_EDITVALUE_TARGET 0x6807
+#define IDC_EDITVALUE_TARGETKEYAFTER 0x6808
+#define IDC_EDITVALUE_TARGETCONTROLCHANGE 0x6809
+#define IDC_EDITVALUE_TARGETCHANNELAFTER 0x680A
+#define IDC_EDITVALUE_TARGETPITCHBEND 0x680B
+
+#define IDC_EDITBREAKUPANDTRILL_DURATION 0x6900
+#define IDC_EDITBREAKUPANDTRILL_DURATIONSP 0x6901
+#define IDC_EDITBREAKUPANDTRILL_ENABLETRILL 0x6902
+#define IDC_EDITBREAKUPANDTRILL_KEYSHIFT 0x6904
+#define IDC_EDITBREAKUPANDTRILL_KEYSHIFTSP 0x6905
+
+#define IDC_EDITQUANTIZE_SNAPTIME 0x6A00
+#define IDC_EDITQUANTIZE_SNAPTIMESP 0x6A01
+#define IDC_EDITQUANTIZE_STRENGTH 0x6A02
+#define IDC_EDITQUANTIZE_STRENGTHSP 0x6A03
+#define IDC_EDITQUANTIZE_TARGET 0x6A05
+#define IDC_EDITQUANTIZE_TARGETNOTEON 0x6A06
+#define IDC_EDITQUANTIZE_TARGETNOTEOFF 0x6A07
+
+#define IDC_EDITBEATSCAN_BEATTRACK 0x6C00
+#define IDC_EDITBEATSCAN_BEATINTERVAL 0x6C02
+#define IDC_EDITBEATSCAN_INSERTTEMPO 0x6C04
+
+#define IDC_EDITINSERTMEASURE_POSITION 0x6D00
+#define IDC_EDITINSERTMEASURE_POSITIONSP 0x6D01
+#define IDC_EDITINSERTMEASURE_NUMMEASURE 0x6D03
+#define IDC_EDITINSERTMEASURE_NUMMEASURESP 0x6D04
+
+#define IDC_EDITREMOVEMEASURE_POSITION 0x6E00
+#define IDC_EDITREMOVEMEASURE_POSITIONSP 0x6E01
+#define IDC_EDITREMOVEMEASURE_NUMMEASURE 0x6E03
+#define IDC_EDITREMOVEMEASURE_NUMMEASURESP 0x6E04
+
+#define IDC_PROPERTYNOTE_TRACKINDEX 0x6F00
+#define IDC_PROPERTYNOTE_TRACKINDEXSP 0x6F01
+#define IDC_PROPERTYNOTE_TIME 0x6F02
+#define IDC_PROPERTYNOTE_TIMESP 0x6F03
+#define IDC_PROPERTYNOTE_CHANNEL 0x6F04
+#define IDC_PROPERTYNOTE_CHANNELSP 0x6F05
+#define IDC_PROPERTYNOTE_KEY 0x6F06
+#define IDC_PROPERTYNOTE_KEYSP 0x6F07
+#define IDC_PROPERTYNOTE_ONVELOCITY 0x6F08
+#define IDC_PROPERTYNOTE_ONVELOCITYSP 0x6F09
+#define IDC_PROPERTYNOTE_OFFVELOCITY 0x6F0A
+#define IDC_PROPERTYNOTE_OFFVELOCITYSP 0x6F0B
+#define IDC_PROPERTYNOTE_DURATION 0x6F0C
+#define IDC_PROPERTYNOTE_DURATIONSP 0x6F0D
+
+#define IDC_PROPERTYTEMPO_TIME 0x6F10
+#define IDC_PROPERTYTEMPO_TIMESP 0x6F11
+#define IDC_PROPERTYTEMPO_TEMPOBPM 0x6F12
+#define IDC_PROPERTYTEMPO_TEMPOBPMSP 0x6F13
+
+#define IDC_PROPERTYTIMESIGNATURE_TIME 0x6F20
+#define IDC_PROPERTYTIMESIGNATURE_TIMESP 0x6F21
+#define IDC_PROPERTYTIMESIGNATURE_NN 0x6F22
+#define IDC_PROPERTYTIMESIGNATURE_NNSP 0x6F23
+#define IDC_PROPERTYTIMESIGNATURE_DDINDEX 0x6F24
+#define IDC_PROPERTYTIMESIGNATURE_DDSP 0x6F25
+#define IDC_PROPERTYTIMESIGNATURE_CC 0x6F26
+#define IDC_PROPERTYTIMESIGNATURE_CCSP 0x6F27
+#define IDC_PROPERTYTIMESIGNATURE_BB 0x6F28
+#define IDC_PROPERTYTIMESIGNATURE_BBSP 0x6F29
+
+#define IDC_PROPERTYKEYSIGNATURE_TIME 0x6F30
+#define IDC_PROPERTYKEYSIGNATURE_TIMESP 0x6F31
+#define IDC_PROPERTYKEYSIGNATURE_SFINDEX 0x6F32
+#define IDC_PROPERTYKEYSIGNATURE_SFSP 0x6F33
+#define IDC_PROPERTYKEYSIGNATURE_MIINDEX 0x6F34
+#define IDC_PROPERTYKEYSIGNATURE_MISP 0x6F35
+
+#define IDC_PROPERTYMARKER_TIME 0x6F40
+#define IDC_PROPERTYMARKER_TIMESP 0x6F41
+#define IDC_PROPERTYMARKER_TEXT 0x6F42
+
+
+#define IDC_MIDIINDEVICE_01 0x7000
+#define IDC_MIDIINDEVICE_02 0x7001
+#define IDC_MIDIINDEVICE_03 0x7002
+#define IDC_MIDIINDEVICE_04 0x7003
+#define IDC_MIDIINDEVICE_05 0x7004
+#define IDC_MIDIINDEVICE_06 0x7005
+#define IDC_MIDIINDEVICE_07 0x7006
+#define IDC_MIDIINDEVICE_08 0x7007
+#define IDC_MIDIINDEVICE_09 0x7008
+#define IDC_MIDIINDEVICE_10 0x7009
+#define IDC_MIDIINDEVICE_11 0x700A
+#define IDC_MIDIINDEVICE_12 0x700B
+#define IDC_MIDIINDEVICE_13 0x700C
+#define IDC_MIDIINDEVICE_14 0x700D
+#define IDC_MIDIINDEVICE_15 0x700E
+#define IDC_MIDIINDEVICE_16 0x700F
+
+#define IDC_MIDIOUTDEVICE_01 0x7100
+#define IDC_MIDIOUTDEVICE_02 0x7101
+#define IDC_MIDIOUTDEVICE_03 0x7102
+#define IDC_MIDIOUTDEVICE_04 0x7103
+#define IDC_MIDIOUTDEVICE_05 0x7104
+#define IDC_MIDIOUTDEVICE_06 0x7105
+#define IDC_MIDIOUTDEVICE_07 0x7106
+#define IDC_MIDIOUTDEVICE_08 0x7107
+#define IDC_MIDIOUTDEVICE_09 0x7108
+#define IDC_MIDIOUTDEVICE_10 0x7109
+#define IDC_MIDIOUTDEVICE_11 0x710A
+#define IDC_MIDIOUTDEVICE_12 0x710B
+#define IDC_MIDIOUTDEVICE_13 0x710C
+#define IDC_MIDIOUTDEVICE_14 0x710D
+#define IDC_MIDIOUTDEVICE_15 0x710E
+#define IDC_MIDIOUTDEVICE_16 0x710F
+
+#define IDC_MIDIINSTDEFNORM_01 0x7200
+#define IDC_MIDIINSTDEFNORM_02 0x7201
+#define IDC_MIDIINSTDEFNORM_03 0x7202
+#define IDC_MIDIINSTDEFNORM_04 0x7203
+#define IDC_MIDIINSTDEFNORM_05 0x7204
+#define IDC_MIDIINSTDEFNORM_06 0x7205
+#define IDC_MIDIINSTDEFNORM_07 0x7206
+#define IDC_MIDIINSTDEFNORM_08 0x7207
+#define IDC_MIDIINSTDEFNORM_09 0x7208
+#define IDC_MIDIINSTDEFNORM_10 0x7209
+#define IDC_MIDIINSTDEFNORM_11 0x720A
+#define IDC_MIDIINSTDEFNORM_12 0x720B
+#define IDC_MIDIINSTDEFNORM_13 0x720C
+#define IDC_MIDIINSTDEFNORM_14 0x720D
+#define IDC_MIDIINSTDEFNORM_15 0x720E
+#define IDC_MIDIINSTDEFNORM_16 0x720F
+
+#define IDC_MIDIINSTDEFDRUM_01 0x7300
+#define IDC_MIDIINSTDEFDRUM_02 0x7301
+#define IDC_MIDIINSTDEFDRUM_03 0x7302
+#define IDC_MIDIINSTDEFDRUM_04 0x7303
+#define IDC_MIDIINSTDEFDRUM_05 0x7304
+#define IDC_MIDIINSTDEFDRUM_06 0x7305
+#define IDC_MIDIINSTDEFDRUM_07 0x7306
+#define IDC_MIDIINSTDEFDRUM_08 0x7307
+#define IDC_MIDIINSTDEFDRUM_09 0x7308
+#define IDC_MIDIINSTDEFDRUM_10 0x7309
+#define IDC_MIDIINSTDEFDRUM_11 0x730A
+#define IDC_MIDIINSTDEFDRUM_12 0x730B
+#define IDC_MIDIINSTDEFDRUM_13 0x730C
+#define IDC_MIDIINSTDEFDRUM_14 0x730D
+#define IDC_MIDIINSTDEFDRUM_15 0x730E
+#define IDC_MIDIINSTDEFDRUM_16 0x730F
+
+
+#define IDC_MIDIINSYNCMODE_01 0x7300 // 仮ID
+#define IDC_MIDIINSYNCMODE_02 0x7301
+#define IDC_MIDIINSYNCMODE_03 0x7302
+#define IDC_MIDIINSYNCMODE_04 0x7303
+#define IDC_MIDIINSYNCMODE_05 0x7304
+#define IDC_MIDIINSYNCMODE_06 0x7305
+#define IDC_MIDIINSYNCMODE_07 0x7306
+#define IDC_MIDIINSYNCMODE_08 0x7307
+#define IDC_MIDIINSYNCMODE_09 0x7308
+#define IDC_MIDIINSYNCMODE_10 0x7309
+#define IDC_MIDIINSYNCMODE_11 0x730A
+#define IDC_MIDIINSYNCMODE_12 0x730B
+#define IDC_MIDIINSYNCMODE_13 0x730C
+#define IDC_MIDIINSYNCMODE_14 0x730D
+#define IDC_MIDIINSYNCMODE_15 0x730E
+#define IDC_MIDIINSYNCMODE_16 0x730F
+
+#define IDC_MIDIOUTSYNCMODE_01 0x7300 // 仮ID
+#define IDC_MIDIOUTSYNCMODE_02 0x7301
+#define IDC_MIDIOUTSYNCMODE_03 0x7302
+#define IDC_MIDIOUTSYNCMODE_04 0x7303
+#define IDC_MIDIOUTSYNCMODE_05 0x7304
+#define IDC_MIDIOUTSYNCMODE_06 0x7305
+#define IDC_MIDIOUTSYNCMODE_07 0x7306
+#define IDC_MIDIOUTSYNCMODE_08 0x7307
+#define IDC_MIDIOUTSYNCMODE_09 0x7308
+#define IDC_MIDIOUTSYNCMODE_10 0x7309
+#define IDC_MIDIOUTSYNCMODE_11 0x730A
+#define IDC_MIDIOUTSYNCMODE_12 0x730B
+#define IDC_MIDIOUTSYNCMODE_13 0x730C
+#define IDC_MIDIOUTSYNCMODE_14 0x730D
+#define IDC_MIDIOUTSYNCMODE_15 0x730E
+#define IDC_MIDIOUTSYNCMODE_16 0x730F
+
+
+#define IDC_METRONOME_ON 0x7401
+#define IDC_METRONOME_OUTPUT 0x7402
+#define IDC_METRONOME_OUTPUTPORT 0x7403
+#define IDC_METRONOME_OUTPUTCHANNEL 0x7404
+#define IDC_METRONOME_OUTPUTCHANNELSP 0x7405
+#define IDC_METRONOME_PATTERN 0x7406
+#define IDC_METRONOME_NOTEKEY1 0x7407
+#define IDC_METRONOME_NOTEKEY1SP 0x7408
+#define IDC_METRONOME_NOTEVEL1 0x7409
+#define IDC_METRONOME_NOTEVEL1SP 0x740A
+#define IDC_METRONOME_NOTEKEY2 0x740B
+#define IDC_METRONOME_NOTEKEY2SP 0x740C
+#define IDC_METRONOME_NOTEVEL2 0x740D
+#define IDC_METRONOME_NOTEVEL2SP 0x740E
+
+
+#define IDC_AUTOSAVE_ON 0x7501
+#define IDC_AUTOSAVE_SETUP 0x7502
+#define IDC_AUTOSAVE_INTERVAL 0x7503
+#define IDC_AUTOSAVE_INTERVALSP 0x7504
+#define IDC_AUTOSAVE_DISABLEWHILEPLAYING 0x7505
+#define IDC_AUTOSAVE_DISABLEWHILERECORDING 0x7506
+#define IDC_AUTOSAVE_DELETE 0x7509
+#define IDC_AUTOSAVE_DELETEALLFILENOW 0x750A
+
+#define IDC_LANGUAGE_COMBO 0x759A
+
+#define IDC_GENERALOPTION_ENABLEMULTIEXEC 0x7611
+#define IDC_GENERALOPTION_ENABLEMULTIOPEN 0x7612
+#define IDC_GENERALOPTION_RESTOREWINDOWPLACEMENT 0x7613
+#define IDC_GENERALOPTION_EXECOPEN 0x7614
+#define IDC_GENERALOPTION_OPENPLAY 0x7615
+#define IDC_GENERALOPTION_PLAYUPDATE 0x7616
+#define IDC_GENERALOPTION_SEARCHUPDATE 0x7617
+#define IDC_GENERALOPTION_PATCHSEARCH 0x7618
+#define IDC_GENERALOPTION_ENABLECC111LOOP 0x7619
+#define IDC_GENERALOPTION_INVERTCTRLMOUSEWHEEL 0x761A
+#define IDC_GENERALOPTION_TRACKZEROORIGIN 0x761B
+#define IDC_GENERALOPTION_EVENTZEROORIGIN 0x761C
+#define IDC_GENERALOPTION_ENABLEAUTOPAGEUPDATE 0x761D
+#define IDC_GENERALOPTION_SENDNOTEOFFHOLDOFFATEND 0x761E
+#define IDC_GENERALOPTION_UPDOWNDELTA1 0x7621
+#define IDC_GENERALOPTION_UPDOWNDELTA1SP 0x7622
+#define IDC_GENERALOPTION_UPDOWNDELTA2 0x7623
+#define IDC_GENERALOPTION_UPDOWNDELTA2SP 0x7624
+#define IDC_GENERALOPTION_KEYVELOCITY1 0x7625
+#define IDC_GENERALOPTION_KEYVELOCITY1SP 0x7626
+#define IDC_GENERALOPTION_KEYVELOCITY2 0x7627
+#define IDC_GENERALOPTION_KEYVELOCITY2SP 0x7628
+#define IDC_GENERALOPTION_SPEEDSLOW 0x7631
+#define IDC_GENERALOPTION_SPEEDSLOWSP 0x7632
+#define IDC_GENERALOPTION_SPEEDNORMAL 0x7633
+#define IDC_GENERALOPTION_SPEEDNORMALSP 0x7634
+#define IDC_GENERALOPTION_SPEEDFAST 0x7635
+#define IDC_GENERALOPTION_SPEEDFASTSP 0x7636
+#define IDC_GENERALOPTION_PLAYRECORDINTERVAL 0x7643
+#define IDC_GENERALOPTION_PLAYRECORDINTERVALSP 0x7644
+#define IDC_GENERALOPTION_OCTAVESIGNATURE 0x7653
+#define IDC_GENERALOPTION_OCTAVESIGNATURESP 0x7654
+
+#define IDC_TRACKLISTOPTION1_DEFROWZOOM 0x7711
+#define IDC_TRACKLISTOPTION1_DEFROWZOOMSP 0x7712
+#define IDC_TRACKLISTOPTION1_DEFCOLUMNZOOM 0x7713
+#define IDC_TRACKLISTOPTION1_DEFCOLUMNZOOMSP 0x7714
+#define IDC_TRACKLISTOPTION1_DEFTIMEZOOM 0x7715
+#define IDC_TRACKLISTOPTION1_DEFTIMEZOOMSP 0x7716
+#define IDC_TRACKLISTOPTION1_DEFNAMEWIDTH 0x7723
+#define IDC_TRACKLISTOPTION1_DEFNAMEWIDTHSP 0x7724
+#define IDC_TRACKLISTOPTION1_DEFCOLORWIDTH 0x7725
+#define IDC_TRACKLISTOPTION1_DEFCOLORWIDTHSP 0x7726
+#define IDC_TRACKLISTOPTION1_DEFINPUTONWIDTH 0x7727
+#define IDC_TRACKLISTOPTION1_DEFINPUTONWIDTHSP 0x7728
+#define IDC_TRACKLISTOPTION1_DEFINPUTPORTWIDTH 0x7729
+#define IDC_TRACKLISTOPTION1_DEFINPUTPORTWIDTHSP 0x773A
+#define IDC_TRACKLISTOPTION1_DEFINPUTCHWIDTH 0x773B
+#define IDC_TRACKLISTOPTION1_DEFINPUTCHWIDTHSP 0x773C
+#define IDC_TRACKLISTOPTION1_DEFOUTPUTONWIDTH 0x773D
+#define IDC_TRACKLISTOPTION1_DEFOUTPUTONWIDTHSP 0x773E
+#define IDC_TRACKLISTOPTION1_DEFOUTPUTPORTWIDTH 0x773F
+#define IDC_TRACKLISTOPTION1_DEFOUTPUTPORTWIDTHSP 0x7740
+#define IDC_TRACKLISTOPTION1_DEFOUTPUTCHWIDTH 0x7741
+#define IDC_TRACKLISTOPTION1_DEFOUTPUTCHWIDTHSP 0x7742
+#define IDC_TRACKLISTOPTION1_DEFVIEWMODEWIDTH 0x7743
+#define IDC_TRACKLISTOPTION1_DEFVIEWMODEWIDTHSP 0x7744
+
+#define IDC_TRACKLISTOPTION2_DEFCC000WIDTH 0x7745
+#define IDC_TRACKLISTOPTION2_DEFCC000WIDTHSP 0x7746
+#define IDC_TRACKLISTOPTION2_DEFCC032WIDTH 0x7747
+#define IDC_TRACKLISTOPTION2_DEFCC032WIDTHSP 0x7748
+#define IDC_TRACKLISTOPTION2_DEFPCWIDTH 0x7749
+#define IDC_TRACKLISTOPTION2_DEFPCWIDTHSP 0x774A
+#define IDC_TRACKLISTOPTION2_DEFCC007WIDTH 0x774B
+#define IDC_TRACKLISTOPTION2_DEFCC007WIDTHSP 0x774C
+#define IDC_TRACKLISTOPTION2_DEFCC010WIDTH 0x774D
+#define IDC_TRACKLISTOPTION2_DEFCC010WIDTHSP 0x774E
+#define IDC_TRACKLISTOPTION2_DEFCC091WIDTH 0x774F
+#define IDC_TRACKLISTOPTION2_DEFCC091WIDTHSP 0x7750
+#define IDC_TRACKLISTOPTION2_DEFCC093WIDTH 0x7751
+#define IDC_TRACKLISTOPTION2_DEFCC093WIDTHSP 0x7752
+#define IDC_TRACKLISTOPTION2_DEFCC094WIDTH 0x7753
+#define IDC_TRACKLISTOPTION2_DEFCC094WIDTHSP 0x7754
+#define IDC_TRACKLISTOPTION2_DEFKEYSHIFTWIDTH 0x7755
+#define IDC_TRACKLISTOPTION2_DEFKEYSHIFTWIDTHSP 0x7756
+#define IDC_TRACKLISTOPTION2_DEFVELSHIFTWIDTH 0x7757
+#define IDC_TRACKLISTOPTION2_DEFVELSHIFTWIDTHSP 0x7758
+#define IDC_TRACKLISTOPTION2_DEFTIMESHIFTWIDTH 0x7759
+#define IDC_TRACKLISTOPTION2_DEFTIMESHIFTWIDTHSP 0x775A
+#define IDC_TRACKLISTOPTION2_DEFNUMEVENTWIDTH 0x775B
+#define IDC_TRACKLISTOPTION2_DEFNUMEVENTWIDTHSP 0x775C
+#define IDC_TRACKLISTOPTION2_ENABLEROWZOOMKEY 0x7761
+#define IDC_TRACKLISTOPTION2_ENABLECOLUMNZOOMKEY 0x7762
+#define IDC_TRACKLISTOPTION2_ENABLETIMEZOOMKEY 0x7763
+
+
+#define IDC_PIANOROLLOPTION_DEFKEYZOOM 0x7811
+#define IDC_PIANOROLLOPTION_DEFKEYZOOMSP 0x7812
+#define IDC_PIANOROLLOPTION_DEFVELZOOM 0x7813
+#define IDC_PIANOROLLOPTION_DEFVELZOOMSP 0x7814
+#define IDC_PIANOROLLOPTION_DEFTIMEZOOM 0x7815
+#define IDC_PIANOROLLOPTION_DEFTIMEZOOMSP 0x7816
+#define IDC_PIANOROLLOPTION_ENABLEKEYZOOMKEY 0x7821
+#define IDC_PIANOROLLOPTION_ENABLEVELZOOMKEY 0x7822
+#define IDC_PIANOROLLOPTION_ENABLETIMEZOOMKEY 0x7823
+#define IDC_PIANOROLLOPTION_SPEAKERMODE 0x7830
+#define IDC_PIANOROLLOPTION_SPEAKERMODEALLTRACK 0x7831
+#define IDC_PIANOROLLOPTION_SPEAKERMODEVISIBLETRACK 0x7832
+#define IDC_PIANOROLLOPTION_GRAPHLINEWIDTH 0x7841
+#define IDC_PIANOROLLOPTION_GRAPHLINEWIDTHSP 0x7842
+
+#define IDC_EVENTLISTOPTION_DEFROWZOOM 0x7911
+#define IDC_EVENTLISTOPTION_DEFROWZOOMSP 0x7912
+#define IDC_EVENTLISTOPTION_DEFCOLUMNZOOM 0x7913
+#define IDC_EVENTLISTOPTION_DEFCOLUMNZOOMSP 0x7914
+#define IDC_EVENTLISTOPTION_DEFTRACKWIDTH 0x7923
+#define IDC_EVENTLISTOPTION_DEFTRACKWIDTHSP 0x7924
+#define IDC_EVENTLISTOPTION_DEFMILLISECWIDTH 0x7925
+#define IDC_EVENTLISTOPTION_DEFMILLISECWIDTHSP 0x7926
+#define IDC_EVENTLISTOPTION_DEFTIMEWIDTH 0x7927
+#define IDC_EVENTLISTOPTION_DEFTIMEWIDTHSP 0x7928
+#define IDC_EVENTLISTOPTION_DEFKINDWIDTH 0x7929
+#define IDC_EVENTLISTOPTION_DEFKINDWIDTHSP 0x792A
+#define IDC_EVENTLISTOPTION_DEFCHWIDTH 0x792B
+#define IDC_EVENTLISTOPTION_DEFCHWIDTHSP 0x792C
+#define IDC_EVENTLISTOPTION_DEFVAL1WIDTH 0x792D
+#define IDC_EVENTLISTOPTION_DEFVAL1WIDTHSP 0x792E
+#define IDC_EVENTLISTOPTION_DEFVAL2WIDTH 0x792F
+#define IDC_EVENTLISTOPTION_DEFVAL2WIDTHSP 0x7930
+#define IDC_EVENTLISTOPTION_DEFVAL3WIDTH 0x7931
+#define IDC_EVENTLISTOPTION_DEFVAL3WIDTHSP 0x7932
+#define IDC_EVENTLISTOPTION_INSERTEVENT 0x7980
+#define IDC_EVENTLISTOPTION_INSERTEVENTBEFORE 0x7981
+#define IDC_EVENTLISTOPTION_INSERTEVENTAFTER 0x7982
+#define IDC_EVENTLISTOPTION_DUPLICATEEVENT 0x7983
+#define IDC_EVENTLISTOPTION_DUPLICATEEVENTBEFORE 0x7984
+#define IDC_EVENTLISTOPTION_DUPLICATEEVENTAFTER 0x7985
+#define IDC_EVENTLISTOPTION_DELETEEVENT 0x7986
+#define IDC_EVENTLISTOPTION_DELETEEVENTBEFORE 0x7987
+#define IDC_EVENTLISTOPTION_DELETEEVENTAFTER 0x7988
+#define IDC_EVENTLISTOPTION_ENABLEROWZOOMKEY 0x7991
+#define IDC_EVENTLISTOPTION_ENABLECOLUMNZOOMKEY 0x7992
+
+#define IDC_MUSICALSCOREOPTION_DEFTRACKZOOM 0x7A11
+#define IDC_MUSICALSCOREOPTION_DEFTRACKZOOMSP 0x7A12
+#define IDC_MUSICALSCOREOPTION_DEFTIMEZOOM 0x7A13
+#define IDC_MUSICALSCOREOPTION_DEFTIMEZOOMSP 0x7A14
+#define IDC_MUSICALSCOREOPTION_ENABLETRACKZOOMKEY 0x7A21
+#define IDC_MUSICALSCOREOPTION_ENABLETIMEZOOMKEY 0x7A22
+#define IDC_MUSICALSCOREOPTION_SPEAKERMODE 0x7A30
+#define IDC_MUSICALSCOREOPTION_SPEAKERMODEALLTRACK 0x7A31
+#define IDC_MUSICALSCOREOPTION_SPEAKERMODEVISIBLETRACK 0x7A32
+
+#define IDC_COLOROPTION_FORECOLOR_00 0x7C00
+#define IDC_COLOROPTION_FORECOLOR_01 0x7C01
+#define IDC_COLOROPTION_FORECOLOR_02 0x7C02
+#define IDC_COLOROPTION_FORECOLOR_03 0x7C03
+#define IDC_COLOROPTION_FORECOLOR_04 0x7C04
+#define IDC_COLOROPTION_FORECOLOR_05 0x7C05
+#define IDC_COLOROPTION_FORECOLOR_06 0x7C06
+#define IDC_COLOROPTION_FORECOLOR_07 0x7C07
+#define IDC_COLOROPTION_BACKCOLOR_00 0x7C08
+#define IDC_COLOROPTION_BACKCOLOR_01 0x7C09
+#define IDC_COLOROPTION_HORZCOLOR_00 0x7C0A
+#define IDC_COLOROPTION_HORZCOLOR_01 0x7C0B
+#define IDC_COLOROPTION_VERTCOLOR_00 0x7C0C
+#define IDC_COLOROPTION_VERTCOLOR_01 0x7C0D
+
+//-----------------------------------------------------------------------------
+// ダイアログボックスにおけるスピンコントロールの許可
+//-----------------------------------------------------------------------------
+#define UPDOWN "msctls_updown32"
+
+#define UDS_WRAP 0x0001
+#define UDS_SETBUDDYINT 0x0002
+#define UDS_ALIGNRIGHT 0x0004
+#define UDS_ALIGNLEFT 0x0008
+#define UDS_AUTOBUDDY 0x0010
+#define UDS_ARROWKEYS 0x0020
+#define UDS_HORZ 0x0040
+#define UDS_NOTHOUSANDS 0x0080
+#define UDS_DEFAULT (UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS)
+
+#define UDM_SETRANGE (WM_USER+101)
+#define UDM_GETRANGE (WM_USER+102)
+#define UDM_SETPOS (WM_USER+103)
+#define UDM_GETPOS (WM_USER+104)
+#define UDM_SETBUDDY (WM_USER+105)
+#define UDM_GETBUDDY (WM_USER+106)
+#define UDM_SETACCEL (WM_USER+107)
+#define UDM_GETACCEL (WM_USER+108)
+#define UDM_SETBASE (WM_USER+109)
+#define UDM_GETBASE (WM_USER+110)
diff --git a/src/Sekaiju.rc b/src/Sekaiju.rc
new file mode 100644
index 0000000..0170df0
--- /dev/null
+++ b/src/Sekaiju.rc
@@ -0,0 +1,37 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// リソーススクリプトファイル
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+// 警告:このファイルはVisualC++のリソースエディタで編集しないでください。
+// 警告:このファイルはテキストエディタで編集してください。
+
+#include "winver.h"
+#include "resource.h"
+#include <afxres.h>
+
+//-----------------------------------------------------------------------------
+// アイコン
+//-----------------------------------------------------------------------------
+
+// アプリケーションのアイコンをすべてのシステム上で維持するために、最も小さい
+// ID 値のアイコンが最初に配置されます。
+IDR_MAINFRAME ICON DISCARDABLE "..\\res\\MainFrame.ico"
+IDR_SEKAIJUTYPE ICON DISCARDABLE "..\\res\\SekaijuType.ico"
+
+
diff --git a/src/SekaijuApp.cpp b/src/SekaijuApp.cpp
new file mode 100644
index 0000000..af4a785
--- /dev/null
+++ b/src/SekaijuApp.cpp
@@ -0,0 +1,4044 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹アプリケーションクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "resource.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDocManager.h"
+#include "SekaijuDocTemplate.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "PianoRollFrame.h"
+#include "TrackListFrame.h"
+
+#include "MIDIDeviceSheet.h"
+#include "MIDISyncModeSheet.h"
+#include "AutoSaveDlg.h"
+#include "LanguageDlg.h"
+#include "MetronomeDlg.h"
+#include "OptionSheet.h"
+#include "AboutDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CSekaijuApp, CWinApp)
+ ON_COMMAND (ID_FILE_NEW, CWinApp::OnFileNew)
+ ON_UPDATE_COMMAND_UI (ID_FILE_NEW, CSekaijuApp::OnUpdateFileNewUI)
+ ON_COMMAND (ID_FILE_OPEN, CWinApp::OnFileOpen)
+ ON_UPDATE_COMMAND_UI (ID_FILE_OPEN, CSekaijuApp::OnUpdateFileOpenUI)
+ ON_COMMAND (ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
+ ON_COMMAND (ID_CONTROL_TOBEGIN, OnControlToBegin)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_TOBEGIN, OnUpdateControlToBeginUI)
+ ON_COMMAND (ID_CONTROL_TOEND, OnControlToEnd)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_TOEND, OnUpdateControlToEndUI)
+ ON_COMMAND (ID_CONTROL_PLAY, OnControlPlay)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_PLAY, OnUpdateControlPlayUI)
+ ON_COMMAND (ID_CONTROL_RECORD, OnControlRecord)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_RECORD, OnUpdateControlRecordUI)
+ ON_COMMAND (ID_CONTROL_PREVMEASURE, OnControlPrevMeasure)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_PREVMEASURE, OnUpdateControlPrevMeasureUI)
+ ON_COMMAND (ID_CONTROL_NEXTMEASURE, OnControlNextMeasure)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_NEXTMEASURE, OnUpdateControlNextMeasureUI)
+ ON_COMMAND (ID_CONTROL_PREVBEAT, OnControlPrevBeat)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_PREVBEAT, OnUpdateControlPrevBeatUI)
+ ON_COMMAND (ID_CONTROL_NEXTBEAT, OnControlNextBeat)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_NEXTBEAT, OnUpdateControlNextBeatUI)
+ ON_COMMAND (ID_CONTROL_SPEEDNONE, OnControlSpeedNone)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_SPEEDNONE, OnUpdateControlSpeedNoneUI)
+ ON_COMMAND (ID_CONTROL_SPEEDSLOW, OnControlSpeedSlow)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_SPEEDSLOW, OnUpdateControlSpeedSlowUI)
+ ON_COMMAND (ID_CONTROL_SPEEDNORMAL, OnControlSpeedNormal)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_SPEEDNORMAL, OnUpdateControlSpeedNormalUI)
+ ON_COMMAND (ID_CONTROL_SPEEDFAST, OnControlSpeedFast)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_SPEEDFAST, OnUpdateControlSpeedFastUI)
+ ON_COMMAND (ID_CONTROL_SPEEDSLAVE, OnControlSpeedSlave)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_SPEEDSLAVE, OnUpdateControlSpeedSlaveUI)
+ ON_COMMAND (ID_CONTROL_AUTOREPEAT, OnControlAutoRepeat)
+ ON_UPDATE_COMMAND_UI (ID_CONTROL_AUTOREPEAT, OnUpdateControlAutoRepeatUI)
+ ON_COMMAND (ID_SETUP_MIDIDEVICE, OnSetupMIDIDevice)
+ ON_COMMAND (ID_SETUP_MIDISYNCMODE, OnSetupMIDISyncMode)
+ ON_COMMAND (ID_SETUP_INSTRUMENT, OnSetupInstrument)
+ ON_COMMAND (ID_SETUP_METRONOME, OnSetupMetronome)
+ ON_COMMAND (ID_SETUP_AUTOSAVE, OnSetupAutoSave)
+ ON_COMMAND (ID_SETUP_LANGUAGE, OnSetupLanguage)
+ ON_COMMAND (ID_SETUP_OPTIONS, OnSetupOptions)
+ ON_COMMAND (ID_HELP_README, OnHelpReadMe)
+ ON_COMMAND (ID_HELP_LICENSE, OnHelpLicense)
+ ON_COMMAND (ID_HELP_MANUAL, OnHelpManual)
+ ON_COMMAND (ID_HELP_PROJECTHOMEPAGE, OnHelpProjectHomePage)
+ ON_COMMAND (ID_HELP_ABOUT, OnHelpAbout)
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CSekaijuApp::CSekaijuApp () {
+ m_pPlayRecordThread = NULL;
+ m_bPlayRecordThreadRunning = FALSE;
+ m_pCurChildWnd = NULL;
+ m_pCurDocument = NULL;
+ m_pOldChildWnd = NULL;
+ m_pOldDocument = NULL;
+ m_bPlaying = FALSE;
+ m_bRecording = FALSE;
+ m_lCurSpeedIndex = 2;
+ m_lOldSpeedIndex = 2;
+ long i;
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ m_pMIDIIn[i] = NULL;
+ m_pMIDIInStatus[i] = NULL;
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_pMIDIOut[i] = NULL;
+ m_pMIDIOutStatus[i] = NULL;
+ m_pTempMIDIStatus[i] = NULL;
+ }
+ m_bIgnoreNoteEvent = FALSE;
+ m_bFirstMetronome = FALSE;
+ m_bInplaceEditing = FALSE;
+ m_bInplaceListing = FALSE;
+ m_bValueUpDowning = FALSE;
+}
+
+//------------------------------------------------------------------------------
+// 唯一の CSekaijuApp オブジェクト
+//------------------------------------------------------------------------------
+CSekaijuApp theApp;
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// CSekaijuApp クラスの初期化
+BOOL CSekaijuApp::InitInstance () {
+
+ // コモンコントロールの初期化
+ // 次のInitCommonControlsは、
+ // デバッグ版又はリリース版でsekaiju.exe.manufestと共用したときに
+ // エラーを起こして起動できなくなる場合は、コメントアウトすること。
+ //InitCommonControls ();
+
+#ifdef _AFXDLL
+ Enable3dControls(); // 共有DLLの中でMFCを使用する場合
+#else
+ Enable3dControlsStatic(); // MFCと静的にリンクしている場合
+#endif
+
+ CString strMsg;
+ CString strFileName;
+
+ // EXEファイルのあるフルパス名を取得
+ TCHAR szPath[_MAX_PATH];
+ TCHAR szDrive[_MAX_DRIVE];
+ TCHAR szDir[_MAX_DIR];
+ TCHAR szFileName[_MAX_FNAME];
+ TCHAR szExt[_MAX_EXT];
+ ::GetModuleFileName (this->m_hInstance, szPath, TSIZEOF (szPath));
+ _tsplitpath (szPath, szDrive, szDir, szFileName, szExt);
+ m_strExeFilePath.Format (_T("%s%s"), szDrive, szDir);
+ if (m_strExeFilePath.Right (7) == _T("\\Debug\\")) {
+ m_strExeFilePath = m_strExeFilePath.Left (m_strExeFilePath.GetLength () - 6);
+ }
+ else if (m_strExeFilePath.Right (9) == _T("\\Release\\")) {
+ m_strExeFilePath = m_strExeFilePath.Left (m_strExeFilePath.GetLength () - 8);
+ }
+ else if (m_strExeFilePath.Right (8) == _T("\\DebugU\\")) {
+ m_strExeFilePath = m_strExeFilePath.Left (m_strExeFilePath.GetLength () - 7);
+ }
+ else if (m_strExeFilePath.Right (10) == _T("\\ReleaseU\\")) {
+ m_strExeFilePath = m_strExeFilePath.Left (m_strExeFilePath.GetLength () - 9);
+ }
+
+ // 初期化時のカレントディレクトリ取得
+ memset (szPath, 0, sizeof (szPath));
+ ::GetCurrentDirectory (MAX_PATH, szPath);
+ m_strInitialPath.Format (_T("%s"), szPath);
+
+ // INIファイルのフルパス名の変更
+ if (m_pszProfileName) {
+ delete ((void*)m_pszProfileName);
+ m_pszProfileName = NULL;
+ }
+ m_pszProfileName = new TCHAR[MAX_PATH + 1]; // 20120422修正
+ if (!m_pszProfileName) {
+ strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_FOR_EXEFILENAME);
+ AfxMessageBox (strMsg, MB_ICONSTOP);
+ return FALSE;
+ }
+ memset ((void*)m_pszProfileName, 0, sizeof (TCHAR) * (MAX_PATH + 1)); // 20120422修正
+ _sntprintf ((TCHAR*)m_pszProfileName, MAX_PATH, _T("%s%s"), m_strExeFilePath, _T("Sekaiju.ini"));
+
+ // 標準のINIファイルのオプションをロードする(最近使ったファイルを含む)
+ LoadStdProfileSettings (16);
+
+ // INIファイルから設定の読み込み
+ LoadIniFile ();
+
+ // リソースDLLの読み込み
+ if (LoadResourceDLL () == FALSE) {
+ return FALSE;
+ // この関数の後でCSekaijuApp::ExitInstanceが呼び出される。
+ }
+
+ // アプリケーション名の変更(20100128:リソースのDLL化に伴い追加)
+ TCHAR szAppName[256];
+ memset (szAppName, 0, sizeof (szAppName));
+ VERIFY (::LoadString (m_hResourceDLL, AFX_IDS_APP_TITLE, szAppName, 255));
+ free ((void*)m_pszAppName );
+ m_pszAppName = NULL;
+ m_pszAppName = _tcsdup (szAppName);
+ if (m_pszAppName == NULL) {
+ strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_FOR_EXEFILENAME);
+ ::MessageBox (NULL, strMsg, _T("Sekaiju"), MB_ICONSTOP);
+ return FALSE;
+ }
+ AfxGetModuleState()->m_lpszCurrentAppName = m_pszAppName;
+
+ // DDE、file open など標準のシェル コマンドのコマンドラインを解析。
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine (cmdInfo); //20081019位置変更
+
+ // 二重起動の防止
+ if (CheckMultiExec (&cmdInfo) == FALSE) {
+ return FALSE;
+ // この関数の後でCSekaijuApp::ExitInstanceが呼び出される。
+ }
+
+ // 最後に開いたファイルを自動的に開く場合、cmdInfoを書き換える。
+ if (m_theGeneralOption.m_bExecOpen == TRUE &&
+ m_strLastOpenFileName[0] != _T("") &&
+ cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew) {
+ // 最後に開いたファイルが存在する場合のみ(20081019)
+ if (::GetFileAttributes (m_strLastOpenFileName[0]) != -1) {
+ cmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen;
+ cmdInfo.m_strFileName = m_strLastOpenFileName[0];
+ }
+ }
+
+ // すべてのMIDI入力デバイスを開く
+ OpenAllMIDIInDevice ();
+
+ // すべてのMIDI出力デバイスを開く
+ OpenAllMIDIOutDevice ();
+
+ // すべてのMIDIインストゥルメント定義ファイル(*.ins)を読み込む
+ LoadAllMIDIInstrument ();
+
+ SelectAllMIDIInstDefNorm ();
+ SelectAllMIDIInstDefDrum ();
+
+ // カーソルの読み込み
+ m_hCursorArrow = LoadStandardCursor (IDC_ARROW);
+ m_hCursorCross = LoadStandardCursor (IDC_CROSS);
+ m_hCursorSizeWE = LoadStandardCursor (IDC_SIZEWE);
+ m_hCursorSizeNS = LoadStandardCursor (IDC_SIZENS);
+ m_hCursorSizeAll = LoadStandardCursor (IDC_SIZEALL);
+ m_hCursorSizeAllCopy = LoadCursor (IDC_SIZEALLCOPY);
+ m_hCursorNo = LoadStandardCursor (IDC_NO);
+ m_hCursorResizeWE = LoadCursor (IDC_RESIZEWE);
+ m_hCursorResizeNS = LoadCursor (IDC_RESIZENS);
+ m_hCursorResizeAll = LoadCursor (IDC_RESIZEALL);
+ m_hCursorDraw = LoadCursor (IDC_DRAW);
+ m_hCursorLine = LoadCursor (IDC_LINE);
+ m_hCursorEraser = LoadCursor (IDC_ERASER);
+ m_hCursorSelect = LoadCursor (IDC_SELECT);
+ m_hCursorSelectAdd = LoadCursor (IDC_SELECTADD);
+ m_hCursorSelect2 = LoadCursor (IDC_SELECT2);
+ m_hCursorSelectAdd2 = LoadCursor (IDC_SELECTADD2);
+ m_hCursorSpeaker = LoadCursor (IDC_SPEAKER);
+
+ // イベントの種類名の読み込み
+ long i = 0;
+ for (i = 0; i < 256; i++) {
+ m_strEventKindName[i].LoadString (IDS_EVENTKIND_00 + i);
+ if (m_strEventKindName[i] == _T("")) {
+ m_strEventKindName[i].Format (_T("0x%02X"), i);
+ }
+ }
+
+ // キー名の読み込み
+ for (i = 0; i < 256; i++) {
+ m_strNoteKeyName[i].LoadString (IDS_NOTEKEY_0S00 + i);
+ if (m_strNoteKeyName[i] == _T("")) {
+ m_strNoteKeyName[i].Format (_T("ERR"));
+ }
+ }
+
+ // デフォルトフォントの読み込み
+ CString strDefaultFontName;
+ VERIFY (strDefaultFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theDefaultFont.CreateFont (12, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strDefaultFontName);
+
+ // 一時変数の初期化
+ m_bInplaceEditing = 0;
+ m_bInplaceListing = 0;
+ m_bValueUpDowning = 0;
+
+ // 自動保存用ディレクトリの作成
+ CString strDirName1;
+ CString strDirName2;
+ strDirName1.LoadString (IDS_AUTOSAVEDIRNAME);
+ strDirName2 = m_strExeFilePath + strDirName1;
+ if (strDirName2.Right (1) == _T("\\")) {
+ strDirName2 = strDirName2.Left (strDirName2.GetLength () - 1);
+ }
+ ::CreateDirectory ((LPCTSTR)strDirName2, NULL);
+
+ // MIDIデータ用のドキュメントテンプレートを作成
+ CSekaijuDocTemplate* pDocTemplate;
+ pDocTemplate = new CSekaijuDocTemplate(
+ IDR_SEKAIJUTYPE,
+ RUNTIME_CLASS(CSekaijuDoc),
+ RUNTIME_CLASS(CTrackListFrame), // カスタム MDI 子フレーム
+ RUNTIME_CLASS(CSekaijuView));
+ AddDocTemplate(pDocTemplate);
+ m_pSekaijuDocTemplate = pDocTemplate;
+
+ //DragAcceptFiles (TRUE); // 意味なし
+ //EnableShellOpen(); // 意味なし
+
+ // メインMDIフレームウィンドウを作成
+ // ウィンドウクラス名をオリジナルなものにするためにLoadFrameではなくCreateを使う。
+ // 注意:LoadFrameで構築するとCMainFrame::PreCreateWindowでの設定が反映されない。
+ // 注意:Createで構築した場合、デフォルトメニューとアクセラレータは別途設定しなければならない。
+ CMainFrame* pMainFrame = new CMainFrame;
+ if (pMainFrame->Create (
+ NULL, // ウィンドウクラス名(CMainFrame::PreCreateWindow内で設定する)
+ this->m_pszAppName, // タイトル
+ WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // ウィンドウスタイル
+ CRect (0, 0, 640, 400), // 仮配置(CMainFrame::PreCreateWindow内で再設定する)
+ NULL, // 親
+ MAKEINTRESOURCE (IDR_MAINFRAME), // メニュー
+ 0, // ExStyle
+ NULL) == FALSE) {
+ return FALSE;
+ }
+
+ // デフォルトメニューの設定(メインMDIフレームをCreateで生成したため)
+ ASSERT (pMainFrame->m_hWnd != NULL);
+ pMainFrame->m_hMenuDefault = ::GetMenu (pMainFrame->m_hWnd);
+
+ // アクセラレータの設定(メインMDIフレームをCreateで生成したため)
+ VERIFY (pMainFrame->LoadAccelTable (MAKEINTRESOURCE(IDR_MAINFRAME)));
+ m_pMainWnd = pMainFrame;
+
+ // 解析済みコマンドラインを反映
+ if (!ProcessShellCommand (cmdInfo)) {
+ // 自動的に最後に使ったファイルを開いたが失敗した場合
+ if (m_theGeneralOption.m_bExecOpen == TRUE &&
+ cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen &&
+ cmdInfo.m_strFileName == m_strLastOpenFileName[0]) {
+ m_strLastOpenFileName[0] = _T("");
+ //AfxGetMainWnd ()->PostMessage (WM_COMMAND, ID_FILE_NEW, 0);
+ }
+ // 通常の失敗の場合
+ else {
+ return FALSE;
+ }
+ }
+
+ // メイン ウィンドウが初期化されたので、表示と更新を行う。
+ if (m_theGeneralOption.m_bRestoreWindowPlacement) {
+ if (m_theWindowPlacement.m_bIconic) {
+ m_nCmdShow = SW_SHOWMINIMIZED;
+ }
+ else if (m_theWindowPlacement.m_bZoomed) {
+ m_nCmdShow = SW_SHOWMAXIMIZED;
+ }
+ }
+ pMainFrame->ShowWindow (m_nCmdShow);
+ pMainFrame->UpdateWindow();
+
+ // メニューの更新
+ UpdateMenu ();
+
+ // 録音演奏用スレッドの開始
+ m_bPlayRecordThreadRunning = TRUE;
+ m_pPlayRecordThread = AfxBeginThread (PlayRecordThread, this);
+ if (m_pPlayRecordThread == NULL) {
+ _RPTF1 (_CRT_WARN, "PlayRecordThread Create Failed, Address=0x%p.\n", m_pPlayRecordThread);
+ // "録音再生スレッドを作成することができません。"
+ strMsg.LoadString (IDS_RECPLAYTHREAD_CREATE_ERROR);
+ AfxMessageBox (strMsg, MB_ICONSTOP);
+ }
+ else {
+ _RPTF1 (_CRT_WARN, "PlayRecordThread Create Successful, Address=0x%p.\n", m_pPlayRecordThread);
+ }
+
+ return TRUE;
+}
+
+// アプリケーションの後処理
+int CSekaijuApp::ExitInstance () {
+ m_theCriticalSection.Lock ();
+ m_bPlayRecordThreadRunning = FALSE;
+ m_theCriticalSection.Unlock ();
+
+ ::Sleep (500);
+ int nRet = CWinApp::ExitInstance ();
+
+ // INIファイルへ設定を保存
+ SaveIniFile ();
+
+ long i;
+
+ // MIDI入力デバイスを閉じる
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ if (m_pMIDIIn[i] != NULL) {
+ MIDIIn_Close (m_pMIDIIn[i]);
+ m_pMIDIIn[i] = NULL;
+ }
+ if (m_pMIDIInStatus[i]) {
+ MIDIStatus_Delete (m_pMIDIInStatus[i]);
+ m_pMIDIInStatus[i] = NULL;
+ }
+ }
+
+ // MIDI出力デバイスを閉じる
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ if (m_pMIDIOut[i] != NULL) {
+ MIDIOut_Close (m_pMIDIOut[i]);
+ m_pMIDIOut[i] = NULL;
+ }
+ if (m_pMIDIOutStatus[i]) {
+ MIDIStatus_Delete (m_pMIDIOutStatus[i]);
+ m_pMIDIOutStatus[i] = NULL;
+ }
+ if (m_pTempMIDIStatus[i]) {
+ MIDIStatus_Delete (m_pTempMIDIStatus[i]);
+ m_pTempMIDIStatus[i] = NULL;
+ }
+ }
+
+ // リソースDLLの開放
+ FreeResourceDLL ();
+
+ // INIファイルのフルパス用に割り当てられたメモリを解放する。
+ if (m_pszProfileName) {
+ delete ((void*)m_pszProfileName);
+ m_pszProfileName = NULL;
+ }
+
+ // アプリケーション名用に割り当てられたメモリを解放する(20100202:リソースのDLL化に伴い追加)
+ if (m_pszAppName) {
+ free ((void*)m_pszAppName);
+ m_pszAppName = NULL;
+ }
+
+ ::Sleep (500);
+
+ return nRet;
+
+}
+
+// CWinApp::AddDocTemplateのオーバーライド
+void CSekaijuApp::AddDocTemplate (CDocTemplate* pTemplate) {
+ if (m_pDocManager == NULL) {
+ m_pDocManager = new CSekaijuDocManager;
+ }
+ m_pDocManager->AddDocTemplate (pTemplate);
+}
+
+// CWinApp::PreTranslateMessageのオーバーライド20080809,20091222
+BOOL CSekaijuApp::PreTranslateMessage (MSG* pMsg) {
+ if (pMsg->message == WM_KEYDOWN) {
+ // インプレーステキスト入力時もしくは
+ // インプレースリスト選択時は
+ // アクセラレーターキーを効かなくする。
+ if (m_bInplaceEditing || m_bInplaceListing) {
+ return 0; // 通常の(アクセラレーターを介さない)処理
+ }
+ // 特定のウィンドウ上にフォーカスがある場合は、
+ // そのウィンドウのキー操作を優先する(20091222追加)
+ CWnd* pFocusedWnd = AfxGetMainWnd ()->GetFocus ();
+ if (pFocusedWnd != NULL) {
+ // コンボボックスの場合はGetFocus()によって、
+ // コンボボックス内の"Edit"へのポインタが取得できるので、
+ // その親のコントロールIDを調べなければならない。
+ //char szClassName[256];
+ //memset (szClassName, 0, sizeof (szClassName));
+ //HWND hFocusedWnd = pFocusedWnd->GetSafeHwnd ();
+ //GetClassName (hFocusedWnd, szClassName, sizeof (szClassName));
+ int nCtrlID = pFocusedWnd->GetDlgCtrlID ();
+ CWnd* pParentWnd = pFocusedWnd->GetParent ();
+ int nParentCtrlID = 0;
+ if (pParentWnd) {
+ nParentCtrlID = pParentWnd->GetDlgCtrlID ();
+ }
+ // ピアノロールウィンドウのツールバーのベロシティコンボボックスの場合
+ // ピアノロールウィンドウのツールバーの音長さコンボボックスの場合
+ // イベントリストウィンドウのツールバーのタイムエディットの場合
+ if (nParentCtrlID == IDC_VELOCITYCOMBO ||
+ nParentCtrlID == IDC_DURATIONCOMBO ||
+ nCtrlID == IDC_EVENTTIMEEDIT) {
+ return 0; // 通常の(アクセラレーターを介さない)処理
+ }
+ return CWinApp::PreTranslateMessage (pMsg); // アクセラレーターを介した処理
+ }
+ return CWinApp::PreTranslateMessage (pMsg); // アクセラレーターを介した処理
+ }
+ return CWinApp::PreTranslateMessage (pMsg); // アクセラレーターを介した処理
+}
+
+// アイドリング時のオーバーライド
+BOOL CSekaijuApp::OnIdle (LONG lCount) {
+ // 通常のアイドリング処理(ツールバーの描画など)
+ BOOL bRet = CWinApp::OnIdle (lCount);
+ // ツールバーの更新(アイドリング256回に1回の割合で)
+ if ((lCount & 0x000000FF) == 0) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame) {
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ if (pMainFrame->m_wndPositionScroll.GetSafeHwnd ()) {
+ if (pMainFrame->m_wndPositionScroll.IsWindowEnabled () == 0) {
+ //pMainFrame->m_wndPositionScroll.EnableWindow (1);
+ }
+ }
+ }
+ else {
+ if (pMainFrame->m_wndPositionScroll.GetSafeHwnd ()) {
+ if (pMainFrame->m_wndPositionScroll.IsWindowEnabled () != 0) {
+ //pMainFrame->m_wndPositionScroll.EnableWindow (0);
+ }
+ }
+ }
+ }
+ }
+ // 自動保存(アイドリング256回に1回の割合で)
+ if (m_theAutoSaveDlgStatus.m_nOn && (lCount & 0x000000FF) == 0) {
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ // ドキュメントが変更されている場合のみかつ保存ロックされていない場合のみ
+ if (pSekaijuDoc->IsModified () && !(pSekaijuDoc->m_bSaveLocked)) {
+ // 自動保存するべき時が来たならば
+ time_t tmCurTime;
+ time (&tmCurTime);
+ if (tmCurTime - pSekaijuDoc->m_tmLastAutoSaveTime > m_theAutoSaveDlgStatus.m_lInterval &&
+ (m_theAutoSaveDlgStatus.m_nDisableWhilePlaying & m_bPlaying) == 0 &&
+ (m_theAutoSaveDlgStatus.m_nDisableWhileRecording & m_bRecording) == 0) {
+ // 現状を自動保存
+ struct tm* pLocalTime = localtime (&tmCurTime);
+ CString strFileName1;
+ CString strFileName2;
+ CString strFileName3;
+ VERIFY (strFileName1.LoadString (IDS_AUTOSAVEFILEFORMAT));
+ strFileName2.Format (
+ strFileName1,
+ pLocalTime->tm_year + 1900,
+ pLocalTime->tm_mon + 1,
+ pLocalTime->tm_mday,
+ pLocalTime->tm_hour,
+ pLocalTime->tm_min,
+ pLocalTime->tm_sec,
+ (ULONG)pSekaijuDoc);
+ strFileName3 = m_strExeFilePath + strFileName2;
+ long lRet = pSekaijuDoc->OnSaveDocument (strFileName3);
+ // 自動保存失敗
+ if (lRet == FALSE) {
+ _RPTF1 (_CRT_WARN, "AutoSaveFile Failed. - \"%s\"\n", strFileName3);
+ }
+ // 自動保存成功
+ else {
+ _RPTF1 (_CRT_WARN, "AutoSaveFile Successful. - \"%s\"\n", strFileName3);
+ // 前回自動保存したファイルを削除(保存成功時で前回保存したファイルがある場合のみ)
+ if (pSekaijuDoc->m_tmLastAutoSaveTime != 0) {
+ pLocalTime = localtime (&(pSekaijuDoc->m_tmLastAutoSaveTime));
+ VERIFY (strFileName1.LoadString (IDS_AUTOSAVEFILEFORMAT));
+ strFileName2.Format (
+ strFileName1,
+ pLocalTime->tm_year + 1900,
+ pLocalTime->tm_mon + 1,
+ pLocalTime->tm_mday,
+ pLocalTime->tm_hour,
+ pLocalTime->tm_min,
+ pLocalTime->tm_sec,
+ (ULONG)pSekaijuDoc);
+ strFileName3 = m_strExeFilePath + strFileName2;
+ BOOL bRet = _tremove (strFileName3);
+ if (bRet == FALSE) {
+ _RPTF1 (_CRT_WARN, "AutoSaveFile Delete Failed. - \"%s\"\n", strFileName3);
+ }
+ else {
+ _RPTF1 (_CRT_WARN, "AutoSaveFile Delete Successful. - \"%s\"\n", strFileName3);
+ }
+ }
+ // 前回保存した時刻を更新
+ pSekaijuDoc->m_tmLastAutoSaveTime = tmCurTime;
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ }
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// リソースDLLの読み込み
+BOOL CSekaijuApp::LoadResourceDLL () {
+ if (m_strLanguage == _T("English")) {
+ m_hResourceDLL = ::LoadLibrary (_T("SekaijuEnu.dll"));
+ if (m_hResourceDLL == NULL) {
+ ::MessageBox (NULL, _T("SekaijuEnu.dll Load failed!!"), _T("Sekaiju"), MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ }
+ else {
+ m_hResourceDLL = ::LoadLibrary (_T("SekaijuJpn.dll"));
+ if (m_hResourceDLL == NULL) {
+ ::MessageBox (NULL, _T("SekaijuJpn.dll Load failed!!"), _T("Sekaiju"), MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ }
+ AfxSetResourceHandle (m_hResourceDLL);
+ return TRUE;
+}
+
+// リソースDLLの開放
+BOOL CSekaijuApp::FreeResourceDLL () {
+ if (m_hResourceDLL) {
+ ::FreeLibrary (m_hResourceDLL);
+ }
+ return TRUE;
+}
+
+// 二重起動の防止(起動不能の場合FALSEを返す)
+BOOL CSekaijuApp::CheckMultiExec (CCommandLineInfo* pCmdInfo) {
+ // 二重起動が許可されていないならば
+ if (!m_theGeneralOption.m_bEnableMultiExec) {
+ HWND hFindWnd = ::FindWindow (AfxGetAppName (), NULL);
+ // 二重起動であるならば
+ if (hFindWnd) {
+ ::SendMessage (hFindWnd, WM_COMMANDWAKEUP, NULL, NULL);
+ // ファイル名が指定されている場合、
+ // 既に起動している方のアプリにファイル名を渡す。
+ if (pCmdInfo->m_strFileName != _T("")) {
+ HANDLE hShare = CreateFileMapping
+ (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SHMSIZE, AfxGetAppName ());
+ if (hShare == NULL) {
+ // 共有メモリ(送信側)オープンエラー
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_SHAREMEMORY_FOR_SEND_OPEN_ERROR));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ TCHAR* pShareMem =
+ (TCHAR*)::MapViewOfFile (hShare, FILE_MAP_WRITE, 0, 0, SHMSIZE);
+ if (pShareMem == NULL) {
+ // 共有メモリ(送信側)マッピングエラー
+ ::CloseHandle (hShare);
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_SHAREMEMORY_FOR_SEND_MAPPING_ERROR));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ memset (pShareMem, 0, SHMSIZE);
+ TCSNCPY (pShareMem, (LPCTSTR)(pCmdInfo->m_strFileName), SHMSIZE / sizeof(TCHAR) - 1);
+ ::UnmapViewOfFile (pShareMem);
+ ::SendMessage (hFindWnd, WM_COMMANDREADSHM, NULL, NULL);
+ ::CloseHandle (hShare);
+ ::PostMessage (hFindWnd, WM_COMMANDFILEOPEN, NULL, NULL);
+ }
+ return FALSE;
+ // TODO:MFCのヴァージョンによっては、InitInstance内で
+ // return FALSEをするとメッセージが出てしまうという説がある。
+ }
+ // 二重起動でない
+ else {
+ return TRUE;
+ }
+ }
+ // 二重起動が許可されている
+ else {
+ return TRUE;
+ }
+}
+
+// INIファイルから設定を読み込み
+BOOL CSekaijuApp::LoadIniFile () {
+ long i;
+ TCHAR szTemp[256];
+ // [MIDIInDevice]
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ m_strMIDIInName[i] = GetProfileString (_T("MIDIInDevice"), szTemp, _T(""));
+ }
+ // [MIDIOutDevice]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ m_strMIDIOutName[i] = GetProfileString (_T("MIDIOutDevice"), szTemp, _T(""));
+ }
+ if (m_strMIDIOutName[0] == _T("")) {
+ m_strMIDIOutName[0] = _T("MIDI Mapper");
+ }
+ // [MIDIInstDefNorm]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ m_strMIDIInstDefNormName[i] = GetProfileString (_T("MIDIInstDefNorm"), szTemp,
+ i == 0 ? _T("Microsoft GS Wavetable Synth") : _T(""));
+ }
+ // [MIDIInstDefDrum]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ m_strMIDIInstDefDrumName[i] = GetProfileString (_T("MIDIInstDefDrum"), szTemp,
+ i == 0 ? _T("Microsoft GS Wavetable Synth Drumsets") : _T(""));
+ }
+ // [MIDIInSyncMode]
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ m_lMIDIInSyncMode[i] = GetProfileInt (_T("MIDIInSyncMode"), szTemp, i == 0 ? 1 : 0);
+ }
+ // [MIDIOutSyncMode]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ m_lMIDIOutSyncMode[i] = GetProfileInt (_T("MIDIOutSyncMode"), szTemp, i == 0 ? 1 : 0);
+ }
+
+ // [WindowPlacement]
+ m_theWindowPlacement.m_bIconic = (BOOL)GetProfileInt (_T("WindowPlacement"), _T("Iconic"), FALSE);
+ m_theWindowPlacement.m_bZoomed = (BOOL)GetProfileInt (_T("WindowPlacement"), _T("Zoomed"), FALSE);
+ m_theWindowPlacement.m_nX = GetProfileInt (_T("WindowPlacement"), _T("X"), CW_USEDEFAULT);
+ m_theWindowPlacement.m_nY = GetProfileInt (_T("WindowPlacement"), _T("Y"), CW_USEDEFAULT);
+ m_theWindowPlacement.m_nWidth = GetProfileInt (_T("WindowPlacement"), _T("Width"), CW_USEDEFAULT);
+ m_theWindowPlacement.m_nHeight =GetProfileInt (_T("WindowPlacement"), _T("Height"), CW_USEDEFAULT);
+
+ // [GeneralOption]
+ m_theGeneralOption.m_bEnableMultiExec = (BOOL)GetProfileInt (_T("GeneralOption"), _T("EnableMultiExec"), FALSE);
+ m_theGeneralOption.m_bEnableMultiOpen = (BOOL)GetProfileInt (_T("GeneralOption"), _T("EnableMultiOpen"), TRUE);
+ m_theGeneralOption.m_bRestoreWindowPlacement = (BOOL)GetProfileInt (_T("GeneralOption"), _T("RestoreWindowPlacement"), TRUE);
+ m_theGeneralOption.m_bExecOpen = (BOOL)GetProfileInt (_T("GeneralOption"), _T("ExecOpen"), FALSE);
+ m_theGeneralOption.m_bOpenPlay = (BOOL)GetProfileInt (_T("GeneralOption"), _T("OpenPlay"), FALSE);
+ m_theGeneralOption.m_bPlayUpdate = (BOOL)GetProfileInt (_T("GeneralOption"), _T("PlayUpdate"), TRUE);
+ m_theGeneralOption.m_bSearchUpdate = (BOOL)GetProfileInt (_T("GeneralOption"), _T("SearchUpdate"), TRUE);
+ m_theGeneralOption.m_bSearchSysx = (BOOL)GetProfileInt (_T("GeneralOption"), _T("SearchSysx"), TRUE);
+ m_theGeneralOption.m_bEnableCC111Loop = (BOOL)GetProfileInt (_T("GeneralOption"), _T("EnableCC111Loop"), TRUE);
+ m_theGeneralOption.m_bPatchSearch = (BOOL)GetProfileInt (_T("GeneralOption"), _T("PatchSearch"), TRUE);
+ m_theGeneralOption.m_bInvertCtrlMouseWheel = (BOOL)GetProfileInt (_T("GeneralOption"), _T("InvertCtrlMouseWheel"), FALSE);
+ m_theGeneralOption.m_bTrackZeroOrigin = (BOOL)GetProfileInt (_T("GeneralOption"), _T("TrackZeroOrigin"), FALSE);
+ m_theGeneralOption.m_bEventZeroOrigin = (BOOL)GetProfileInt (_T("GeneralOption"), _T("EventZeroOrigin"), FALSE);
+ m_theGeneralOption.m_bEnableAutoPageUpdate = (BOOL)GetProfileInt (_T("GeneralOption"), _T("EnableAutoPageUpdate"), TRUE);
+ m_theGeneralOption.m_bSendNoteOffHoldOffAtEnd = (BOOL)GetProfileInt (_T("GeneralOption"), _T("SendNoteOffHoldOffAtEnd"), TRUE);
+ m_theGeneralOption.m_lUpDownDelta1 = GetProfileInt (_T("GeneralOption"), _T("UpDownDelta1"), 1);
+ m_theGeneralOption.m_lUpDownDelta2 = GetProfileInt (_T("GeneralOption"), _T("UpDownDelta2"), 10);
+ m_theGeneralOption.m_lKeyVelocity1 = GetProfileInt (_T("GeneralOption"), _T("KeyVelocity1"), 80);
+ m_theGeneralOption.m_lKeyVelocity2 = GetProfileInt (_T("GeneralOption"), _T("KeyVelocity2"), 120);
+ m_theGeneralOption.m_lSpeedSlow = GetProfileInt (_T("GeneralOption"), _T("SpeedSlow"), 5000);
+ m_theGeneralOption.m_lSpeedNormal = GetProfileInt (_T("GeneralOption"), _T("SpeedNormal"), 10000);
+ m_theGeneralOption.m_lSpeedFast = GetProfileInt (_T("GeneralOption"), _T("SpeedFast"), 20000);
+ m_theGeneralOption.m_lPlayRecordInterval = GetProfileInt (_T("GeneralOption"), _T("PlayRecordInterval"), 5);
+ m_theGeneralOption.m_lOctaveSignature = GetProfileInt (_T("GeneralOption"), _T("OctaveSignature"), 3);
+
+ // [ColorOption]
+ m_theColorOption.m_lForeColor[0] = GetProfileInt (_T("ColorOption"), _T("ForeColor00"), 0x00FF0000);
+ m_theColorOption.m_lForeColor[1] = GetProfileInt (_T("ColorOption"), _T("ForeColor01"), 0x00808000);
+ m_theColorOption.m_lForeColor[2] = GetProfileInt (_T("ColorOption"), _T("ForeColor02"), 0x00008000);
+ m_theColorOption.m_lForeColor[3] = GetProfileInt (_T("ColorOption"), _T("ForeColor03"), 0x00008080);
+ m_theColorOption.m_lForeColor[4] = GetProfileInt (_T("ColorOption"), _T("ForeColor04"), 0x000000F0);
+ m_theColorOption.m_lForeColor[5] = GetProfileInt (_T("ColorOption"), _T("ForeColor05"), 0x008000F0);
+ m_theColorOption.m_lForeColor[6] = GetProfileInt (_T("ColorOption"), _T("ForeColor06"), 0x00800080);
+ m_theColorOption.m_lForeColor[7] = GetProfileInt (_T("ColorOption"), _T("ForeColor07"), 0x00FF0080);
+ m_theColorOption.m_lBackColor[0] = GetProfileInt (_T("ColorOption"), _T("BackColor00"), 0x00FFFFFF);
+ m_theColorOption.m_lBackColor[1] = GetProfileInt (_T("ColorOption"), _T("BackColor01"), 0x00C0FFFF);
+ m_theColorOption.m_lHorzColor[0] = GetProfileInt (_T("ColorOption"), _T("HorzColor00"), 0x00C0C0C0);
+ m_theColorOption.m_lHorzColor[1] = GetProfileInt (_T("ColorOption"), _T("HorzColor01"), 0x00FF8080);
+ m_theColorOption.m_lVertColor[0] = GetProfileInt (_T("ColorOption"), _T("VertColor00"), 0x00C0C0C0);
+ m_theColorOption.m_lVertColor[1] = GetProfileInt (_T("ColorOption"), _T("VertColor01"), 0x00FF8080);
+
+ // [TrackListOption1]
+ m_theTrackListOption1.m_lDefRowZoom = GetProfileInt (_T("TrackListOption1"), _T("DefRowZoom"), 24);
+ m_theTrackListOption1.m_lDefColumnZoom = GetProfileInt (_T("TrackListOption1"), _T("DefColumnZoom"), 6);
+ m_theTrackListOption1.m_lDefTimeZoom = GetProfileInt (_T("TrackListOption1"), _T("DefTimeZoom"), 6);
+ m_theTrackListOption1.m_lDefNameWidth = GetProfileInt (_T("TrackListOption1"), _T("DefNameWidth"), 12);
+ m_theTrackListOption1.m_lDefColorWidth = GetProfileInt (_T("TrackListOption1"), _T("DefColorWidth"), 2);
+ m_theTrackListOption1.m_lDefInputOnWidth = GetProfileInt (_T("TrackListOption1"), _T("DefInputOnWidth"), 4);
+ m_theTrackListOption1.m_lDefInputPortWidth = GetProfileInt (_T("TrackListOption1"), _T("DefInputPortWidth"), 16);
+ m_theTrackListOption1.m_lDefInputChWidth = GetProfileInt (_T("TrackListOption1"), _T("DefInputChWidth"), 5);
+ m_theTrackListOption1.m_lDefOutputOnWidth = GetProfileInt (_T("TrackListOption1"), _T("DefOutputOnWidth"), 4);
+ m_theTrackListOption1.m_lDefOutputPortWidth = GetProfileInt (_T("TrackListOption1"), _T("DefOutputPortWidth"), 16);
+ m_theTrackListOption1.m_lDefOutputChWidth = GetProfileInt (_T("TrackListOption1"), _T("DefOutputChWidth"), 5);
+ m_theTrackListOption1.m_lDefViewModeWidth = GetProfileInt (_T("TrackListOption1"), _T("DefViewModeWidth"), 5);
+
+ // [TrackListOption2]
+ m_theTrackListOption2.m_lDefCC000Width = GetProfileInt (_T("TrackListOption2"), _T("DefCC000Width"), 5);
+ m_theTrackListOption2.m_lDefCC032Width = GetProfileInt (_T("TrackListOption2"), _T("DefCC032Width"), 5);
+ m_theTrackListOption2.m_lDefPCWidth = GetProfileInt (_T("TrackListOption2"), _T("DefPCWidth"), 16);
+ m_theTrackListOption2.m_lDefCC007Width = GetProfileInt (_T("TrackListOption2"), _T("DefCC007Width"), 5);
+ m_theTrackListOption2.m_lDefCC010Width = GetProfileInt (_T("TrackListOption2"), _T("DefCC010Width"), 5);
+ m_theTrackListOption2.m_lDefCC091Width = GetProfileInt (_T("TrackListOption2"), _T("DefCC091Width"), 5);
+ m_theTrackListOption2.m_lDefCC093Width = GetProfileInt (_T("TrackListOption2"), _T("DefCC093Width"), 5);
+ m_theTrackListOption2.m_lDefCC094Width = GetProfileInt (_T("(TrackListOption2"), _T("DefCC094Width"), 5);
+ m_theTrackListOption2.m_lDefKeyShiftWidth = GetProfileInt (_T("TrackListOption2"), _T("DefKeyShiftWidth"), 5);
+ m_theTrackListOption2.m_lDefVelShiftWidth = GetProfileInt (_T("TrackListOption2"), _T("DefVelShiftWidth"), 5);
+ m_theTrackListOption2.m_lDefTimeShiftWidth = GetProfileInt (_T("TrackListOption2"), _T("DefTimeShiftWidth"), 5);
+ m_theTrackListOption2.m_lDefNumEventWidth = GetProfileInt (_T("TrackListOption2"), _T("DefNumEventWidth"), 8);
+ m_theTrackListOption2.m_bEnableRowZoomKey = GetProfileInt (_T("TrackListOption2"), _T("EnableRowZoomKey"), 1);
+ m_theTrackListOption2.m_bEnableColumnZoomKey = GetProfileInt (_T("TrackListOption2"), _T("EnableColumnZoomKey"), 0);
+ m_theTrackListOption2.m_bEnableTimeZoomKey = GetProfileInt (_T("TrackListOption2"), _T("EnableTimeZoomKey"), 0);
+
+ // [PianoRollOption]
+ m_thePianoRollOption.m_lDefKeyZoom = GetProfileInt (_T("PianoRollOption"), _T("DefKeyZoom"), 6);
+ m_thePianoRollOption.m_lDefVelZoom = GetProfileInt (_T("PianoRollOption"), _T("DefVelZoom"), 1);
+ m_thePianoRollOption.m_lDefTimeZoom = GetProfileInt (_T("PianoRollOption"), _T("DefTimeZoom"), 6);
+ m_thePianoRollOption.m_bEnableKeyZoomKey = GetProfileInt (_T("PianoRollOption"), _T("EnableKeyZoomKey"), 1);
+ m_thePianoRollOption.m_bEnableVelZoomKey = GetProfileInt (_T("PianoRollOption"), _T("EnableVelZoomKey"), 0);
+ m_thePianoRollOption.m_bEnableTimeZoomKey = GetProfileInt (_T("PianoRollOption"), _T("EnableTimeZoomKey"), 0);
+ m_thePianoRollOption.m_bSpeakerModeVisibleTrack = GetProfileInt (_T("PianoRollOption"), _T("SpeakerModeVisibleTrack"), 0);
+ m_thePianoRollOption.m_lGraphLineWidth = GetProfileInt (_T("PianoRollOption"), _T("GraphLineWidth"), 1);
+
+ // [EventListOption]
+ m_theEventListOption.m_lDefRowZoom = GetProfileInt (_T("EventListOption"), _T("DefRowZoom"), 20);
+ m_theEventListOption.m_lDefColumnZoom = GetProfileInt (_T("EventListOption"), _T("DefColumnZoom"), 6);
+ m_theEventListOption.m_lDefTrackWidth = GetProfileInt (_T("EventListOption"), _T("DefTrackWidth"), 16);
+ m_theEventListOption.m_lDefMillisecWidth = GetProfileInt (_T("EventListOption"), _T("DefMillisecWidth"), 16);
+ m_theEventListOption.m_lDefTimeWidth = GetProfileInt (_T("EventListOption"), _T("DefTimeWidth"), 16);
+ m_theEventListOption.m_lDefKindWidth = GetProfileInt (_T("EventListOption"), _T("DefKindWidth"), 16);
+ m_theEventListOption.m_lDefChWidth = GetProfileInt (_T("EventListOption"), _T("DefChWidth"), 8);
+ m_theEventListOption.m_lDefVal1Width = GetProfileInt (_T("EventListOption"), _T("DefVal1Width"), 16);
+ m_theEventListOption.m_lDefVal2Width = GetProfileInt (_T("EventListOption"), _T("DefVal2Width"), 16);
+ m_theEventListOption.m_lDefVal3Width = GetProfileInt (_T("EventListOption"), _T("DefVal3Width"), 16);
+ m_theEventListOption.m_bInsertEventAfter = GetProfileInt (_T("EventListOption"), _T("InsertEventAfter"), 0);
+ m_theEventListOption.m_bDuplicateEventAfter = GetProfileInt (_T("EventListOption"), _T("DuplicateEventAfter"), 0);
+ m_theEventListOption.m_bDeleteEventAfter = GetProfileInt (_T("EventListOption"), _T("DeleteEventAfter"), 1);
+ m_theEventListOption.m_bEnableRowZoomKey = GetProfileInt (_T("EventListOption"), _T("EnableRowZoomKey"), 1);
+ m_theEventListOption.m_bEnableColumnZoomKey = GetProfileInt (_T("EventListOption"), _T("EnableColumnZoomKey"), 0);
+
+ // [MusicalScoreOption]
+ m_theMusicalScoreOption.m_lDefTrackZoom = GetProfileInt (_T("MusicalScoreOption"), _T("DefTrackZoom"), 4);
+ m_theMusicalScoreOption.m_lDefTimeZoom = GetProfileInt (_T("MusicalScoreOption"), _T("DefTimeZoom"), 8);
+ m_theMusicalScoreOption.m_bEnableTrackZoomKey = GetProfileInt (_T("MusicalScoreOption"), _T("EnableTrackZoomKey"), 1);
+ m_theMusicalScoreOption.m_bEnableTimeZoomKey = GetProfileInt (_T("MusicalScoreOption"), _T("EnableTimeZoomKey"), 0);
+ m_theMusicalScoreOption.m_bSpeakerModeVisibleTrack = GetProfileInt (_T("MusicalScoreOption"), _T("SpeakerModeVisibleTrack"), 0);
+
+ // [CurrentPage]
+ m_theCurrentPage.m_lMIDIDevice = GetProfileInt (_T("CurrentPage"), _T("MIDIDevice"), 0);
+ m_theCurrentPage.m_lOption = GetProfileInt (_T("CurrentPage"), _T("Option"), 0);
+
+ // [Control]
+ m_bPlaying = FALSE;
+ m_bRecording = FALSE;
+ m_lCurSpeedIndex = GetProfileInt (_T("Control"), _T("CurSpeedIndex"), 2);
+ m_bAutoRepeat = GetProfileInt (_T("Control"), _T("AutoRepeat"), TRUE);
+
+ // [EditTrackDlgStatus]
+ m_theEditTrackDlgStatus.m_nAmount = GetProfileInt (_T("EditTrackDlgStatus"), _T("Amount"), 0);
+ m_theEditTrackDlgStatus.m_nUnit = GetProfileInt (_T("EditTrackDlgStatus"), _T("Unit"), 0);
+ m_theEditTrackDlgStatus.m_nFitChannel = GetProfileInt (_T("EditTrackDlgStatus"), _T("FitChannel"), 1);
+
+ // [EditTimeDlgStatus]
+ m_theEditTimeDlgStatus.m_nAmount = GetProfileInt (_T("EditTimeDlgStatus"), _T("Amount"), 0);
+ m_theEditTimeDlgStatus.m_nUnit = GetProfileInt (_T("EditTimeDlgStatus"), _T("Unit"), 0);
+
+ // [EditTimeSmpDlgStatus]
+ m_theEditTimeSmpDlgStatus.m_nAmount = GetProfileInt (_T("EditTimeSmpDlgStatus"), _T("Amount"), 0);
+ m_theEditTimeSmpDlgStatus.m_nUnit = GetProfileInt (_T("EditTimeSmpDlgStatus"), _T("Unit"), 0);
+
+ // [EditChannelDlgStatus]
+ m_theEditChannelDlgStatus.m_nAmount = GetProfileInt (_T("EditChannelDlgStatus"), _T("Amount"), 0);
+ m_theEditChannelDlgStatus.m_nUnit = GetProfileInt (_T("EditChannelDlgStatus"), _T("Unit"), 0);
+
+ // [EditKeyDlgStatus]
+ m_theEditKeyDlgStatus.m_nAmount = GetProfileInt (_T("EditKeyDlgStatus"), _T("Amount"), 0);
+ m_theEditKeyDlgStatus.m_nUnit = GetProfileInt (_T("EditKeyDlgStatus"), _T("Unit"), 0);
+ m_theEditKeyDlgStatus.m_nTargetNote = GetProfileInt (_T("EditKeyDlgStatus"), _T("TargetNote"), 1);
+ m_theEditKeyDlgStatus.m_nTargetKeyAfter = GetProfileInt (_T("EditKeyDlgStatus"), _T("TargetKeyAfter"), 1);
+
+ // [EditVelocityDlgStatus]
+ m_theEditVelocityDlgStatus.m_nAmount = GetProfileInt (_T("EditVelocityDlgStatus"), _T("Amount"), 0);
+ m_theEditVelocityDlgStatus.m_nUnit = GetProfileInt (_T("EditVelocityDlgStatus"), _T("Unit"), 0);
+ m_theEditVelocityDlgStatus.m_nTargetNoteOn = GetProfileInt (_T("EditVelocityDlgStatus"), _T("TargetNoteOn"), 1);
+ m_theEditVelocityDlgStatus.m_nTargetNoteOff = GetProfileInt (_T("EditVelocityDlgStatus"), _T("TargetNoteOff"), 1);
+
+ // [EditDurationDlgStatus]
+ m_theEditDurationDlgStatus.m_nAmount = GetProfileInt (_T("EditDurationDlgStatus"), _T("Amount"), 0);
+ m_theEditDurationDlgStatus.m_nUnit = GetProfileInt (_T("EditDurationDlgStatus"), _T("Unit"), 0);
+
+ // [EditValueDlgStatus]
+ m_theEditValueDlgStatus.m_nAmount = GetProfileInt (_T("EditValueDlgStatus"), _T("Amount"), 0);
+ m_theEditValueDlgStatus.m_nUnit = GetProfileInt (_T("EditValueDlgStatus"), _T("Unit"), 0);
+ m_theEditValueDlgStatus.m_nTargetKeyAfter = GetProfileInt (_T("EditValueDlgStatus"), _T("TargetKeyAfter"), 1);
+ m_theEditValueDlgStatus.m_nTargetControlChange = GetProfileInt (_T("EditValueDlgStatus"), _T("ControlChange"), 1);
+ m_theEditValueDlgStatus.m_nTargetChannelAfter = GetProfileInt (_T("EditValueDlgStatus"), _T("ChannelAfter"), 1);
+ m_theEditValueDlgStatus.m_nTargetPitchBend = GetProfileInt (_T("EditValueDlgStatus"), _T("PitchBend"), 1);
+
+ // [EditBreakupAndTrillDlgStatus]
+ m_theEditBreakupAndTrillDlgStatus.m_nDurationIndex = GetProfileInt (_T("EditBreakupAndTrillDlgStatus"), _T("DurationIndex"), 3);
+ m_theEditBreakupAndTrillDlgStatus.m_nEnableTrill = GetProfileInt (_T("EditBreakupAndTrillDlgStatus"), _T("EnableTrill"), 1);
+ m_theEditBreakupAndTrillDlgStatus.m_nKeyShift = GetProfileInt (_T("EditBreakupAndTrillDlgStatus"), _T("KeyShift"), 2);
+
+ // [EditQuantizeDlgStatus]
+ m_theEditQuantizeDlgStatus.m_nSnapTimeIndex = GetProfileInt (_T("EditQuantizeDlgStatus"), _T("SnapTimeIndex"), 3);
+ m_theEditQuantizeDlgStatus.m_nStrength = GetProfileInt (_T("EditQuantizeDlgStatus"), _T("Strength"), 100);
+ m_theEditQuantizeDlgStatus.m_nTargetNoteOn = GetProfileInt (_T("EditQuantizeDlgStatus"), _T("TargetNoteOn"), 1);
+ m_theEditQuantizeDlgStatus.m_nTargetNoteOff = GetProfileInt (_T("EditQuantizeyDlgStatus"), _T("TargetNoteOff"), 0);
+
+ // [EditBeatScanDlgStatus]
+ m_theEditBeatScanDlgStatus.m_nBeatTrackIndex = GetProfileInt (_T("EditBeatScanDlgStatus"), _T("BeatTrackIndex"), 1);
+ m_theEditBeatScanDlgStatus.m_nBeatIntervalIndex = GetProfileInt (_T("EditBeatScanDlgStatus"), _T("BeatIntervalIndex"), 0);
+ m_theEditBeatScanDlgStatus.m_nInsertTempo = GetProfileInt (_T("EditBeatScanDlgStatus"), _T("InsertTempo"), 1);
+
+ // [EditInsertMeasureDlgStatus]
+ m_theEditInsertMeasureDlgStatus.m_nPosition = GetProfileInt (_T("EditInsertMeasureDlgStatus"), _T("Position"), 1);
+ m_theEditInsertMeasureDlgStatus.m_nNumMeasure = GetProfileInt (_T("EditInsertMeasureDlgStatus"), _T("NumMeasure"), 1);
+
+ // [EditRemoveMeasureDlgStatus]
+ m_theEditRemoveMeasureDlgStatus.m_nPosition = GetProfileInt (_T("EditRemoveMeasureDlgStatus"), _T("Position"), 1);
+ m_theEditRemoveMeasureDlgStatus.m_nNumMeasure = GetProfileInt (_T("EditRemoveMeasureDlgStatus"), _T("NumMeasure"), 1);
+
+ // [MetronomeDlgStatus]
+ m_theMetronomeDlgStatus.m_nOn = GetProfileInt (_T("MetronomeDlgStatus"), _T("On"), 1);
+ m_theMetronomeDlgStatus.m_nOutputPort = GetProfileInt (_T("MetronomeDlgStatus"), _T("OutputPort"), 0);
+ m_theMetronomeDlgStatus.m_nOutputChannel = GetProfileInt (_T("MetronomeDlgStatus"), _T("OutputChannel"), 9);
+ m_theMetronomeDlgStatus.m_nNoteKey1 = GetProfileInt (_T("MetronomeDlgStatus"), _T("NoteKey1"), 60);
+ m_theMetronomeDlgStatus.m_nNoteVel1 = GetProfileInt (_T("MetronomeDlgStatus"), _T("NoteVel1"), 120);
+ m_theMetronomeDlgStatus.m_nNoteKey2 = GetProfileInt (_T("MetronomeDlgStatus"), _T("NoteKey2"), 61);
+ m_theMetronomeDlgStatus.m_nNoteVel2 = GetProfileInt (_T("MetronomeDlgStatus"), _T("NoteVel2"), 120);
+
+ // [AutoSaveDlgStatus]
+ m_theAutoSaveDlgStatus.m_nOn = GetProfileInt (_T("AutoSaveDlgStatus"), _T("On"), 1);
+ m_theAutoSaveDlgStatus.m_lInterval = GetProfileInt (_T("AutoSaveDlgStatus"), _T("Interval"), 600);
+ m_theAutoSaveDlgStatus.m_nDisableWhilePlaying = GetProfileInt (_T("AutoSaveDlgStatus"), _T("DisableWhilePlaying"), 1);
+ m_theAutoSaveDlgStatus.m_nDisableWhileRecording = GetProfileInt (_T("AutoSaveDlgStatus"),_T( "DisableWhileRecording"), 1);
+
+
+ // [LastOpenFileName]
+ m_strLastOpenFileName[0] = GetProfileString (_T("LastOpenFileName"), _T("File1"), _T(""));
+
+ // [Language]
+ m_strLanguage = GetProfileString (_T("Language"), _T("Language"), _T("Japanese"));
+ return TRUE;
+}
+
+// INIファイルに設定を保存
+BOOL CSekaijuApp::SaveIniFile () {
+ long i;
+ TCHAR szTemp[256];
+ // [MIDIInDevice]
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ WriteProfileString (_T("MIDIInDevice"), szTemp, m_strMIDIInName[i]);
+ }
+ // [MIDIOutDevice]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ WriteProfileString (_T("MIDIOutDevice"), szTemp, m_strMIDIOutName[i]);
+ }
+ // [MIDIInstDefNorm]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ WriteProfileString (_T("MIDIInstDefNorm"), szTemp, m_strMIDIInstDefNormName[i]);
+ }
+ // [MIDIInstDefDrum]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ WriteProfileString (_T("MIDIInstDefDrum"), szTemp, m_strMIDIInstDefDrumName[i]);
+ }
+ // [MIDIInSyncMode]
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ WriteProfileInt (_T("MIDIInSyncMode"), szTemp, m_lMIDIInSyncMode[i]);
+ }
+ // [MIDIOutSyncMode]
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ memset (szTemp, 0, sizeof (szTemp));
+ _sntprintf (szTemp, 255, _T("%03d"), i);
+ WriteProfileInt (_T("MIDIOutSyncMode"), szTemp, m_lMIDIOutSyncMode[i]);
+ }
+
+ // [WindowPlacement]
+ WriteProfileInt (_T("WindowPlacement"), _T("Iconic"), m_theWindowPlacement.m_bIconic);
+ WriteProfileInt (_T("WindowPlacement"), _T("Zoomed"), m_theWindowPlacement.m_bZoomed);
+ WriteProfileInt (_T("WindowPlacement"), _T("X"), m_theWindowPlacement.m_nX);
+ WriteProfileInt (_T("WindowPlacement"), _T("Y"), m_theWindowPlacement.m_nY);
+ WriteProfileInt (_T("WindowPlacement"), _T("Width"), m_theWindowPlacement.m_nWidth);
+ WriteProfileInt (_T("WindowPlacement"), _T("Height"), m_theWindowPlacement.m_nHeight);
+
+ // [GeneralOption]
+ WriteProfileInt (_T("GeneralOption"), _T("EnableMultiExec"), m_theGeneralOption.m_bEnableMultiExec);
+ WriteProfileInt (_T("GeneralOption"), _T("EnableMultiOpen"), m_theGeneralOption.m_bEnableMultiOpen);
+ WriteProfileInt (_T("GeneralOption"), _T("RestoreWindowPlacement"), m_theGeneralOption.m_bRestoreWindowPlacement);
+ WriteProfileInt (_T("GeneralOption"), _T("ExecOpen"), m_theGeneralOption.m_bExecOpen);
+ WriteProfileInt (_T("GeneralOption"), _T("OpenPlay"), m_theGeneralOption.m_bOpenPlay);
+ WriteProfileInt (_T("GeneralOption"), _T("PlayUpdate"), m_theGeneralOption.m_bPlayUpdate);
+ WriteProfileInt (_T("GeneralOption"), _T("SearchUpdate"), m_theGeneralOption.m_bSearchUpdate);
+ WriteProfileInt (_T("GeneralOption"), _T("SearchSysx"), m_theGeneralOption.m_bSearchSysx);
+ WriteProfileInt (_T("GeneralOption"), _T("EnableCC111Loop"), m_theGeneralOption.m_bEnableCC111Loop);
+ WriteProfileInt (_T("GeneralOption"), _T("PatchSearch"), m_theGeneralOption.m_bPatchSearch);
+ WriteProfileInt (_T("GeneralOption"), _T("InvertCtrlMouseWheel"), m_theGeneralOption.m_bInvertCtrlMouseWheel);
+ WriteProfileInt (_T("GeneralOption"), _T("TrackZeroOrigin"), m_theGeneralOption.m_bTrackZeroOrigin);
+ WriteProfileInt (_T("GeneralOption"), _T("EventZeroOrigin"), m_theGeneralOption.m_bEventZeroOrigin);
+ WriteProfileInt (_T("GeneralOption"), _T("EnableAutoPageUpdate"), m_theGeneralOption.m_bEnableAutoPageUpdate);
+ WriteProfileInt (_T("GeneralOption"), _T("SendNoteOffHoldOffAtEnd"), m_theGeneralOption.m_bSendNoteOffHoldOffAtEnd);
+ WriteProfileInt (_T("GeneralOption"), _T("UpDownDelta1"), m_theGeneralOption.m_lUpDownDelta1);
+ WriteProfileInt (_T("GeneralOption"), _T("UpDownDelta2"), m_theGeneralOption.m_lUpDownDelta2);
+ WriteProfileInt (_T("GeneralOption"), _T("KeyVelocity1"), m_theGeneralOption.m_lKeyVelocity1);
+ WriteProfileInt (_T("GeneralOption"), _T("KeyVelocity2"), m_theGeneralOption.m_lKeyVelocity2);
+ WriteProfileInt (_T("GeneralOption"), _T("SpeedSlow"), m_theGeneralOption.m_lSpeedSlow);
+ WriteProfileInt (_T("GeneralOption"), _T("SpeedNormal"), m_theGeneralOption.m_lSpeedNormal);
+ WriteProfileInt (_T("GeneralOption"), _T("SpeedFast"), m_theGeneralOption.m_lSpeedFast);
+ WriteProfileInt (_T("GeneralOption"), _T("PlayRecordInterval"), m_theGeneralOption.m_lPlayRecordInterval);
+ WriteProfileInt (_T("GeneralOption"), _T("OctaveSignature"), m_theGeneralOption.m_lOctaveSignature);
+
+ // [ColorOption]
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor00"), m_theColorOption.m_lForeColor[0]);
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor01"), m_theColorOption.m_lForeColor[1]);
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor02"), m_theColorOption.m_lForeColor[2]);
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor03"), m_theColorOption.m_lForeColor[3]);
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor04"), m_theColorOption.m_lForeColor[4]);
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor05"), m_theColorOption.m_lForeColor[5]);
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor06"), m_theColorOption.m_lForeColor[6]);
+ WriteProfileInt (_T("ColorOption"), _T("ForeColor07"), m_theColorOption.m_lForeColor[7]);
+ WriteProfileInt (_T("ColorOption"), _T("BackColor00"), m_theColorOption.m_lBackColor[0]);
+ WriteProfileInt (_T("ColorOption"), _T("BackColor01"), m_theColorOption.m_lBackColor[1]);
+ WriteProfileInt (_T("ColorOption"), _T("HorzColor00"), m_theColorOption.m_lHorzColor[0]);
+ WriteProfileInt (_T("ColorOption"), _T("HorzColor01"), m_theColorOption.m_lHorzColor[1]);
+ WriteProfileInt (_T("ColorOption"), _T("VertColor00"), m_theColorOption.m_lVertColor[0]);
+ WriteProfileInt (_T("ColorOption"), _T("VertColor01"), m_theColorOption.m_lVertColor[1]);
+
+ // [TrackListOption1]
+ WriteProfileInt (_T("TrackListOption1"), _T("DefRowZoom"), m_theTrackListOption1.m_lDefRowZoom);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefColumnZoom"), m_theTrackListOption1.m_lDefColumnZoom);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefTimeZoom"), m_theTrackListOption1.m_lDefTimeZoom);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefNameWidth"), m_theTrackListOption1.m_lDefNameWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefColorWidth"), m_theTrackListOption1.m_lDefColorWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefInputOnWidth"), m_theTrackListOption1.m_lDefInputOnWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefInputPortWidth"), m_theTrackListOption1.m_lDefInputPortWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefInputChWidth"), m_theTrackListOption1.m_lDefInputChWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefOutputOnWidth"), m_theTrackListOption1.m_lDefOutputOnWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefOutputPortWidth"), m_theTrackListOption1.m_lDefOutputPortWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefOutputChWidth"), m_theTrackListOption1.m_lDefOutputChWidth);
+ WriteProfileInt (_T("TrackListOption1"), _T("DefViewModeWidth"), m_theTrackListOption1.m_lDefViewModeWidth);
+
+ // [TrackListOption2]
+ WriteProfileInt (_T("TrackListOption2"), _T("DefCC000Width"), m_theTrackListOption2.m_lDefCC000Width);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefCC032Width"), m_theTrackListOption2.m_lDefCC032Width);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefPCWidth"), m_theTrackListOption2.m_lDefPCWidth);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefCC007Width"), m_theTrackListOption2.m_lDefCC007Width);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefCC010Width"), m_theTrackListOption2.m_lDefCC010Width);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefCC091Width"), m_theTrackListOption2.m_lDefCC091Width);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefCC093Width"), m_theTrackListOption2.m_lDefCC093Width);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefCC094Width"), m_theTrackListOption2.m_lDefCC094Width);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefKeyShiftWidth"), m_theTrackListOption2.m_lDefKeyShiftWidth);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefVelShiftWidth"), m_theTrackListOption2.m_lDefVelShiftWidth);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefTimeShiftWidth"), m_theTrackListOption2.m_lDefTimeShiftWidth);
+ WriteProfileInt (_T("TrackListOption2"), _T("DefNumEventWidth"), m_theTrackListOption2.m_lDefNumEventWidth);
+ WriteProfileInt (_T("TrackListOption2"), _T("EnableRowZoomKey"), m_theTrackListOption2.m_bEnableRowZoomKey);
+ WriteProfileInt (_T("TrackListOption2"), _T("EnableColumnZoomKey"), m_theTrackListOption2.m_bEnableColumnZoomKey);
+ WriteProfileInt (_T("TrackListOption2"), _T("EnableTimeZoomKey"), m_theTrackListOption2.m_bEnableTimeZoomKey);
+
+ // [PianoRollOption]
+ WriteProfileInt (_T("PianoRollOption"), _T("DefKeyZoom"), m_thePianoRollOption.m_lDefKeyZoom);
+ WriteProfileInt (_T("PianoRollOption"), _T("DefVelZoom"), m_thePianoRollOption.m_lDefVelZoom);
+ WriteProfileInt (_T("PianoRollOption"), _T("DefTimeZoom"), m_thePianoRollOption.m_lDefTimeZoom);
+ WriteProfileInt (_T("PianoRollOption"), _T("EnableKeyZoomKey"), m_thePianoRollOption.m_bEnableKeyZoomKey);
+ WriteProfileInt (_T("PianoRollOption"), _T("EnableVelZoomKey"), m_thePianoRollOption.m_bEnableVelZoomKey);
+ WriteProfileInt (_T("PianoRollOption"), _T("EnableTimeZoomKey"), m_thePianoRollOption.m_bEnableTimeZoomKey);
+ WriteProfileInt (_T("PianoRollOption"), _T("SpeakerModeVisibleTrack"), m_thePianoRollOption.m_bSpeakerModeVisibleTrack);
+ WriteProfileInt (_T("PianoRollOption"), _T("GraphLineWidth"), m_thePianoRollOption.m_lGraphLineWidth);
+
+ // [EventListOption]
+ WriteProfileInt (_T("EventListOption"), _T("DefRowZoom"), m_theEventListOption.m_lDefRowZoom);
+ WriteProfileInt (_T("EventListOption"), _T("DefColumnZoom"), m_theEventListOption.m_lDefColumnZoom);
+ WriteProfileInt (_T("EventListOption"), _T("DefTrackWidth"), m_theEventListOption.m_lDefTrackWidth);
+ WriteProfileInt (_T("EventListOption"), _T("DefMillisecWidth"), m_theEventListOption.m_lDefMillisecWidth);
+ WriteProfileInt (_T("EventListOption"), _T("DefTimeWidth"), m_theEventListOption.m_lDefTimeWidth);
+ WriteProfileInt (_T("EventListOption"), _T("DefKindWidth"), m_theEventListOption.m_lDefKindWidth);
+ WriteProfileInt (_T("EventListOption"), _T("DefChWidth"), m_theEventListOption.m_lDefChWidth);
+ WriteProfileInt (_T("EventListOption"), _T("DefVal1Width"), m_theEventListOption.m_lDefVal1Width);
+ WriteProfileInt (_T("EventListOption"), _T("DefVal2Width"), m_theEventListOption.m_lDefVal2Width);
+ WriteProfileInt (_T("EventListOption"), _T("DefVal3Width"), m_theEventListOption.m_lDefVal3Width);
+ WriteProfileInt (_T("EventListOption"), _T("InsertEventAfter"), m_theEventListOption.m_bInsertEventAfter);
+ WriteProfileInt (_T("EventListOption"), _T("DuplicateEventAfter"), m_theEventListOption.m_bDuplicateEventAfter);
+ WriteProfileInt (_T("EventListOption"), _T("DeleteEventAfter"), m_theEventListOption.m_bDeleteEventAfter);
+ WriteProfileInt (_T("EventListOption"), _T("EnableRowZoomKey"), m_theEventListOption.m_bEnableRowZoomKey);
+ WriteProfileInt (_T("EventListOption"), _T("EnableColumnZoomKey"), m_theEventListOption.m_bEnableColumnZoomKey);
+
+ // [MusicalScoreOption]
+ WriteProfileInt (_T("MusicalScoreOption"), _T("DefTrackZoom"), m_theMusicalScoreOption.m_lDefTrackZoom);
+ WriteProfileInt (_T("MusicalScoreOption"), _T("DefTimeZoom"), m_theMusicalScoreOption.m_lDefTimeZoom);
+ WriteProfileInt (_T("MusicalScoreOption"), _T("EnableTrackZoomKey"), m_theMusicalScoreOption.m_bEnableTrackZoomKey);
+ WriteProfileInt (_T("MusicalScoreOption"), _T("EnableTimeZoomKey"), m_theMusicalScoreOption.m_bEnableTimeZoomKey);
+ WriteProfileInt (_T("MusicalScoreOption"), _T("SpeakerModeVisibleTrack"), m_theMusicalScoreOption.m_bSpeakerModeVisibleTrack);
+
+ // [CurrentPage]
+ WriteProfileInt (_T("CurrentPage"), _T("MIDIDevice"), m_theCurrentPage.m_lMIDIDevice);
+ WriteProfileInt (_T("CurrentPage"), _T("Option"), m_theCurrentPage.m_lOption);
+
+ // [Control]
+ WriteProfileInt (_T("Control"), _T("Playing"),m_bPlaying);
+ WriteProfileInt (_T("Control"), _T("Recording"), m_bRecording);
+ WriteProfileInt (_T("Control"), _T("CurSpeedIndex"), m_lCurSpeedIndex);
+ WriteProfileInt (_T("Control"), _T("AutoRepeat"), m_bAutoRepeat);
+
+ // [EditTrackDlgStatus]
+ WriteProfileInt (_T("EditTrackDlgStatus"), _T("Amount"), m_theEditTrackDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditTrackDlgStatus"), _T("Unit"), m_theEditTrackDlgStatus.m_nUnit);
+ WriteProfileInt (_T("EditTrackDlgStatus"), _T("FitChannel"), m_theEditTrackDlgStatus.m_nFitChannel);
+
+ // [EditTimeDlgStatus]
+ WriteProfileInt (_T("EditTimeDlgStatus"), _T("Amount"), m_theEditTimeDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditTimeDlgStatus"), _T("Unit"), m_theEditTimeDlgStatus.m_nUnit);
+
+ // [EditTimeSmpDlgStatus]
+ WriteProfileInt (_T("EditTimeSmpDlgStatus"), _T("Amount"), m_theEditTimeSmpDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditTimeSmpDlgStatus"), _T("Unit"), m_theEditTimeSmpDlgStatus.m_nUnit);
+
+ // [EditChannelDlgStatus]
+ WriteProfileInt (_T("EditChannelDlgStatus"), _T("Amount"), m_theEditChannelDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditChannelDlgStatus"), _T("Unit"), m_theEditChannelDlgStatus.m_nUnit);
+
+ // [EditKeyDlgStatus]
+ WriteProfileInt (_T("EditKeyDlgStatus"), _T("Amount"), m_theEditKeyDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditKeyDlgStatus"), _T("Unit"), m_theEditKeyDlgStatus.m_nUnit);
+ WriteProfileInt (_T("EditKeyDlgStatus"), _T("TargetNote"), m_theEditKeyDlgStatus.m_nTargetNote);
+ WriteProfileInt (_T("EditKeyDlgStatus"), _T("TargetKeyAfter"), m_theEditKeyDlgStatus.m_nTargetKeyAfter);
+
+ // [EditVelocityDlgStatus]
+ WriteProfileInt (_T("EditVelocityDlgStatus"), _T("Amount"), m_theEditVelocityDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditVelocityDlgStatus"), _T("Unit"), m_theEditVelocityDlgStatus.m_nUnit);
+ WriteProfileInt (_T("EditVelocityDlgStatus"), _T("TargetNoteOn"), m_theEditVelocityDlgStatus.m_nTargetNoteOn);
+ WriteProfileInt (_T("EditVelocityDlgStatus"), _T("TargetNoteOff"), m_theEditVelocityDlgStatus.m_nTargetNoteOff);
+
+ // [EditDurationDlgStatus]
+ WriteProfileInt (_T("EditDurationDlgStatus"), _T("Amount"), m_theEditDurationDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditDurationDlgStatus"), _T("Unit"), m_theEditDurationDlgStatus.m_nUnit);
+
+ // [EditValueDlgStatus]
+ WriteProfileInt (_T("EditValueDlgStatus"), _T("Amount"), m_theEditValueDlgStatus.m_nAmount);
+ WriteProfileInt (_T("EditValueDlgStatus"), _T("Unit"), m_theEditValueDlgStatus.m_nUnit);
+ WriteProfileInt (_T("EditValueDlgStatus"), _T("TargetKeyAfter"), m_theEditValueDlgStatus.m_nTargetKeyAfter);
+ WriteProfileInt (_T("EditValueDlgStatus"), _T("ControlChange"), m_theEditValueDlgStatus.m_nTargetControlChange);
+ WriteProfileInt (_T("EditValueDlgStatus"), _T("ChannelAfter"), m_theEditValueDlgStatus.m_nTargetChannelAfter);
+ WriteProfileInt (_T("EditValueDlgStatus"), _T("PitchBend"), m_theEditValueDlgStatus.m_nTargetPitchBend);
+
+ // [EditBreakupAndTrillDlgStatus]
+ WriteProfileInt (_T("EditBreakupAndTrillDlgStatus"), _T("DurationIndex"), m_theEditBreakupAndTrillDlgStatus.m_nDurationIndex);
+ WriteProfileInt (_T("EditBreakupAndTrillDlgStatus"), _T("EnableTrill"), m_theEditBreakupAndTrillDlgStatus.m_nEnableTrill);
+ WriteProfileInt (_T("EditBreakupAndTrillDlgStatus"), _T("KeyShift"), m_theEditBreakupAndTrillDlgStatus.m_nKeyShift);
+
+ // [EditQuantizeDlgStatus]
+ WriteProfileInt (_T("EditQuantizeDlgStatus"), _T("SnapTimeIndex"), m_theEditQuantizeDlgStatus.m_nSnapTimeIndex);
+ WriteProfileInt (_T("EditQuantizeDlgStatus"), _T("Strength"), m_theEditQuantizeDlgStatus.m_nStrength);
+ WriteProfileInt (_T("EditQuantizeDlgStatus"), _T("TargetNoteOn"), m_theEditQuantizeDlgStatus.m_nTargetNoteOn);
+ WriteProfileInt (_T("EditQuantizeDlgStatus"), _T("TargetNoteOff"), m_theEditQuantizeDlgStatus.m_nTargetNoteOff);
+
+ // [EditBeatScanDlgStatus]
+ WriteProfileInt (_T("EditBeatScanDlgStatus"), _T("BeatTrackIndex"), m_theEditBeatScanDlgStatus.m_nBeatTrackIndex);
+ WriteProfileInt (_T("EditBeatScanDlgStatus"), _T("BeatIntervalIndex"), m_theEditBeatScanDlgStatus.m_nBeatIntervalIndex);
+ WriteProfileInt (_T("EditBeatScanDlgStatus"), _T("InsertTempo"), m_theEditBeatScanDlgStatus.m_nInsertTempo);
+
+ // [EditInsertMeasureDlgStatus]
+ WriteProfileInt (_T("EditInsertMeasureDlgStatus"), _T("Position"), m_theEditInsertMeasureDlgStatus.m_nPosition);
+ WriteProfileInt (_T("EditInsertMeasureDlgStatus"), _T("NumMeasure"), m_theEditInsertMeasureDlgStatus.m_nNumMeasure);
+
+ // [EditRemoveMeasureDlgStatus]
+ WriteProfileInt (_T("EditRemoveMeasureDlgStatus"), _T("Position"), m_theEditRemoveMeasureDlgStatus.m_nPosition);
+ WriteProfileInt (_T("EditRemoveMeasureDlgStatus"), _T("NumMeasure"), m_theEditRemoveMeasureDlgStatus.m_nNumMeasure);
+
+ // [MetronomeDlgStatus]
+ WriteProfileInt (_T("MetronomeDlgStatus"), _T("On"), m_theMetronomeDlgStatus.m_nOn);
+ WriteProfileInt (_T("MetronomeDlgStatus"), _T("OutputPort"), m_theMetronomeDlgStatus.m_nOutputPort);
+ WriteProfileInt (_T("MetronomeDlgStatus"), _T("OutputChannel"), m_theMetronomeDlgStatus.m_nOutputChannel);
+ WriteProfileInt (_T("MetronomeDlgStatus"), _T("NoteKey1"), m_theMetronomeDlgStatus.m_nNoteKey1);
+ WriteProfileInt (_T("MetronomeDlgStatus"), _T("NoteVel1"), m_theMetronomeDlgStatus.m_nNoteVel1);
+ WriteProfileInt (_T("MetronomeDlgStatus"), _T("NoteKey2"), m_theMetronomeDlgStatus.m_nNoteKey2);
+ WriteProfileInt (_T("MetronomeDlgStatus"), _T("NoteVel2"), m_theMetronomeDlgStatus.m_nNoteVel2);
+
+ // [AutoSaveDlgStatus]
+ WriteProfileInt (_T("AutoSaveDlgStatus"), _T("On"), m_theAutoSaveDlgStatus.m_nOn);
+ WriteProfileInt (_T("AutoSaveDlgStatus"), _T("Interval"), m_theAutoSaveDlgStatus.m_lInterval);
+ WriteProfileInt (_T("AutoSaveDlgStatus"), _T("DisableWhilePlaying"), m_theAutoSaveDlgStatus.m_nDisableWhilePlaying);
+ WriteProfileInt (_T("AutoSaveDlgStatus"), _T("DisableWhileRecording"), m_theAutoSaveDlgStatus.m_nDisableWhileRecording);
+
+ // [LastOpenFileName]
+ WriteProfileString (_T("LastOpenFileName"), _T("File1"), m_strLastOpenFileName[0]);
+
+ // [Language]
+ WriteProfileString (_T("Language"), _T("Language"), m_strLanguage);
+
+ return TRUE;
+}
+
+
+// すべてのMIDIインストゥルメント定義ファイル(*.ins)を読み込む
+long CSekaijuApp::LoadAllMIDIInstrument () {
+ long i = 0;
+ // 既にMIDIインストゥルメントが読み込まれいている場合は削除
+ for (i = 0; i < MAXMIDIINSTRUMENTNUM; i++) {
+ if (m_pMIDIInstrument[i]) {
+ MIDIInstrument_Delete (m_pMIDIInstrument[i]);
+ m_pMIDIInstrument[i] = NULL;
+ }
+ }
+ // 空のMIDIインストゥルメントを生成 // 20100220廃止
+ //m_pMIDIInstrument = MIDIInstrument_Create ();
+ //if (m_pMIDIInstrument == NULL) {
+ // //_RPTF0 (_CRT_WARN, "エラー:OnCreate内でMIDIインストゥルメントを読み込めません。\n");
+ // //MessageBox (g_hMainWnd, MIDIINSTRUMENT_CANT_LOAD, APPNAME, MB_ICONSTOP);
+ // return 0;
+ //}
+ // 拡張子(*.ins)のファイルを全て読み込む
+ i = 0;
+ CString strFileName1;
+ CString strFileName2;
+ VERIFY (strFileName1.LoadString (IDS_INSTRUMENTFILENAME));
+ strFileName2 = m_strExeFilePath + strFileName1;
+ HANDLE hFind = NULL;
+ WIN32_FIND_DATA fd;
+ hFind = ::FindFirstFile ((LPCTSTR)strFileName2, &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ do {
+ if (_tcscmp (fd.cFileName, _T(".")) != 0 &&
+ _tcscmp (fd.cFileName, _T("..")) != 0) {
+ CString strFileName3;
+ CString strFileName4;
+ VERIFY (strFileName3.LoadString (IDS_INSTRUMENTDIRNAME));
+ strFileName4 = m_strExeFilePath + strFileName3 + fd.cFileName;
+ m_pMIDIInstrument[i] = MIDIInstrument_Load ((LPCTSTR)strFileName4); // 20100220変更
+ if (m_pMIDIInstrument[i] == NULL) {
+ _RPTF1 (_CRT_WARN, "MIDIInstDefFile Load Failed. - \"%s\"\n", strFileName4);
+ }
+ else {
+ _RPTF1 (_CRT_WARN, "MIDIInstDefFile Load Successful. - \"%s\"\n", strFileName4);
+ }
+ i++;
+ }
+ } while (::FindNextFile (hFind, &fd) && i < MAXMIDIINSTRUMENTNUM); // 20100220条件追加
+ ::FindClose (hFind);
+ }
+ return i;
+}
+
+
+long CSekaijuApp::SelectAllMIDIInstDefNorm () {
+ long lPort = 0;
+ long j = 0;
+ CString strMsg;
+ CString strMsg2;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ // インストゥルメント定義名称よりインストゥルメント定義へのポインタを取得
+ for (j = 0; j < MAXMIDIINSTRUMENTNUM; j++) {
+ if (m_pMIDIInstrument[j] != NULL) {
+ m_pMIDIInstDefNorm[lPort] = MIDIInstrument_GetInstrumentDefinitionFromTitle
+ (m_pMIDIInstrument[j], m_strMIDIInstDefNormName[lPort]);
+ if (m_pMIDIInstDefNorm[lPort] != NULL) {
+ break;
+ }
+ }
+ }
+ // インストゥルメント定義が見つかった
+ if (m_pMIDIInstDefNorm[lPort] != NULL) {
+ _RPTF2 (_CRT_WARN, "MIDIInstDef[%d] Find Successful. - \"%s\"\n",
+ lPort, m_strMIDIInstDefNormName[lPort]);
+ }
+ // インストゥルメント定義が見つからなかった
+ else {
+ _RPTF2 (_CRT_WARN, "MIDIInstDef[%d] Find Failed. - \"%s\"\n",
+ lPort, m_strMIDIInstDefNormName[lPort]);
+ if (m_strMIDIInstDefNormName[lPort] != _T("")) { // 20080829修正
+ // %s\n-MIDIインストゥルメント定義[%d]が見つかりません。
+ strMsg.LoadString (IDS_S_N_MIDIINSTDEF_D_FIND_FAILED);
+ strMsg2.Format (strMsg, m_strMIDIInstDefNormName[lPort], lPort + 1);
+ AfxMessageBox (strMsg2, MB_OK | MB_ICONEXCLAMATION);
+ }
+ m_strMIDIInstDefNormName[lPort] = _T("");
+ }
+ }
+ return 1;
+}
+
+long CSekaijuApp::SelectAllMIDIInstDefDrum () {
+ long lPort = 0;
+ long j = 0;
+ CString strMsg;
+ CString strMsg2;
+ for (lPort = 0; lPort < MAXMIDIINDEVICENUM; lPort++) {
+ // インストゥルメント定義名称よりインストゥルメント定義へのポインタを取得
+ for (j = 0; j < MAXMIDIINSTRUMENTNUM; j++) {
+ if (m_pMIDIInstrument[j] != NULL) {
+ m_pMIDIInstDefDrum[lPort] = MIDIInstrument_GetInstrumentDefinitionFromTitle
+ (m_pMIDIInstrument[j], m_strMIDIInstDefDrumName[lPort]);
+ if (m_pMIDIInstDefDrum[lPort] != NULL) {
+ break;
+ }
+ }
+ }
+ // インストゥルメント定義が見つかった
+ if (m_pMIDIInstDefDrum[lPort] != NULL) {
+ _RPTF2 (_CRT_WARN, "MIDIInstDef[%d] Find Successful. - \"%s\"\n",
+ lPort, m_strMIDIInstDefDrumName[lPort]);
+ }
+ // インストゥルメント定義が見つからなかった
+ else {
+ _RPTF2 (_CRT_WARN, "MIDIInstDef[%d] Find Failed. - \"%s\"\n",
+ lPort, m_strMIDIInstDefDrumName[lPort]);
+ if (m_strMIDIInstDefDrumName[lPort] != _T("")) { // 20080829修正
+ // %s\n-MIDIインストゥルメント定義[%d]が見つかりません。
+ strMsg.LoadString (IDS_S_N_MIDIINSTDEF_D_FIND_FAILED);
+ strMsg2.Format (strMsg, m_strMIDIInstDefDrumName[lPort], lPort + 1);
+ AfxMessageBox (strMsg2, MB_OK | MB_ICONEXCLAMATION);
+ }
+ m_strMIDIInstDefDrumName[lPort] = _T("");
+ }
+ }
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+// オペレーション
+//-----------------------------------------------------------------------------
+
+// メニューの更新
+void CSekaijuApp::UpdateMenu () {
+ CMenu* pMenu = AfxGetMainWnd ()->GetMenu ();
+ CString str1;
+ CString str2;
+ str1.LoadString (IDS_CONTROL_SPEEDSLOW);
+ str2.Format (str1, m_theGeneralOption.m_lSpeedSlow / 100);
+ pMenu->ModifyMenu (ID_CONTROL_SPEEDSLOW, MF_BYCOMMAND, ID_CONTROL_SPEEDSLOW, (LPCTSTR)str2);
+ str1.LoadString (IDS_CONTROL_SPEEDNORMAL);
+ str2.Format (str1, m_theGeneralOption.m_lSpeedNormal / 100);
+ pMenu->ModifyMenu (ID_CONTROL_SPEEDNORMAL, MF_BYCOMMAND, ID_CONTROL_SPEEDNORMAL, (LPCTSTR)str2);
+ str1.LoadString (IDS_CONTROL_SPEEDFAST);
+ str2.Format (str1, m_theGeneralOption.m_lSpeedFast / 100);
+ pMenu->ModifyMenu (ID_CONTROL_SPEEDFAST, MF_BYCOMMAND, ID_CONTROL_SPEEDFAST, (LPCTSTR)str2);
+}
+
+// 現在のウィンドウと現在のドキュメントへのポインタを更新
+void CSekaijuApp::UpdateCurWndAndDocPtr () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ // カレント子ウィンドウの更新
+ m_pCurChildWnd = (CMDIChildWnd*)(pMainFrame->GetActiveFrame ());
+ // 以前のドキュメントとカレントドキュメントの更新
+ if (m_pCurChildWnd) {
+ m_pOldDocument = m_pCurDocument;
+ m_pCurDocument = m_pCurChildWnd->GetActiveDocument ();
+ }
+ else {
+ m_pOldDocument = m_pCurDocument;
+ m_pCurDocument = NULL;
+ }
+ // カレントドキュメントが変更された場合
+ if (m_pCurDocument != m_pOldDocument) {
+ CSekaijuDoc* pOldSekaijuDoc = (CSekaijuDoc*)m_pOldDocument;
+ CSekaijuDoc* pCurSekaijuDoc = (CSekaijuDoc*)m_pCurDocument;
+ // ドキュメントがある場合クリティカルセクションロック
+ if (pOldSekaijuDoc) {
+ pOldSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ if (pCurSekaijuDoc) {
+ pCurSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ this->m_theCriticalSection.Lock ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ //CScrollBar* pPositionScroll = &(pMainFrame->m_wndPositionScroll);
+ // 演奏用ドキュメント・記録用ドキュメントの変更処理
+ // 古いドキュメントがある場合
+ if (pOldSekaijuDoc) {
+ // 録音中の場合は強制停止(20080709追加)(20081003修正)
+ if (m_bRecording) {
+ // 注意:録音中に突然閉じられた場合pCurHistoryUnit取得不可。
+ // 注意:これはPostNcDestroyから呼び出される。CSekaijuDoc::OnCloseDocumentより後。
+ // 注意:よってCSekaijuDoc::OnCloseDocumentでStopRecordingしておくこと。
+ StopRecording (pOldSekaijuDoc);
+ }
+ // 旧ドキュメントのMIDIクロックの強制停止
+ if (pOldSekaijuDoc->m_pMIDIClock) {
+ MIDIClock_Stop (pOldSekaijuDoc->m_pMIDIClock);
+ }
+ // 発音の強制停止
+ SendAllNoteOff ();
+ SendAllHold1Off ();
+ SendAllSostenutoOff ();
+ SendAllHold2Off ();
+ SendAllSoundOff ();
+ // 新しいドキュメントがある場合
+ if (pCurSekaijuDoc) {
+ // ポジションスクロールバーの範囲設定
+ long lEndTime = MIDIData_GetEndTime (pCurSekaijuDoc->m_pMIDIData);
+ pMainFrame->SetPositionScrollRange (0, lEndTime, TRUE);
+ // MIDIクロックのsスピードと同期モードをアプリケーションに合わせる(20090630廃止)
+ // pCurSekaijuDoc->ApplyAppCurSpeedIndex ();
+ // 演奏中又は録音中の場合は、MIDIStatusを更新する。
+ if (m_bPlaying || m_bRecording) {
+ ResetTempMIDIStatusArray ();
+ pCurSekaijuDoc->TimeMIDIStatus
+ (pCurSekaijuDoc->m_lOldTime, m_pTempMIDIStatus);
+ long lFlags = m_bPlaying ? SDS_ALL : SDS_ALL & ‾SDS_NOTE;
+ m_bIgnoreNoteEvent = TRUE; // 20090625追加
+ SendDifferentStatus (lFlags);
+ }
+ // 演奏中の場合は、新ドキュメントの演奏を開始する。
+ // 録音中の場合は、新ドキュメントの録音を開始する。
+ if (m_bPlaying || m_bRecording) {
+ MIDIClock_Start (pCurSekaijuDoc->m_pMIDIClock);
+ }
+ }
+ // 新しいドキュメントがない場合
+ else {
+ m_bPlaying = FALSE;
+ m_bRecording = FALSE;
+ }
+ }
+ this->m_theCriticalSection.Unlock ();
+ // ドキュメントがある場合クリティカルセクション解放
+ if (m_pOldDocument) {
+ ((CSekaijuDoc*)m_pOldDocument)->m_theCriticalSection.Unlock ();
+ }
+ if (m_pCurDocument) {
+ ((CSekaijuDoc*)m_pCurDocument)->m_theCriticalSection.Unlock ();
+ }
+ }
+ _RPTF2 (_CRT_WARN,
+ "CMainFrame::UpdateCurWndAndDocPtr : m_pCurDocument=%p, m_pOldDocument=%p.\n",
+ m_pCurDocument, m_pOldDocument);
+}
+
+// MIDI同期入力ポート番号と同期入力モードを取得する(なければFALSEを返す)
+BOOL CSekaijuApp::GetCurSyncInputPortAndMode (long* pPort, long* pMode) {
+ long lSyncPort = 0;
+ long lSyncMode = 0;
+ for (lSyncPort = 0; lSyncPort < MAXMIDIINDEVICENUM; lSyncPort++) {
+ if (m_lMIDIInSyncMode[lSyncPort] == 1 || m_lMIDIInSyncMode[lSyncPort] == 2) {
+ *pPort = lSyncPort;
+ *pMode = m_lMIDIInSyncMode[lSyncPort];
+ return TRUE;
+ }
+ }
+ *pPort = 0;
+ *pMode = 0;
+ return FALSE;
+}
+
+
+
+// PlayRecordThread-演奏・記録用スレッド
+UINT CSekaijuApp::PlayRecordThread (LPVOID pInfo) {
+ // 注意:静的なメンバ関数はthisポインタにアクセスすることができない。
+ CString strMsg;
+ strMsg = ("CSekaijuApp::PlayRecordThread Started.\n");
+ _RPTF0 (_CRT_WARN, strMsg);
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)pInfo;
+ while (pSekaijuApp->m_bPlayRecordThreadRunning != FALSE) {
+ pSekaijuApp->PlayRecordProc (pInfo);
+ ::Sleep (pSekaijuApp->m_theGeneralOption.m_lPlayRecordInterval);
+ }
+ strMsg = ("CSekaijuApp::PlayRecordThread Finished.\n");
+ _RPTF0 (_CRT_WARN, strMsg);
+ return 1;
+}
+
+
+// PlayRecordProc(約5ミリ秒おきにCSekaijuApp::PlayRecordThreadから呼び出される。)
+BOOL CSekaijuApp::PlayRecordProc (LPVOID pInfo) {
+ BYTE byMsg[1024];
+ long lLen;
+ long i, j;
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)pInfo;
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)m_pCurDocument;
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pSekaijuDoc == NULL || pSekaijuApp == NULL) {
+ return FALSE;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return FALSE;
+ }
+ // クリティカルセクションロック
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDIClock* pMIDIClock = pSekaijuDoc->m_pMIDIClock;
+ if (pMIDIData == NULL || pMIDIClock == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ return FALSE;
+ }
+ long lCurTime = 0;
+ long lCurMillisec = 0;
+ lCurTime = MIDIClock_GetTickCount (pMIDIClock);
+ lCurMillisec = MIDIClock_GetMillisec (pMIDIClock);
+ pSekaijuDoc->m_lNewTime = lCurTime;
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+
+ // データの入力処理(記録用)
+ // 各MIDI入力デバイスについて
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ // MIDI入力デバイスが有効ならば
+ if (m_pMIDIIn[i] != NULL) {
+ long lMIDIInSyncMode = pSekaijuApp->m_lMIDIInSyncMode[i];
+ // MIDIメッセージの取得できる限り
+ while (1) {
+ // MIDIメッセージの取得
+ memset (byMsg, 0, sizeof (byMsg));
+ lLen = MIDIIn_GetMIDIMessage (m_pMIDIIn[i], byMsg, sizeof (byMsg));
+ if (lLen <= 0) {
+ break;
+ }
+ // MIDIInStatusへの記録
+ MIDIStatus_PutMIDIMessage (m_pMIDIInStatus[i], byMsg, lLen);
+ // アクティブセンシングの場合
+ if (byMsg[0] == 0xFE) {
+ ;
+ }
+ // MIDIタイムコードクォーターフレームの場合
+ else if (byMsg[0] == 0xF1 || byMsg[0] == 0xF0) {
+ if (lMIDIInSyncMode >= 2) {
+ if (pMIDIClock) {
+ MIDIClock_PutMIDIMessage (pMIDIClock, byMsg, lLen);
+ }
+ }
+ }
+ // MIDIタイミングクロックの場合
+ else if (byMsg[0] == 0xF8) {
+ if (lMIDIInSyncMode == 1) {
+ if (pMIDIClock) {
+ MIDIClock_PutMIDIMessage (pMIDIClock, byMsg, lLen);
+ }
+ }
+ }
+ // ソングポジションセレクタの場合
+ else if (byMsg[0] == 0xF2) {
+ if (lMIDIInSyncMode == 1) {
+ long lVal = ((byMsg[2] & 0x7F) << 7) | (byMsg[1] & 0x7F);
+ long lTickCount = lVal * lTimeResolution / 4;
+ SetPlayPosition (pSekaijuDoc, lTickCount);
+ }
+ }
+ // スタートの場合
+ else if (byMsg[0] == 0xFA && pSekaijuDoc) {
+ if (pMIDIClock && !m_bPlaying && !m_bRecording) {
+ pMainFrame->PostMessage (WM_COMMAND, ID_CONTROL_TOBEGIN, 0);
+ pMainFrame->PostMessage (WM_COMMAND, ID_CONTROL_PLAY, 0);
+ }
+ else if (pMIDIClock && m_bPlaying && !m_bRecording) { // 20090704追加
+ pMainFrame->PostMessage (WM_COMMAND, ID_CONTROL_TOBEGIN, 0);
+ pMainFrame->PostMessage (WM_COMMAND, ID_CONTROL_PLAY, 0);
+ }
+ }
+ // コンティニューの場合
+ else if (byMsg[0] == 0xFB && pSekaijuDoc) {
+ if (pSekaijuDoc->m_pMIDIClock && !m_bPlaying && !m_bRecording) {
+ pMainFrame->PostMessage (WM_COMMAND, ID_CONTROL_PLAY, 0);
+ }
+ }
+ // ストップの場合
+ else if (byMsg[0] == 0xFC && pSekaijuDoc) {
+ if (pSekaijuDoc->m_pMIDIClock && (m_bPlaying || m_bRecording)) {
+ pMainFrame->PostMessage (WM_COMMAND, ID_CONTROL_PLAY, 0);
+ }
+ }
+ // MIDIチャンネルメッセージの場合
+ else if (0x80 <= byMsg[0] && byMsg[0] <= 0xEF && pSekaijuDoc) {
+ // シンクロスタート処理
+ if (m_bRecording && m_lCurSpeedIndex == 0) {
+ m_lCurSpeedIndex = m_lOldSpeedIndex;
+ MIDIClock_Stop (pMIDIClock);
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ MIDIClock_Start (pMIDIClock);
+ }
+ // リアルタイム入力処理
+ MIDITrack* pMIDITrack = NULL;
+ forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) {
+ long lInputOn = MIDITrack_GetInputOn (pMIDITrack);
+ long lInputPort = MIDITrack_GetInputPort (pMIDITrack);
+ long lInputChannel = MIDITrack_GetInputChannel (pMIDITrack);
+ long lOutputOn = MIDITrack_GetOutputOn (pMIDITrack);
+ long lOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (lInputOn && lInputPort == i && lInputChannel == (byMsg[0] & 0x0F)) {
+ // 出力チャンネルの変換
+ BYTE byMsg2[sizeof(byMsg)];
+ memset (byMsg2, 0, sizeof (byMsg));
+ memcpy (byMsg2, byMsg, sizeof (byMsg));
+ if (0 <= lOutputChannel && lOutputChannel < 16) {
+ byMsg2[0] &= 0xF0;
+ byMsg2[0] |= (BYTE)lOutputChannel;
+ }
+ // 音出し処理(演奏中でなくかつ録音中でない場合のみ)
+ if (!(m_bPlaying && m_bRecording)) {
+ MIDIOut* pMIDIOut = NULL;
+ MIDIStatus* pMIDIOutStatus = NULL;
+ if (0 <= lOutputPort && lOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = m_pMIDIOut[lOutputPort];
+ pMIDIOutStatus = m_pMIDIOutStatus [lOutputPort];
+ }
+ if (pMIDIOut) {
+ //TODO:MIDIメッセージがループバックする場合下記を無効にしてください。
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMsg2, lLen);
+ }
+ if (pMIDIOutStatus) {
+ MIDIStatus_PutMIDIMessage (pMIDIOutStatus, byMsg2, lLen);
+ }
+ }
+ // このMIDIメッセージをMIDIデータに記録
+ if (m_bRecording) {
+ MIDIEvent* pMIDIEvent = MIDIEvent_Create
+ (pSekaijuDoc->m_lNewTime, (byMsg[0] & 0xF0), byMsg2, lLen);
+ if (pMIDIEvent) {
+ //pMIDIEvent->m_lUserFlag |= MIDIEVENT_REALTIMEGENERATE;
+ MIDITrack_InsertEvent (pMIDITrack, pMIDIEvent);
+ // ノートオフの場合のノートオンとの結合処理
+ if (MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ long lTempRecordedEventCount = m_theTempRecordedEventArray.GetSize ();
+ long j;
+ for (j = lTempRecordedEventCount - 1; j >= 0; j--) {
+ MIDIEvent* pTempEvent =
+ (MIDIEvent*)(m_theTempRecordedEventArray.GetAt (j));
+ if (MIDIEvent_IsNoteOn (pTempEvent) &&
+ pTempEvent->m_pNextCombinedEvent == NULL) {
+ if (MIDIEvent_GetChannel (pTempEvent) ==
+ MIDIEvent_GetChannel (pMIDIEvent)) {
+ if (MIDIEvent_GetKey (pTempEvent) ==
+ MIDIEvent_GetKey (pMIDIEvent)) {
+ pTempEvent->m_pNextCombinedEvent = pMIDIEvent;
+ pMIDIEvent->m_pPrevCombinedEvent = pTempEvent;
+ }
+ }
+ }
+ }
+ //MIDIEvent_Combine (pMIDIEvent);
+ }
+ m_theTempRecordedEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ }
+ }
+ // システムエクスクルーシブメッセージの場合
+ else if (byMsg[0] == 0xF0 || byMsg[0] == 0xF7) {
+ // シンクロスタート処理
+ if (m_bRecording && m_lCurSpeedIndex == 0) {
+ m_lCurSpeedIndex = m_lOldSpeedIndex;
+ MIDIClock_Stop (pMIDIClock);
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ MIDIClock_Start (pMIDIClock);
+ }
+ // リアルタイム入力処理
+ MIDITrack* pMIDITrack = NULL;
+ forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) {
+ long lInputOn = MIDITrack_GetInputOn (pMIDITrack);
+ long lInputPort = MIDITrack_GetInputPort (pMIDITrack);
+ long lInputChannel = MIDITrack_GetInputChannel (pMIDITrack);
+ long lOutputOn = MIDITrack_GetOutputOn (pMIDITrack);
+ long lOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (lInputOn && lInputPort == i && lInputChannel == -1) {
+ // 音出し処理(演奏中でなくかつ録音中でない場合のみ)
+ if (!(m_bPlaying && m_bRecording)) {
+ MIDIOut* pMIDIOut = NULL;
+ if (0 <= lOutputPort && lOutputPort < MAXMIDIOUTDEVICENUM) {
+ pMIDIOut = m_pMIDIOut[lOutputPort];
+ }
+ if (pMIDIOut) {
+ //TODO:MIDIメッセージがループバックする場合下記を無効にしてください。
+ MIDIOut_PutMIDIMessage (pMIDIOut, byMsg, lLen);
+ }
+ }
+ // このMIDIメッセージをMIDIデータに記録
+ if (m_bRecording) {
+ MIDITrack_InsertSysExEvent
+ (pMIDITrack, pSekaijuDoc->m_lNewTime, byMsg, lLen);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // MIDIタイミングクロックとSMPTE/MTCの送出処理(20090624追加)
+ if (m_bPlaying) {
+ long lOutputPort;
+ // MIDIタイミングクロック数計算(20090620追加)
+ long lNumMIDITimingClock = 0;
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lOldClock = pSekaijuDoc->m_lOldTime * 24 / lTimeResolution;
+ long lNewClock = pSekaijuDoc->m_lNewTime * 24 / lTimeResolution;
+ lNumMIDITimingClock = lNewClock - lOldClock;
+ lNumMIDITimingClock = MAX (0, lNumMIDITimingClock);
+ }
+ // MIDIタイミングクロックの作成(20090620追加)
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0xF8;
+ // MIDIタイミングクロック出力処理(20090620追加)
+ for (lOutputPort = 0; lOutputPort < MAXMIDIOUTDEVICENUM; lOutputPort++) {
+ if (pSekaijuApp->m_lMIDIOutSyncMode[lOutputPort] == 1) {
+ if (m_pMIDIOut[lOutputPort]) {
+ for (j = 0; j < lNumMIDITimingClock; j++) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 1);
+ }
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ for (j = 0; j < lNumMIDITimingClock; j++) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, 1);
+ }
+ }
+ }
+ }
+ // 前回の時:分:秒:フレーム格納用変数
+ static long lOldSec;
+ static long lOldMinute;
+ static long lOldHour;
+ static long lOldFrame[4];
+ // 現在の時:分:秒:フレーム計算(20090624追加)
+ long lMillisec = lCurMillisec % 1000;
+ long lSec = (lCurMillisec / 1000) % 60;
+ long lMinute = (lCurMillisec / 60000) % 60;
+ long lHour = (lCurMillisec / 3600000);
+ long lFrame[4] = {
+ lMillisec * 24 / 1000, lMillisec * 25 / 1000,
+ lMillisec * 2997 / 100000, lMillisec * 30 / 1000};
+ // SMPTE24,SMPTE25,SMPTE29.97,SMPTE30用のMIDIタイムコードクォーターフレームを作成
+ memset (byMsg, 0, sizeof (byMsg));
+ long lFrameRate;
+ for (lFrameRate = 0; lFrameRate < 4; lFrameRate++) {
+ byMsg[lFrameRate * 16 + 0] = 0xF1;
+ byMsg[lFrameRate * 16 + 1] = 0x00 | (lFrame[lFrameRate] & 0x0F);
+ byMsg[lFrameRate * 16 + 2] = 0xF1;
+ byMsg[lFrameRate * 16 + 3] = 0x10 | ((lFrame[lFrameRate] >> 4) & 0x0F);
+ byMsg[lFrameRate * 16 + 4] = 0xF1;
+ byMsg[lFrameRate * 16 + 5] = 0x20 | (lSec & 0x0F);
+ byMsg[lFrameRate * 16 + 6] = 0xF1;
+ byMsg[lFrameRate * 16 + 7] = 0x30 | ((lSec >> 4) & 0x0F);
+ byMsg[lFrameRate * 16 + 8] = 0xF1;
+ byMsg[lFrameRate * 16 + 9] = 0x40 | (lMinute & 0x0F);
+ byMsg[lFrameRate * 16 + 10] = 0xF1;
+ byMsg[lFrameRate * 16 + 11] = 0x50 | ((lMinute >> 4) & 0x0F);
+ byMsg[lFrameRate * 16 + 12] = 0xF1;
+ byMsg[lFrameRate * 16 + 13] = 0x60 | (lHour & 0x0F);
+ byMsg[lFrameRate * 16 + 14] = 0xF1;
+ byMsg[lFrameRate * 16 + 15] = 0x70 | ((lFrameRate & 0x03) << 1) | ((lHour >> 4) & 0x01);
+ }
+ // MIDIタイムコードクォーターフレーム出力処理(20090624追加)
+ for (lOutputPort = 0; lOutputPort < MAXMIDIOUTDEVICENUM; lOutputPort++) {
+ lFrameRate = pSekaijuApp->m_lMIDIOutSyncMode[lOutputPort] - 2;
+ if (0 <= lFrameRate && lFrameRate <= 3) {
+ // 現在の時:分:秒:フレームが前回の時:分:秒:フレームと異なる場合のみ
+ if (lFrameRate == 0 && (lFrame[0] != lOldFrame[0] || lSec != lOldSec || lMinute != lOldMinute) ||
+ lFrameRate == 1 && (lFrame[1] != lOldFrame[1] || lSec != lOldSec || lMinute != lOldMinute) ||
+ lFrameRate == 2 && (lFrame[2] != lOldFrame[2] || lSec != lOldSec || lMinute != lOldMinute) ||
+ lFrameRate == 3 && (lFrame[3] != lOldFrame[3] || lSec != lOldSec || lMinute != lOldMinute)) {
+ if (m_pMIDIOut[lOutputPort]) {
+ for (j = 0; j < 8; j++) {
+ long lPos = lFrameRate * 16 + j * 2;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], &byMsg[lPos], 2);
+ }
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ for (j = 0; j < 8; j++) {
+ long lPos = lFrameRate * 16 + j * 2;
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], &byMsg[lPos], 2);
+ }
+ }
+ }
+ }
+ }
+ // 前回の時:分:秒:フレームに現在の時:分:秒:フレームを格納
+ lOldSec = lSec;
+ lOldMinute = lMinute;
+ lOldHour = lHour;
+ lOldFrame[0] = lFrame[0];
+ lOldFrame[1] = lFrame[1];
+ lOldFrame[2] = lFrame[2];
+ lOldFrame[3] = lFrame[3];
+ }
+
+ // メトロノーム出力処理(20080825追加)
+ if (m_bRecording && m_theMetronomeDlgStatus.m_nOn) {
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lOldMeasure, lOldBeat, lOldTick;
+ MIDIData_BreakTime (pMIDIData,
+ pSekaijuDoc->m_lOldTime, &lOldMeasure, &lOldBeat, &lOldTick);
+ long lNewMeasure, lNewBeat, lNewTick;
+ MIDIData_BreakTime (pMIDIData,
+ pSekaijuDoc->m_lNewTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ long lOutputPort = CLIP (0, m_theMetronomeDlgStatus.m_nOutputPort, 15);
+ long lOutputChannel = CLIP (0, m_theMetronomeDlgStatus.m_nOutputChannel, 15);
+ // 最初の1小節目の強打を鳴らすためのトリック
+ if (pSekaijuDoc->m_lOldTime == pSekaijuDoc->m_lNewTime &&
+ lOldBeat == 0 && lOldTick == 0 && this->m_bFirstMetronome == TRUE) {
+ lOldMeasure --;
+ }
+ m_bFirstMetronome = FALSE;
+ long lMeasure = 0;
+ for (lMeasure = lOldMeasure; lMeasure < lNewMeasure; lMeasure++) {
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0x90 | (BYTE)lOutputChannel;
+ byMsg[1] = CLIP (0, m_theMetronomeDlgStatus.m_nNoteKey1, 127);
+ byMsg[2] = CLIP (1, m_theMetronomeDlgStatus.m_nNoteVel1, 127);
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 3);
+ }
+ byMsg[2] = 0;
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 3);
+ }
+ }
+ long lBeat = 0;
+ for (lBeat = lOldBeat; lBeat < lNewBeat; lBeat++) {
+ if (1) {
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0x90 | (BYTE)lOutputChannel;
+ byMsg[1] = CLIP (0, m_theMetronomeDlgStatus.m_nNoteKey2, 127);
+ byMsg[2] = CLIP (1, m_theMetronomeDlgStatus.m_nNoteVel2, 127);
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 3);
+ }
+ byMsg[2] = 0;
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 3);
+ }
+ }
+ }
+ }
+ }
+
+ // MIDIデータの出力処理(演奏用)
+ if (m_bPlaying) {
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ // 各トラックについて
+ forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) {
+ // このトラックの出力がONならば
+ if (MIDITrack_GetOutputOn (pMIDITrack)) {
+ long lOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ lTime = CLIP (0, lTime + MIDITrack_GetTimePlus (pMIDITrack), 0x7FFFFFFF);
+ if (pSekaijuDoc->m_lOldTime <= lTime && lTime < pSekaijuDoc->m_lNewTime) {
+ // MIDIチャンネルイベントの場合
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ memset (byMsg, 0, sizeof (byMsg));
+ lLen = MIDIEvent_GetLen (pMIDIEvent);
+ MIDIEvent_GetData (pMIDIEvent, byMsg, lLen);
+ // 出力チャンネルが設定されている場合はそのチャンネルに従う
+ if (0 <= lOutputChannel && lOutputChannel < 16) {
+ byMsg[0] &= 0xF0;
+ byMsg[0] |= (BYTE)lOutputChannel;
+ }
+ // キー+とベロシティ+の反映
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ byMsg[1] = (BYTE)CLIP (0, byMsg[1] + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ byMsg[2] = (BYTE)CLIP (1, byMsg[2] + MIDITrack_GetVelocityPlus (pMIDITrack), 127);
+ }
+ else if (MIDIEvent_IsNoteOff (pMIDIEvent) || MIDIEvent_IsKeyAftertouch (pMIDIEvent)) {
+ byMsg[1] = (BYTE)CLIP (0, byMsg[1] + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ }
+ // 演奏位置を動かして発音状態を復元した直後は二重発音・二重消音を防止する
+ if (m_bIgnoreNoteEvent &&
+ !(MIDIEvent_IsNoteOn (pMIDIEvent) && lTime == pSekaijuDoc->m_lOldTime) &&
+ !(MIDIEvent_IsNoteOff (pMIDIEvent) && lTime == pSekaijuDoc->m_lOldTime) ||
+ m_bIgnoreNoteEvent == FALSE) {
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, lLen);
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, lLen);
+ }
+ }
+ else {
+ //_RPTF3 (_CRT_WARN, "PutMIDIMessage Ignored (%02x%02x%02x...)\n",
+ // byMsg[0], byMsg[1], byMsg[2]);
+ }
+ }
+ // システムエクスクルーシブイベントの場合
+ else if (MIDIEvent_IsSysExEvent (pMIDIEvent)) {
+ memset (byMsg, 0, sizeof (byMsg));
+ lLen = MIDIEvent_GetLen (pMIDIEvent);
+ MIDIEvent_GetData (pMIDIEvent, byMsg, lLen);
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, lLen);
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, lLen);
+ }
+ }
+ // テンポイベントの場合
+ else if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ if (pMIDIClock) {
+ MIDIClock_SetTempo (pMIDIClock, lTempo);
+ }
+ }
+ }
+ }
+ }
+ }
+ // 二十発音防止用のm_bIngoreNoteEventフラグのクリア
+ if (pSekaijuDoc->m_lOldTime != pSekaijuDoc->m_lNewTime) {
+ m_bIgnoreNoteEvent = FALSE;
+ }
+ // 演奏範囲タイムの更新
+ pSekaijuDoc->m_lOldTime = pSekaijuDoc->m_lNewTime;
+ // 録音中でない場合かつ終端に達した場合
+ long lEndTime = MIDIData_GetEndTime (pSekaijuDoc->m_pMIDIData);
+ if (!m_bRecording &&
+ pSekaijuDoc->m_lOldTime > lEndTime) {
+ // オートリピート処理
+ if (m_bAutoRepeat) {
+ if (m_theGeneralOption.m_bSendNoteOffHoldOffAtEnd) {
+ SendAllNoteOff (); // 20081027追加
+ SendAllHold1Off (); // 20081219追加
+ SendAllSostenutoOff (); // 20081219追加
+ SendAllHold2Off (); // 20081219追加
+ }
+ // CC#111の位置からループ開始する場合(RPGツクール方式) // 20081211追加
+ if (m_theGeneralOption.m_bEnableCC111Loop) {
+ // 最後のCC#111イベントのタイムを探索
+ long lCC111Time = 0;
+ long lCC111Millisec = 0;
+ long lTempo = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == 111) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime > lCC111Time) {
+ lCC111Time = lTime;
+ }
+ }
+ }
+ }
+ }
+ lCC111Millisec = MIDIData_TimeToMillisec (pMIDIData, lCC111Time);
+ MIDIData_FindTempo (pMIDIData, lCC111Time, &lTempo);
+ MIDIClock_Stop (pMIDIClock);
+ MIDIClock_SetTickCount (pMIDIClock, lCC111Time);
+ MIDIClock_SetMillisec (pMIDIClock, lCC111Millisec);
+ if (lTempo != 0) {
+ MIDIClock_SetTempo (pMIDIClock, lTempo);
+ }
+ pSekaijuDoc->m_lOldTime = lCC111Time;
+ pSekaijuDoc->m_lNewTime = lCC111Time;
+ MIDIClock_Start (pMIDIClock);
+ }
+ // 最初からループ開始する場合
+ else {
+ MIDIClock_Reset (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_lOldTime = 0;
+ pSekaijuDoc->m_lNewTime = 0;
+ }
+ }
+ // 自動停止処理
+ else {
+ if (m_theGeneralOption.m_bSendNoteOffHoldOffAtEnd) {
+ SendAllNoteOff (); // 20081027追加
+ SendAllHold1Off (); // 20081218追加
+ SendAllSostenutoOff (); // 20081218追加
+ SendAllHold2Off (); // 20081218追加
+ }
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_lOldTime = lEndTime;
+ pSekaijuDoc->m_lNewTime = lEndTime;
+ }
+ }
+ }
+
+ // クリティカルセクション解放
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return TRUE;
+}
+
+// 全ポートにオールホールド1オフ(CC#64-0)を送信
+void CSekaijuApp::SendAllHold1Off () {
+ int i, j;
+ BYTE byMsg[3] = {0xB0, 64, 0};
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ for (j = 0; j < 16; j++) {
+ byMsg[0] = 0xB0 | j;
+ if (m_pMIDIOut[i]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[i], byMsg, 3);
+ }
+ if (m_pMIDIOutStatus[i]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[i], byMsg, 3);
+ }
+ }
+ }
+}
+
+// 全ポートにオールソステヌートオフ(CC#66-0)を送信
+void CSekaijuApp::SendAllSostenutoOff () {
+ int i, j;
+ BYTE byMsg[3] = {0xB0, 66, 0};
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ for (j = 0; j < 16; j++) {
+ byMsg[0] = 0xB0 | j;
+ if (m_pMIDIOut[i]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[i], byMsg, 3);
+ }
+ if (m_pMIDIOutStatus[i]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[i], byMsg, 3);
+ }
+ }
+ }
+}
+
+
+// 全ポートにオールホールド2オフ(CC#69-0)を送信
+void CSekaijuApp::SendAllHold2Off () {
+ int i, j;
+ BYTE byMsg[3] = {0xB0, 69, 0};
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ for (j = 0; j < 16; j++) {
+ byMsg[0] = 0xB0 | j;
+ if (m_pMIDIOut[i]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[i], byMsg, 3);
+ }
+ if (m_pMIDIOutStatus[i]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[i], byMsg, 3);
+ }
+ }
+ }
+}
+
+// 全ポートにオールサウンドオフ(CC#120)を送信
+void CSekaijuApp::SendAllSoundOff () {
+ int i, j;
+ BYTE byMsg[3] = {0xB0, 120, 0};
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ for (j = 0; j < 16; j++) {
+ byMsg[0] = 0xB0 | j;
+ if (m_pMIDIOut[i]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[i], byMsg, 3);
+ }
+ if (m_pMIDIOutStatus[i]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[i], byMsg, 3);
+ }
+ }
+ }
+}
+
+// 全ポートにリセットオールコントローラー(CC#121)を送信
+void CSekaijuApp::SendResetAllController () {
+ int i, j;
+ BYTE byMsg[3] = {0xB0, 121, 0};
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ for (j = 0; j < 16; j++) {
+ byMsg[0] = 0xB0 | j;
+ if (m_pMIDIOut[i]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[i], byMsg, 3);
+ }
+ if (m_pMIDIOutStatus[i]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[i], byMsg, 3);
+ }
+ }
+ }
+}
+
+// 全ポートにオールノートオフ(CC#123)を送信
+void CSekaijuApp::SendAllNoteOff () {
+ int i, j;
+ BYTE byMsg[3] = {0xB0, 123, 0};
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ for (j = 0; j < 16; j++) {
+ byMsg[0] = 0xB0 | j;
+ if (m_pMIDIOut[i]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[i], byMsg, 3);
+ }
+ if (m_pMIDIOutStatus[i]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[i], byMsg, 3);
+ }
+ }
+ }
+}
+
+// m_theMIDIStatusArrayの内容をリセット
+void CSekaijuApp::ResetMIDIStatusArray () {
+ for (int nPort = 0; nPort < MAXMIDIOUTDEVICENUM; nPort++) {
+ if (m_pMIDIOutStatus[nPort]) {
+ MIDIStatus_PutReset (m_pMIDIOutStatus[nPort]);
+ }
+ }
+}
+
+// m_theTempMIDIStatusArrayの内容をリセットします。
+void CSekaijuApp::ResetTempMIDIStatusArray () {
+ for (int nPort = 0; nPort < MAXMIDIOUTDEVICENUM; nPort++) {
+ if (m_pTempMIDIStatus[nPort]) {
+ MIDIStatus_PutReset (m_pTempMIDIStatus[nPort]);
+ }
+ }
+}
+
+
+// 全ポートにMIDIStatusArrayとTempMIDIStatusArrayの差分のみを送信
+// lFlags : 復元するイベントの種類を示すフラグのビット和。
+// Sekaiju.hに示したSDS_系フラグを足し合わせる。
+void CSekaijuApp::SendDifferentStatus (long lFlags) {
+ int nPort, i, j;
+ long lCurVal;
+ long lTempVal;
+ BYTE byCurBuf[128];
+ BYTE byTempBuf[128];
+ BYTE byMsg[256];
+ BYTE byCC101[] = { 0, 0, 0, 0};
+ BYTE byCC100[] = { 0, 1, 2, 5};
+ BYTE byCC99[] = { 1, 1, 1, 1, 1, 1, 1, 1,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+
+ };
+ BYTE byCC98[] = { 8, 9, 10, 32, 33, 99, 100, 102,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ };
+ // 各ポート毎に
+ for (nPort = 0; nPort < MAXMIDIOUTDEVICENUM; nPort++) {
+ if (m_pMIDIOutStatus[nPort] == NULL || m_pMIDIOut[nPort] == NULL ||
+ m_pTempMIDIStatus[nPort] == NULL) {
+ continue;
+ }
+ // マスターボリューム
+ if (lFlags & SDS_MASTERVOLUME) {
+ long lCurMasterVolume = MIDIStatus_GetMasterVolume (m_pMIDIOutStatus[nPort]);
+ long lTempMasterVolume = MIDIStatus_GetMasterVolume (m_pTempMIDIStatus[nPort]);
+ if (lCurMasterVolume != lTempMasterVolume) {
+ // マスターボリューム {0xF0, 0x7F, 0xid, 0x04, 0x01, 0xll, 0xmm, 0xF7}
+ byMsg[0] = 0xF0;
+ byMsg[1] = 0x7F;
+ byMsg[2] = 0x7F;
+ byMsg[3] = 0x04;
+ byMsg[4] = 0x01;
+ byMsg[5] = 0x00;
+ byMsg[6] = (BYTE)CLIP (0, lTempMasterVolume, 127);
+ byMsg[7] = 0xF7;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 8);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 8);
+ }
+ }
+ // 各パート毎に
+ for (i = 0; i < 16; i++) {
+ MIDIPart* pMIDIPart = MIDIStatus_GetMIDIPart (m_pMIDIOutStatus[nPort], i);
+ MIDIPart* pTempPart = MIDIStatus_GetMIDIPart (m_pTempMIDIStatus[nPort], i);
+ // キーアフタータッチ
+ if (lFlags & SDS_KEYAFTER) {
+ MIDIPart_GetKeyAfterTouchEx (pMIDIPart, byCurBuf, 128);
+ MIDIPart_GetKeyAfterTouchEx (pTempPart, byTempBuf, 128);
+ for (j = 0; j < 128; j++) {
+ if (byCurBuf[j] != byTempBuf[j]) {
+ byMsg[0] = 0xA0 + (BYTE)i;
+ byMsg[1] = (BYTE)j;
+ byMsg[2] = byTempBuf[j];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ }
+ }
+ // コントロールチェンジ
+ if (lFlags & SDS_CONTROLCHANGE) {
+ MIDIPart_GetControlChangeEx (pMIDIPart, byCurBuf, 128);
+ MIDIPart_GetControlChangeEx (pTempPart, byTempBuf, 128);
+ for (j = 0; j < 120; j++) { // 20081218 128→120に変更
+ if (byCurBuf[j] != byTempBuf[j] && j != 0 && j != 32) { // 20111016パッチチェンジは除く
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = (BYTE)j;
+ byMsg[2] = byTempBuf[j];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ }
+ }
+ // RPN
+ if (lFlags & SDS_RPN) {
+ for (j = 0; j < sizeof (byCC101); j++) {
+ lCurVal =
+ (MIDIPart_GetRPNMSB (pMIDIPart, byCC101[j], byCC100[j]) << 7) |
+ (MIDIPart_GetRPNLSB (pMIDIPart, byCC101[j], byCC100[j]) & 0x7F);
+ lTempVal =
+ (MIDIPart_GetRPNMSB (pTempPart, byCC101[j], byCC100[j]) << 7) |
+ (MIDIPart_GetRPNLSB (pTempPart, byCC101[j], byCC100[j]) & 0x7F);
+ if (lCurVal != lTempVal) {
+ // CC#99=127(NRPN=NULL)(初回のみ)
+ if (byCurBuf[99] != 127) {
+ byCurBuf[99] = 127;
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 99;
+ byMsg[2] = 127;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ // CC#98=127(NRPN=NULL)(初回のみ)
+ if (byCurBuf[98] != 127) {
+ byCurBuf[98] = 127;
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 98;
+ byMsg[2] = 127;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ // CC#101
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 101;
+ byMsg[2] = byCC101[j];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ // CC#100
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 100;
+ byMsg[2] = byCC100[j];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ // CC#6
+ if ((lCurVal >> 7) != (lTempVal >> 7)) {
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 6;
+ byMsg[2] = (BYTE)(lTempVal >> 7);
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ // CC#38
+ if ((lCurVal & 0x7F) != (lTempVal & 0x7F)) {
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 38;
+ byMsg[2] = (BYTE)(lTempVal & 0x7F);
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ }
+ }
+ }
+ // NRPN
+ if (lFlags & SDS_NRPN) {
+ for (j = 0; j < sizeof (byCC99); j++) {
+ lCurVal =
+ (MIDIPart_GetRPNMSB (pMIDIPart, byCC99[j], byCC98[j]) << 7) |
+ (MIDIPart_GetRPNLSB (pMIDIPart, byCC99[j], byCC98[j]) & 0x7F);
+ lTempVal =
+ (MIDIPart_GetRPNMSB (pTempPart, byCC99[j], byCC98[j]) << 7) |
+ (MIDIPart_GetRPNLSB (pTempPart, byCC99[j], byCC98[j]) & 0x7F);
+ if (lCurVal != lTempVal) {
+ // CC#101=127(RPN=NULL)(初回のみ)
+ if (byCurBuf[101] != 127) {
+ byCurBuf[101] = 127;
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 101;
+ byMsg[2] = 127;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ // CC#100=127(NRPN=NULL)(初回のみ)
+ if (byCurBuf[100] != 127) {
+ byCurBuf[100] = 127;
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 100;
+ byMsg[2] = 127;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ // CC#99
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 99;
+ byMsg[2] = byCC99[j];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ // CC#98
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 98;
+ byMsg[2] = byCC98[j];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ // CC#6
+ if ((lCurVal >> 7) != (lTempVal >> 7)) {
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 6;
+ byMsg[2] = (BYTE)(lTempVal >> 7);
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ // CC#38
+ if ((lCurVal & 0x7F) != (lTempVal & 0x7F)) {
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = 38;
+ byMsg[2] = (BYTE)(lTempVal & 0x7F);
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ }
+ }
+ }
+ // パッチチェンジ(20111016追加修正)
+ if (lFlags & (SDS_CONTROLCHANGE | SDS_PROGRAMCHANGE)) {
+ MIDIPart_GetControlChangeEx (pMIDIPart, byCurBuf, 128);
+ MIDIPart_GetControlChangeEx (pTempPart, byTempBuf, 128);
+ lCurVal = MIDIPart_GetProgramChange (pMIDIPart);
+ lTempVal = MIDIPart_GetProgramChange (pTempPart);
+ if (byCurBuf[0] != byTempBuf[0] ||
+ byCurBuf[32] != byTempBuf[32] ||
+ lCurVal != lTempVal) {
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = (BYTE)0;
+ byMsg[2] = byTempBuf[0];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ byMsg[0] = 0xB0 + (BYTE)i;
+ byMsg[1] = (BYTE)32;
+ byMsg[2] = byTempBuf[32];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ byMsg[0] = 0xC0 + (BYTE)i;
+ byMsg[1] = (BYTE)lTempVal;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 2);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 2);
+ }
+ }
+ // チャンネルアフタータッチ
+ if (lFlags & SDS_CHANNELAFTER) {
+ lCurVal = MIDIPart_GetChannelAfterTouch (pMIDIPart);
+ lTempVal = MIDIPart_GetChannelAfterTouch (pTempPart);
+ if (lCurVal != lTempVal) {
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0xD0 + (BYTE)i;
+ byMsg[1] = (BYTE)lTempVal;
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 2);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 2);
+ }
+ }
+ // ピッチベンド
+ if (lFlags & SDS_PITCHBEND) {
+ lCurVal = MIDIPart_GetPitchBend (pMIDIPart);
+ lTempVal = MIDIPart_GetPitchBend (pTempPart);
+ if (lCurVal != lTempVal) {
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0xE0 + (BYTE)i;
+ byMsg[1] = (BYTE)(lTempVal & 0x007F);
+ byMsg[2] = (BYTE)(lTempVal >> 7);
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ }
+ // ノート
+ if (lFlags & SDS_NOTE) {
+ MIDIPart_GetNoteKeepEx (pMIDIPart, byCurBuf, 128);
+ MIDIPart_GetNoteKeepEx (pTempPart, byTempBuf, 128);
+ for (j = 0; j < 128; j++) {
+ if (byCurBuf[j] != byTempBuf[j]) {
+ byMsg[0] = 0x90 + (BYTE)i;
+ byMsg[1] = (BYTE)j;
+ byMsg[2] = byTempBuf[j];
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[nPort], byMsg, 3);
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[nPort], byMsg, 3);
+ }
+ }
+ }
+ //TRACE0 ("restored.\n");
+ }
+ }
+}
+
+// MIDI入力デバイスを開く
+void CSekaijuApp::OpenAllMIDIInDevice () {
+ long i;
+ CString strMsg;
+ CString strMsg2;
+ m_theCriticalSection.Lock ();
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ MIDIStatus_Delete (m_pMIDIInStatus[i]);
+ m_pMIDIInStatus[i] = NULL;
+ m_pMIDIIn[i] = MIDIIn_Reopen (m_pMIDIIn[i], m_strMIDIInName[i]);
+ if (m_pMIDIIn[i]) {
+ _RPTF2 (_CRT_WARN, "MIDIInDevice[%d] Open Successful. - \"%s\"\n",
+ i, m_strMIDIInName[i]);
+ m_pMIDIInStatus[i] = MIDIStatus_Create (MIDISTATUS_MODENATIVE, 16, 2);
+ }
+ else {
+ if (m_strMIDIInName[i] != _T("") && m_strMIDIInName[i] != MIDIIO_NONE &&
+ m_strMIDIInName[i] != MIDIIO_NONEJ) {
+ _RPTF2 (_CRT_WARN, "MIDIInDevice[%d] Open Failed. - \"%s\"\n",
+ i, m_strMIDIInName[i]);
+ // "%s\nMIDIInデバイス[%d]が開けません。"
+ strMsg.LoadString (IDS_S_N_MIDIINDEVICE_D_OPEN_FAILED);
+ strMsg2.Format (strMsg, m_strMIDIInName[i], i + 1);
+ m_theCriticalSection.Unlock ();
+ AfxMessageBox (strMsg2, MB_OK | MB_ICONEXCLAMATION);
+ m_theCriticalSection.Lock ();
+ }
+ m_strMIDIInName[i] = _T("");
+ }
+ }
+ m_theCriticalSection.Unlock ();
+}
+
+// MIDI出力デバイスを開く
+void CSekaijuApp::OpenAllMIDIOutDevice () {
+ long i;
+ CString strMsg;
+ CString strMsg2;
+ m_theCriticalSection.Lock ();
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ MIDIStatus_Delete (m_pMIDIOutStatus[i]);
+ m_pMIDIOutStatus[i] = NULL;
+ MIDIStatus_Delete (m_pTempMIDIStatus[i]);
+ m_pTempMIDIStatus[i] = NULL;
+ m_pMIDIOut[i] = MIDIOut_Reopen (m_pMIDIOut[i], m_strMIDIOutName[i]);
+ if (m_pMIDIOut[i]) {
+ _RPTF2 (_CRT_WARN, "MIDIOutDevice[%d] Open Successful. - \"%s\"\n",
+ i, m_strMIDIOutName[i]);
+ m_pMIDIOutStatus[i] = MIDIStatus_Create (MIDISTATUS_MODENATIVE, 16, 2);
+ m_pTempMIDIStatus[i] = MIDIStatus_Create (MIDISTATUS_MODENATIVE, 16, 2);
+ }
+ else {
+ if (m_strMIDIOutName[i] != _T("") && m_strMIDIOutName[i] != MIDIIO_NONE &&
+ m_strMIDIOutName[i] != MIDIIO_NONEJ) {
+ _RPTF2 (_CRT_WARN, "MIDIOutDevice[%d] Open Failed. - \"%s\"\n",
+ i, m_strMIDIOutName[i]);
+ // "%s\nMIDIInデバイス[%d]が開けません。"
+ strMsg.LoadString (IDS_S_N_MIDIOUTDEVICE_D_OPEN_FAILED);
+ strMsg2.Format (strMsg, m_strMIDIOutName[i], i + 1);
+ m_theCriticalSection.Unlock ();
+ AfxMessageBox (strMsg2, MB_OK | MB_ICONEXCLAMATION);
+ m_theCriticalSection.Lock ();
+ }
+ m_strMIDIOutName[i] = _T("");
+ }
+ }
+ m_theCriticalSection.Unlock ();
+}
+
+// 演奏位置指定(絶対ティック指定)
+long CSekaijuApp::SetPlayPosition (CDocument* pDocument, long lTargetTime) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ //CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame ()->GetActiveDocument ());
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)pDocument;
+ if (pSekaijuDoc == NULL) {
+ return 0;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return 0;
+ }
+ long lTempo = MIDIEVENT_DEFTEMPO;
+ long lMillisec = 0;
+ long lEndTime = MIDIData_GetEndTime (pSekaijuDoc->m_pMIDIData);
+ lTargetTime = CLIP (0, lTargetTime, lEndTime);
+ pSekaijuDoc->m_lOldTime = lTargetTime;
+ lMillisec = MIDIData_TimeToMillisec (pSekaijuDoc->m_pMIDIData, lTargetTime);
+ // ソングポジションセレクタ(0xF2)の送出
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pSekaijuDoc->m_pMIDIData, &lTimeMode, &lTimeResolution);
+ long lOutputPort;
+ BYTE byMsg[256];
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0xF2;
+ byMsg[1] = (lTargetTime * 4 / lTimeResolution) & 0x7F;
+ byMsg[2] = ((lTargetTime * 4 / lTimeResolution) >> 7) & 0x7F;
+ for (lOutputPort = 0; lOutputPort < MAXMIDIOUTDEVICENUM; lOutputPort++) {
+ if (m_lMIDIOutSyncMode[lOutputPort] == 1) {
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 3);
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, 3);
+ }
+ }
+ }
+ /* lTargetTime時のテンポをlTempoに取得 */
+ VERIFY (MIDIData_FindTempo (pSekaijuDoc->m_pMIDIData, lTargetTime, &lTempo));
+ /* MIDIステータスをlTargetTime時の状態に合わせる */
+ ResetTempMIDIStatusArray ();
+ pSekaijuDoc->TimeMIDIStatus (lTargetTime, m_pTempMIDIStatus);
+ long lFlags;
+ /* 演奏中ならば(a)すべて又は(b)ノートのみを復元する */
+ if (m_bPlaying) {
+ lFlags = m_theGeneralOption.m_bSearchUpdate ? SDS_ALL : SDS_NOTE;
+ m_bIgnoreNoteEvent = 1;
+ }
+ /* 停止中ならば(a)ノートを除くすべてを復元するか(b)何も復元しない */
+ else {
+ lFlags = m_theGeneralOption.m_bSearchUpdate ? (SDS_ALL & ‾SDS_NOTE) : 0;
+ m_bIgnoreNoteEvent = 0;
+ }
+ SendDifferentStatus (lFlags);
+ /* MIDIクロックの更新 */
+ if (m_bPlaying) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ MIDIClock_Reset (pSekaijuDoc->m_pMIDIClock);
+ MIDIClock_SetTickCount (pSekaijuDoc->m_pMIDIClock, lTargetTime);
+ MIDIClock_SetMillisec (pSekaijuDoc->m_pMIDIClock, lMillisec);
+ MIDIClock_SetTempo (pSekaijuDoc->m_pMIDIClock, lTempo);
+ if (m_bPlaying) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ return 1;
+}
+
+// 演奏の開始
+long CSekaijuApp::StartPlaying (CDocument* pDocument) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)pDocument;
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ long lOutputPort;
+ BYTE byMsg[256];
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = (lCurTime == 0 ? 0xFA : 0xFB);
+ // スタート(0xFA)又はコンティニュー(0xFB)メッセージの送出
+ for (lOutputPort = 0; lOutputPort < MAXMIDIOUTDEVICENUM; lOutputPort++) {
+ if (m_lMIDIOutSyncMode[lOutputPort] >= 1) {
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 1);
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, 1);
+ }
+ }
+ }
+ // 現在の状態を復元する
+ ResetTempMIDIStatusArray ();
+ pSekaijuDoc->TimeMIDIStatus (lCurTime, m_pTempMIDIStatus); // 20090625修正
+ SendDifferentStatus (m_theGeneralOption.m_bPlayUpdate ? SDS_ALL : SDS_NOTE);
+ m_bIgnoreNoteEvent = TRUE; // 20090625修正
+ // 演奏状態にする
+ pSekaijuDoc->m_lOldTime = lCurTime;
+ if (!m_bRecording) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ m_bPlaying = TRUE;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_PLAYSTARTED);
+ return 1;
+}
+
+// 演奏の停止(録音中の場合はStopRecordingを使うこと)
+long CSekaijuApp::StopPlaying (CDocument* pDocument) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)pDocument;
+ long lOutputPort;
+ BYTE byMsg[256];
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0xFC;
+ // ストップメッセージ(0xFC)の送出
+ for (lOutputPort = 0; lOutputPort < MAXMIDIOUTDEVICENUM; lOutputPort++) {
+ if (m_lMIDIOutSyncMode[lOutputPort] >= 1) {
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 1);
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, 1);
+ }
+ }
+ }
+
+ // 演奏・録音の停止
+ m_bRecording = FALSE;
+ m_bPlaying = FALSE;
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ SendAllNoteOff ();
+ SendAllHold1Off ();
+ SendAllSostenutoOff ();
+ SendAllHold2Off ();
+ SendAllSoundOff ();
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_PLAYSTOPED);
+ return 1;
+}
+
+
+// 録音の開始
+long CSekaijuApp::StartRecording (CDocument* pDocument) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)pDocument;
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ // 演奏中でない場合
+ if (!m_bPlaying) {
+ long lOutputPort;
+ BYTE byMsg[256];
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = (lCurTime == 0 ? 0xFA : 0xFB);
+ // スタート(0xFA)又はコンティニュー(0xFB)メッセージの送出
+ for (lOutputPort = 0; lOutputPort < MAXMIDIOUTDEVICENUM; lOutputPort++) {
+ if (m_lMIDIOutSyncMode[lOutputPort] >= 1) {
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 1);
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, 1);
+ }
+ }
+ }
+ // 現在の状態を復元する
+ ResetTempMIDIStatusArray ();
+ pSekaijuDoc->TimeMIDIStatus (lCurTime, m_pTempMIDIStatus); // 20090626修正
+ SendDifferentStatus (m_theGeneralOption.m_bPlayUpdate ? SDS_ALL : SDS_NOTE);
+ m_bIgnoreNoteEvent = TRUE; // 20090626修正
+ pSekaijuDoc->m_lOldTime = lCurTime;
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ m_bPlaying = TRUE;
+ }
+ // 履歴記録
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ pSekaijuDoc->AddHistoryUnit (_T("リアルタイム入力"));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // EOTの履歴記録
+ forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) {
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+ // 記録開始
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ m_theTempRecordedEventArray.RemoveAll ();
+ m_bFirstMetronome = TRUE;
+ m_bRecording = TRUE;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_RECORDSTARTED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ return 1;
+}
+
+// 録音の停止
+long CSekaijuApp::StopRecording (CDocument* pDocument) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)pDocument;
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ long lOutputPort;
+ BYTE byMsg[256];
+ memset (byMsg, 0, sizeof (byMsg));
+ byMsg[0] = 0xFC;
+ // ストップメッセージの送出
+ for (lOutputPort = 0; lOutputPort < MAXMIDIOUTDEVICENUM; lOutputPort++) {
+ if (m_lMIDIOutSyncMode[lOutputPort] >= 1) {
+ if (m_pMIDIOut[lOutputPort]) {
+ MIDIOut_PutMIDIMessage (m_pMIDIOut[lOutputPort], byMsg, 1);
+ }
+ if (m_pMIDIOutStatus[lOutputPort]) {
+ MIDIStatus_PutMIDIMessage (m_pMIDIOutStatus[lOutputPort], byMsg, 1);
+ }
+ }
+ }
+ // 演奏・記録停止
+ m_bRecording = FALSE;
+ m_bPlaying = FALSE;
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ SendAllNoteOff ();
+ SendAllHold1Off ();
+ SendAllHold1Off ();
+ SendAllHold2Off ();
+ SendAllSoundOff ();
+ // 履歴記録
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ long lTempRecordedEventCount = m_theTempRecordedEventArray.GetSize ();
+ long j;
+ // 録音されたすべてのノートイベントの結合確認
+ for (j = 0; j < lTempRecordedEventCount; j++) {
+ pTempEvent = (MIDIEvent*)m_theTempRecordedEventArray.GetAt (j);
+ // ノートオンがないノートオフイベントの場合、ノートオフイベント削除
+ if (MIDIEvent_IsNoteOff (pTempEvent) && pTempEvent->m_pPrevCombinedEvent == NULL) {
+ MIDIEvent_Delete (pTempEvent);
+ pTempEvent = NULL;
+ m_theTempRecordedEventArray.RemoveAt (j);
+ j--;
+ lTempRecordedEventCount = m_theTempRecordedEventArray.GetSize ();
+ }
+ // ノートオフがないノートオンイベントの場合、ノートオンイベント追加
+ else if (MIDIEvent_IsNoteOn (pTempEvent) && pTempEvent->m_pNextCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pTempEvent);
+ long lChannel = MIDIEvent_GetChannel (pTempEvent);
+ long lKey = MIDIEvent_GetKey (pTempEvent);
+ MIDITrack* pTempTrack = MIDIEvent_GetParent (pTempEvent);
+ ASSERT (pTempTrack);
+ MIDIEvent* pNoteOffEvent = NULL;
+ VERIFY (pNoteOffEvent = MIDIEvent_CreateNoteOff (lCurTime, lChannel, lKey, 0));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pNoteOffEvent));
+ //VERIFY (MIDIEvent_Combine (pTempEvent));
+ pTempEvent->m_pNextCombinedEvent = pNoteOffEvent;
+ pNoteOffEvent->m_pPrevCombinedEvent = pTempEvent;
+ m_theTempRecordedEventArray.Add (pNoteOffEvent);
+ lTempRecordedEventCount = m_theTempRecordedEventArray.GetSize ();
+ }
+ }
+
+ // 録音されたすべてのイベントを履歴に記録(結合ノートはノートオンのみ)
+ for (j = 0; j < lTempRecordedEventCount; j++) {
+ pTempEvent = (MIDIEvent*)m_theTempRecordedEventArray.GetAt (j);
+ if (pTempEvent->m_pPrevCombinedEvent == NULL) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent);
+ }
+ }
+ // EOTの履歴記録
+ forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) {
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent);
+ }
+ }
+ }
+ m_theTempRecordedEventArray.RemoveAll ();
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_RECORDSTOPED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ return 1;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// 『ファイル(&F)』-『新規作成(&N)』
+void CSekaijuApp::OnUpdateFileNewUI (CCmdUI* pCmdUI) {
+ //if (m_bRecording) {
+ // pCmdUI->Enable (FALSE);
+ //}
+}
+
+// 『ファイル(&F)』-『開く(&O)』
+void CSekaijuApp::OnUpdateFileOpenUI (CCmdUI* pCmdUI) {
+ //if (m_bRecording) {
+ // pCmdUI->Enable (FALSE);
+ //}
+}
+
+// 『コントロール(&C)』-『最初に戻る(&W)』
+void CSekaijuApp::OnControlToBegin () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+
+ // ドキュメントがない場合
+ if (pSekaijuDoc == NULL) {
+ m_bRecording = FALSE;
+ m_bPlaying = FALSE;
+ return;
+ }
+
+ // ドキュメントがある場合
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ // 記録中の場合
+ if (m_bRecording) {
+ StopRecording (pSekaijuDoc);
+ }
+ // 記録中でない場合
+ else {
+ StopPlaying (pSekaijuDoc);
+ }
+ //MIDIClock_Reset (pSekaijuDoc->m_pMIDIClock); // 20080825移動 // 20090627廃止
+ SetPlayPosition (pSekaijuDoc, 0); // 20090627追加
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED); // 20080922追加
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『最初に戻る(&W)』のUI更新
+void CSekaijuApp::OnUpdateControlToBeginUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->Enable (1);
+ }
+ else {
+ pCmdUI->Enable (0);
+ }
+}
+
+// 『コントロール(&C)』-『最後に進む』
+void CSekaijuApp::OnControlToEnd () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+
+ // ドキュメントがない場合
+ if (pSekaijuDoc == NULL) {
+ m_bRecording = FALSE;
+ m_bPlaying = FALSE;
+ return;
+ }
+
+ // ドキュメントがある場合
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ // 記録中の場合
+ if (m_bRecording) {
+ StopRecording (pSekaijuDoc);
+ }
+ // 記録中でない場合
+ else {
+ StopPlaying (pSekaijuDoc);
+ }
+ long lEndTime = MIDIData_GetEndTime (pSekaijuDoc->m_pMIDIData);
+ SetPlayPosition (pSekaijuDoc, lEndTime);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED); // 20080922追加
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『最後に進む』のUI更新
+void CSekaijuApp::OnUpdateControlToEndUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->Enable (1);
+ }
+ else {
+ pCmdUI->Enable (0);
+ }
+}
+
+
+// 『コントロール(&C)』-『演奏(&P)』
+void CSekaijuApp::OnControlPlay () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc == NULL) {
+ return;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ this->m_theCriticalSection.Lock ();
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ // 停止中の場合
+ if (!m_bPlaying) {
+ StartPlaying (pSekaijuDoc);
+ }
+ // 演奏中の場合
+ else {
+ // 演奏中かつ録音中の場合
+ if (m_bRecording) {
+ StopRecording (pSekaijuDoc);
+ }
+ // 演奏中であるが録音中でない場合
+ else {
+ StopPlaying (pSekaijuDoc);
+ }
+ }
+ this->m_theCriticalSection.Unlock ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『演奏(&P)』のUI更新
+void CSekaijuApp::OnUpdateControlPlayUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->SetCheck (m_bPlaying);
+ pCmdUI->Enable (1);
+ }
+ else {
+ pCmdUI->SetCheck (0);
+ pCmdUI->Enable (0);
+ }
+}
+
+// 『コントロール(&C)』-『録音(&R)』
+void CSekaijuApp::OnControlRecord () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc == NULL) {
+ return;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return;
+ }
+ if (this->m_bInplaceEditing || this->m_bInplaceListing || this->m_bValueUpDowning) {
+ return;
+ }
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ this->m_theCriticalSection.Lock ();
+ // 停止中の場合
+ if (!m_bRecording) {
+ StartRecording (pSekaijuDoc);
+ }
+ // 記録中の場合
+ else {
+ StopRecording (pSekaijuDoc);
+ }
+ this->m_theCriticalSection.Unlock ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『録音(&R)』UI更新
+void CSekaijuApp::OnUpdateControlRecordUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->SetCheck (m_bRecording);
+ if (this->m_bInplaceEditing || this->m_bInplaceListing || this->m_bValueUpDowning) {
+ pCmdUI->Enable (0);
+ }
+ else if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (0);
+ }
+ else {
+ pCmdUI->Enable (1);
+ }
+ }
+ else {
+ pCmdUI->SetCheck (0);
+ pCmdUI->Enable (0);
+ }
+}
+
+
+
+// 『コントロール(&C)』-『前の小節』
+void CSekaijuApp::OnControlPrevMeasure () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc == NULL) {
+ return;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return;
+ }
+ if (m_bRecording) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ this->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ SendAllNoteOff ();
+ SendAllHold1Off ();
+ SendAllSostenutoOff ();
+ SendAllHold2Off ();
+ SendAllSoundOff ();
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ long lTimeMode = 0;
+ long lTimeResolution = 120;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pSekaijuDoc->m_pMIDIData, lCurTime, &lMeasure, &lBeat, &lTick);
+ if (lTick * 2 / lTimeResolution < 1) {
+ MIDIData_MakeTime (pSekaijuDoc->m_pMIDIData, __max (0, lMeasure - 1), 0, 0, &lCurTime);
+ }
+ else {
+ MIDIData_MakeTime (pSekaijuDoc->m_pMIDIData, __max (0, lMeasure), 0, 0, &lCurTime);
+ }
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ else {
+ if (lCurTime % lTimeResolution < lTimeResolution / 2) {
+ lCurTime = (lCurTime - lTimeResolution * 10) / lTimeResolution * lTimeResolution;
+ lCurTime = __max (0, lCurTime);
+ }
+ else {
+ lCurTime = (lCurTime - lTimeResolution * 10) / lTimeResolution * lTimeResolution;
+ lCurTime = __max (0, lCurTime);
+ }
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ this->m_theCriticalSection.Unlock ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『前の小節』のUI更新
+void CSekaijuApp::OnUpdateControlPrevMeasureUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->Enable (1);
+ }
+ else {
+ pCmdUI->Enable (0);
+ }
+}
+
+// 『コントロール(&C)』-『次の小節』
+void CSekaijuApp::OnControlNextMeasure () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc == NULL) {
+ return;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return;
+ }
+ if (m_bRecording) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ this->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ SendAllNoteOff ();
+ SendAllHold1Off ();
+ SendAllSostenutoOff ();
+ SendAllHold2Off ();
+ SendAllSoundOff ();
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ long lTimeMode = 0;
+ long lTimeResolution = 120;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pSekaijuDoc->m_pMIDIData, lCurTime, &lMeasure, &lBeat, &lTick);
+ MIDIData_MakeTime (pSekaijuDoc->m_pMIDIData, __min (65535, lMeasure + 1), 0, 0, &lCurTime);
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ else {
+ lCurTime = (lCurTime + (lTimeResolution * 10)) / lTimeResolution * lTimeResolution;
+ lCurTime = __min (0x7FFFFFFF, lCurTime);
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ this->m_theCriticalSection.Unlock ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『次の小節』のUI更新
+void CSekaijuApp::OnUpdateControlNextMeasureUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->Enable (1);
+ }
+ else {
+ pCmdUI->Enable (0);
+ }
+}
+
+// 『コントロール(&C)』-『前の拍』
+void CSekaijuApp::OnControlPrevBeat () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc == NULL) {
+ return;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return;
+ }
+ if (m_bRecording) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ this->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ SendAllNoteOff ();
+ SendAllHold1Off ();
+ SendAllSostenutoOff ();
+ SendAllHold2Off ();
+ SendAllSoundOff ();
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ long lTimeMode = 0;
+ long lTimeResolution = 120;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pSekaijuDoc->m_pMIDIData, lCurTime, &lMeasure, &lBeat, &lTick);
+ if (lTick * 2 / lTimeResolution < 1) {
+ MIDIData_MakeTime (pSekaijuDoc->m_pMIDIData, __max (lMeasure, 0), lBeat - 1, 0, &lCurTime);
+ }
+ else {
+ MIDIData_MakeTime (pSekaijuDoc->m_pMIDIData, __max (lMeasure, 0), lBeat - 1, 0, &lCurTime);
+ }
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ else {
+ if (lCurTime % lTimeResolution < lTimeResolution / 2) {
+ lCurTime = ((lCurTime - lTimeResolution) / lTimeResolution) * lTimeResolution;
+ lCurTime = __max (0, lCurTime);
+ }
+ else {
+ lCurTime = lCurTime / lTimeResolution * lTimeResolution;
+ lCurTime = __max (0, lCurTime);
+ }
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ this->m_theCriticalSection.Unlock ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『前の拍』のUI更新
+void CSekaijuApp::OnUpdateControlPrevBeatUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->Enable (1);
+ }
+ else {
+ pCmdUI->Enable (0);
+ }
+}
+
+// 『コントロール(&C)』-『次の拍』
+void CSekaijuApp::OnControlNextBeat () {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc == NULL) {
+ return;
+ }
+ if (pSekaijuDoc->m_pMIDIData == NULL || pSekaijuDoc->m_pMIDIClock == NULL) {
+ return;
+ }
+ if (m_bRecording) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ this->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ SendAllNoteOff ();
+ SendAllHold1Off ();
+ SendAllSostenutoOff ();
+ SendAllHold2Off ();
+ SendAllSoundOff ();
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ long lTimeMode = 0;
+ long lTimeResolution = 120;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pSekaijuDoc->m_pMIDIData, lCurTime, &lMeasure, &lBeat, &lTick);
+ MIDIData_MakeTime (pSekaijuDoc->m_pMIDIData, __min (65535, lMeasure), lBeat + 1, 0, &lCurTime);
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ else {
+ lCurTime = ((lCurTime + lTimeResolution) / lTimeResolution) * lTimeResolution;
+ lCurTime = __min (0x7FFFFFFF, lCurTime);
+ SetPlayPosition (pSekaijuDoc, lCurTime);
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ this->m_theCriticalSection.Unlock ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『コントロール(&C)』-『次の拍』のUI更新
+void CSekaijuApp::OnUpdateControlNextBeatUI (CCmdUI* pCmdUI) {
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame()->GetActiveDocument ());
+ if (pSekaijuDoc) {
+ pCmdUI->Enable (1);
+ }
+ else {
+ pCmdUI->Enable (0);
+ }
+}
+
+
+// 『コントロール(&C)』-『スピード=静止』
+void CSekaijuApp::OnControlSpeedNone () {
+ if (m_bRecording) {
+ return;
+ }
+ if (m_lCurSpeedIndex != 0) {
+ m_lOldSpeedIndex = m_lCurSpeedIndex;
+ }
+ m_lCurSpeedIndex = 0;
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ //pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// 『コントロール(&C)』-『スピード=静止』
+void CSekaijuApp::OnUpdateControlSpeedNoneUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurSpeedIndex == 0 ? 1 : 0);
+ pCmdUI->Enable (m_bRecording ? 0 : 1);
+ //CToolBar* pToolBar = (CToolBar*)pCmdUI;
+ //pToolBar->Invalidate (TRUE);
+}
+
+// 『コントロール(&C)』-『スピード=低速』
+void CSekaijuApp::OnControlSpeedSlow () {
+ if (m_lCurSpeedIndex != 1) {
+ m_lOldSpeedIndex = m_lCurSpeedIndex;
+ }
+ m_lCurSpeedIndex = 1;
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ //pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// 『コントロール(&C)』-『スピード=低速』
+void CSekaijuApp::OnUpdateControlSpeedSlowUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurSpeedIndex == 1 ? 1 : 0);
+}
+
+// 『コントロール(&C)』-『スピード=標準』
+void CSekaijuApp::OnControlSpeedNormal () {
+ if (m_lCurSpeedIndex != 2) {
+ m_lOldSpeedIndex = m_lCurSpeedIndex;
+ }
+ m_lCurSpeedIndex = 2;
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ //pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// 『コントロール(&C)』-『スピード=標準』
+void CSekaijuApp::OnUpdateControlSpeedNormalUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurSpeedIndex == 2 ? 1 : 0);
+}
+
+// 『コントロール(&C)』-『スピード=高速』
+void CSekaijuApp::OnControlSpeedFast () {
+ if (m_lCurSpeedIndex != 3) {
+ m_lOldSpeedIndex = m_lCurSpeedIndex;
+ }
+ m_lCurSpeedIndex = 3;
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ //pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// 『コントロール(&C)』-『スピード=高速』
+void CSekaijuApp::OnUpdateControlSpeedFastUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurSpeedIndex == 3 ? 1 : 0);
+}
+
+// 『コントロール(&C)』-『スピード=他機器にスレーブ』
+void CSekaijuApp::OnControlSpeedSlave () {
+ long lSyncInputPort = 0;
+ long lSyncInputMode = 0;
+ GetCurSyncInputPortAndMode (&lSyncInputPort, &lSyncInputMode);
+ // スレーブするものが見つからない場合
+ if (lSyncInputMode == 0) {
+ return;
+ }
+
+ if (m_lCurSpeedIndex != 4) {
+ m_lOldSpeedIndex = m_lCurSpeedIndex;
+ }
+ m_lCurSpeedIndex = 4;
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ //pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// 『コントロール(&C)』-『スピード=他機器にスレーブ』
+void CSekaijuApp::OnUpdateControlSpeedSlaveUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurSpeedIndex == 4 ? 1 : 0);
+}
+
+
+// 『コントロール(&C)』-『オートリピート(&A)』
+void CSekaijuApp::OnControlAutoRepeat () {
+ m_bAutoRepeat = !m_bAutoRepeat;
+}
+
+// 『コントロール(&C)』-『オートリピート(&A)』
+void CSekaijuApp::OnUpdateControlAutoRepeatUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bAutoRepeat);
+}
+
+
+// 『設定(&S)』-『MIDIデバイスとインストゥルメント(&D)...』
+void CSekaijuApp::OnSetupMIDIDevice () {
+ long i;
+ CString strNone;
+ VERIFY (strNone.LoadString (IDS_NONE));
+ CMIDIDeviceSheet theSheet (AfxGetMainWnd ());
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ if (m_strMIDIInName[i] == _T("")) {
+ theSheet.m_theMIDIInDevicePage.m_strMIDIInName[i] = _T("");
+ }
+ else {
+ theSheet.m_theMIDIInDevicePage.m_strMIDIInName[i] = m_strMIDIInName[i];
+ }
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ if (m_strMIDIOutName[i] == _T("")) {
+ theSheet.m_theMIDIOutDevicePage.m_strMIDIOutName[i] = _T("");
+ }
+ else {
+ theSheet.m_theMIDIOutDevicePage.m_strMIDIOutName[i] = m_strMIDIOutName[i];
+ }
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ if (m_strMIDIInstDefNormName[i] == _T("")) {
+ theSheet.m_theMIDIInstDefNormPage.m_strMIDIInstDefNormName[i] = _T("");
+ }
+ else {
+ theSheet.m_theMIDIInstDefNormPage.m_strMIDIInstDefNormName[i] = m_strMIDIInstDefNormName[i];
+ }
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ if (m_strMIDIInstDefDrumName[i] == _T("")) {
+ theSheet.m_theMIDIInstDefDrumPage.m_strMIDIInstDefDrumName[i] = _T("");
+ }
+ else {
+ theSheet.m_theMIDIInstDefDrumPage.m_strMIDIInstDefDrumName[i] = m_strMIDIInstDefDrumName[i];
+ }
+ }
+ if (theSheet.DoModal () == IDOK) {
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ m_strMIDIInName[i] = theSheet.m_theMIDIInDevicePage.m_strMIDIInName[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_strMIDIOutName[i] = theSheet.m_theMIDIOutDevicePage.m_strMIDIOutName[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_strMIDIInstDefNormName[i] = theSheet.m_theMIDIInstDefNormPage.m_strMIDIInstDefNormName[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_strMIDIInstDefDrumName[i] = theSheet.m_theMIDIInstDefDrumPage.m_strMIDIInstDefDrumName[i];
+ }
+ OpenAllMIDIInDevice ();
+ OpenAllMIDIOutDevice ();
+ SelectAllMIDIInstDefNorm ();
+ SelectAllMIDIInstDefDrum ();
+ ((CSekaijuDocTemplate*)m_pSekaijuDocTemplate)->UpdateAllViews
+ (NULL, SEKAIJUDOC_MIDIDATACHANGED | SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ }
+}
+
+// 『設定(&S)』-『MIDI同期モード(&S)...』
+void CSekaijuApp::OnSetupMIDISyncMode () {
+ long i;
+ CMIDISyncModeSheet theSheet (AfxGetMainWnd ());
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ if (0 <= m_lMIDIInSyncMode[i] && m_lMIDIInSyncMode[i] <= 2) {
+ theSheet.m_theMIDIInSyncModePage.m_nMIDIInSyncMode[i] = m_lMIDIInSyncMode[i];
+ }
+ else {
+ theSheet.m_theMIDIInSyncModePage.m_nMIDIInSyncMode[i] = 0;
+ }
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ if (0 <= m_lMIDIOutSyncMode[i] && m_lMIDIOutSyncMode[i] <= 5) {
+ theSheet.m_theMIDIOutSyncModePage.m_nMIDIOutSyncMode[i] = m_lMIDIOutSyncMode[i];
+ }
+ else {
+ theSheet.m_theMIDIOutSyncModePage.m_nMIDIOutSyncMode[i] = 0;
+ }
+ }
+ if (theSheet.DoModal () == IDOK) {
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ m_lMIDIInSyncMode[i] = theSheet.m_theMIDIInSyncModePage.m_nMIDIInSyncMode[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_lMIDIOutSyncMode[i] = theSheet.m_theMIDIOutSyncModePage.m_nMIDIOutSyncMode[i];
+ }
+
+ // スレーブするものが見つからない場合マスター標準速度とする。
+ long lSyncInputPort = 0;
+ long lSyncInputMode = 0;
+ GetCurSyncInputPortAndMode (&lSyncInputPort, &lSyncInputMode);
+ if (lSyncInputMode == 0 && m_lCurSpeedIndex == 4) {
+ m_lCurSpeedIndex = 2;
+ }
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, 0xFFFFFFFF);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+}
+
+
+// MIDIデバイスとインストゥルメントで『適用』を押したとき
+void CSekaijuApp::ApplyMIDIDeviceSheet (CPropertySheet* pSheet) {
+ long i;
+ CMIDIDeviceSheet* pMIDIDeviceSheet = (CMIDIDeviceSheet*)pSheet;
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ m_strMIDIInName[i] = pMIDIDeviceSheet->m_theMIDIInDevicePage.m_strMIDIInName[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_strMIDIOutName[i] = pMIDIDeviceSheet->m_theMIDIOutDevicePage.m_strMIDIOutName[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_strMIDIInstDefNormName[i] = pMIDIDeviceSheet->m_theMIDIInstDefNormPage.m_strMIDIInstDefNormName[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_strMIDIInstDefDrumName[i] = pMIDIDeviceSheet->m_theMIDIInstDefDrumPage.m_strMIDIInstDefDrumName[i];
+ }
+ OpenAllMIDIInDevice ();
+ OpenAllMIDIOutDevice ();
+ SelectAllMIDIInstDefNorm ();
+ SelectAllMIDIInstDefDrum ();
+ ((CSekaijuDocTemplate*)m_pSekaijuDocTemplate)->UpdateAllViews
+ (NULL, SEKAIJUDOC_MIDIDATACHANGED | SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+}
+
+// MIDI同期モードプロパティシートで『適用』を押したとき
+void CSekaijuApp::ApplyMIDISyncModeSheet (CPropertySheet* pSheet) {
+ long i;
+ CMIDISyncModeSheet* pMIDISyncModeSheet = (CMIDISyncModeSheet*)pSheet;
+ for (i = 0; i < MAXMIDIINDEVICENUM; i++) {
+ m_lMIDIInSyncMode[i] = pMIDISyncModeSheet->m_theMIDIInSyncModePage.m_nMIDIInSyncMode[i];
+ }
+ for (i = 0; i < MAXMIDIOUTDEVICENUM; i++) {
+ m_lMIDIOutSyncMode[i] = pMIDISyncModeSheet->m_theMIDIOutSyncModePage.m_nMIDIOutSyncMode[i];
+ }
+
+ // スレーブするものが見つからない場合マスター標準速度とする。
+ long lSyncInputPort = 0;
+ long lSyncInputMode = 0;
+ GetCurSyncInputPortAndMode (&lSyncInputPort, &lSyncInputMode);
+ if (lSyncInputMode == 0 && m_lCurSpeedIndex == 4) {
+ m_lCurSpeedIndex = 2;
+ }
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, 0xFFFFFFFF);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+
+// 『設定(&S)』-『インストゥルメント(&I)...』
+void CSekaijuApp::OnSetupInstrument () {
+
+}
+
+// 『設定(&S)』-『メトロノーム(&M)...』
+void CSekaijuApp::OnSetupMetronome () {
+ CMetronomeDlg theDlg;
+ theDlg.m_nOn = m_theMetronomeDlgStatus.m_nOn;
+ theDlg.m_nOutputPort = CLIP (0, m_theMetronomeDlgStatus.m_nOutputPort, 15);
+ theDlg.m_nOutputChannel = CLIP (0, m_theMetronomeDlgStatus.m_nOutputChannel, 15) + 1;
+ theDlg.m_nNoteKey1 = CLIP (0, m_theMetronomeDlgStatus.m_nNoteKey1, 127);
+ theDlg.m_nNoteVel1 = CLIP (0, m_theMetronomeDlgStatus.m_nNoteVel1, 127);
+ theDlg.m_nNoteKey2 = CLIP (0, m_theMetronomeDlgStatus.m_nNoteKey2, 127);
+ theDlg.m_nNoteVel2 = CLIP (0, m_theMetronomeDlgStatus.m_nNoteVel2, 127);
+ if (theDlg.DoModal () == IDOK) {
+ m_theMetronomeDlgStatus.m_nOn =theDlg.m_nOn;
+ m_theMetronomeDlgStatus.m_nOutputPort = theDlg.m_nOutputPort;
+ m_theMetronomeDlgStatus.m_nOutputChannel = theDlg.m_nOutputChannel - 1;
+ m_theMetronomeDlgStatus.m_nNoteKey1 = theDlg.m_nNoteKey1;
+ m_theMetronomeDlgStatus.m_nNoteVel1 = theDlg.m_nNoteVel1;
+ m_theMetronomeDlgStatus.m_nNoteKey2 = theDlg.m_nNoteKey2;
+ m_theMetronomeDlgStatus.m_nNoteVel2 = theDlg.m_nNoteVel2;
+ }
+}
+
+// 『設定(&S)』-『自動保存(&A)...』
+void CSekaijuApp::OnSetupAutoSave () {
+ CAutoSaveDlg theDlg;
+ theDlg.m_strExeFilePath = m_strExeFilePath;
+ theDlg.m_nOn = m_theAutoSaveDlgStatus.m_nOn;
+ theDlg.m_lInterval = CLIP (1, m_theAutoSaveDlgStatus.m_lInterval / 60, 120);
+ theDlg.m_nDisableWhilePlaying = m_theAutoSaveDlgStatus.m_nDisableWhilePlaying;
+ theDlg.m_nDisableWhileRecording = m_theAutoSaveDlgStatus.m_nDisableWhileRecording;
+ if (theDlg.DoModal () == IDOK) {
+ m_theAutoSaveDlgStatus.m_nOn = theDlg.m_nOn;
+ m_theAutoSaveDlgStatus.m_lInterval =CLIP (1, theDlg.m_lInterval, 120) * 60;
+ m_theAutoSaveDlgStatus.m_nDisableWhilePlaying = theDlg.m_nDisableWhilePlaying;
+ m_theAutoSaveDlgStatus.m_nDisableWhileRecording = theDlg.m_nDisableWhileRecording;
+ }
+}
+
+// 『設定(&S)』-『言語(&L)...』
+void CSekaijuApp::OnSetupLanguage () {
+ CLanguageDlg theDlg;
+ theDlg.m_strLanguage = m_strLanguage;
+ if (theDlg.DoModal () == IDOK) {
+ m_strLanguage = theDlg.m_strLanguage;
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_LANGUAGE_WILL_BE_CHANGED_AT_THE_NEXT_STARTUP));
+ AfxMessageBox (strMsg, MB_ICONINFORMATION);
+ }
+}
+
+
+// 『設定(&S)』-『オプション(&O)...』
+void CSekaijuApp::OnSetupOptions () {
+ long i = 0;
+ COptionSheet theSheet (AfxGetMainWnd ());
+ theSheet.m_theGeneralOptionPage.m_bEnableMultiExec = m_theGeneralOption.m_bEnableMultiExec;
+ theSheet.m_theGeneralOptionPage.m_bEnableMultiOpen = m_theGeneralOption.m_bEnableMultiOpen;
+ theSheet.m_theGeneralOptionPage.m_bRestoreWindowPlacement = m_theGeneralOption.m_bRestoreWindowPlacement;
+ theSheet.m_theGeneralOptionPage.m_bExecOpen = m_theGeneralOption.m_bExecOpen;
+ theSheet.m_theGeneralOptionPage.m_bOpenPlay = m_theGeneralOption.m_bOpenPlay;
+ theSheet.m_theGeneralOptionPage.m_bPlayUpdate = m_theGeneralOption.m_bPlayUpdate;
+ theSheet.m_theGeneralOptionPage.m_bSearchUpdate = m_theGeneralOption.m_bSearchUpdate;
+ theSheet.m_theGeneralOptionPage.m_bEnableCC111Loop = m_theGeneralOption.m_bEnableCC111Loop;
+ theSheet.m_theGeneralOptionPage.m_bPatchSearch = m_theGeneralOption.m_bPatchSearch;
+ theSheet.m_theGeneralOptionPage.m_bInvertCtrlMouseWheel = m_theGeneralOption.m_bInvertCtrlMouseWheel;
+ theSheet.m_theGeneralOptionPage.m_bTrackZeroOrigin = m_theGeneralOption.m_bTrackZeroOrigin;
+ theSheet.m_theGeneralOptionPage.m_bEventZeroOrigin = m_theGeneralOption.m_bEventZeroOrigin;
+ theSheet.m_theGeneralOptionPage.m_bEnableAutoPageUpdate = m_theGeneralOption.m_bEnableAutoPageUpdate;
+ theSheet.m_theGeneralOptionPage.m_bSendNoteOffHoldOffAtEnd = m_theGeneralOption.m_bSendNoteOffHoldOffAtEnd;
+ theSheet.m_theGeneralOptionPage.m_lUpDownDelta1 = CLIP (1, m_theGeneralOption.m_lUpDownDelta1, 16);
+ theSheet.m_theGeneralOptionPage.m_lUpDownDelta2 = CLIP (1, m_theGeneralOption.m_lUpDownDelta2, 16);
+ theSheet.m_theGeneralOptionPage.m_lKeyVelocity1 = CLIP (1, m_theGeneralOption.m_lKeyVelocity1, 127);
+ theSheet.m_theGeneralOptionPage.m_lKeyVelocity2 = CLIP (1, m_theGeneralOption.m_lKeyVelocity2, 127);
+ theSheet.m_theGeneralOptionPage.m_lSpeedSlow = CLIP (1, m_theGeneralOption.m_lSpeedSlow / 100, 1000);
+ theSheet.m_theGeneralOptionPage.m_lSpeedNormal = CLIP (1, m_theGeneralOption.m_lSpeedNormal / 100, 1000);
+ theSheet.m_theGeneralOptionPage.m_lSpeedFast = CLIP (1, m_theGeneralOption.m_lSpeedFast / 100, 1000);
+ theSheet.m_theGeneralOptionPage.m_lPlayRecordInterval = CLIP (1, m_theGeneralOption.m_lPlayRecordInterval, 1000);
+ theSheet.m_theGeneralOptionPage.m_lOctaveSignature = CLIP (3, m_theGeneralOption.m_lOctaveSignature, 5);
+
+ for (i = 0; i < 8; i++) {
+ theSheet.m_theColorOptionPage.m_theForeColorCombo[i].SetCurColor (CLIP (0, m_theColorOption.m_lForeColor[i], 0x00FFFFFF));
+ }
+ for (i = 0; i < 2; i++) {
+ theSheet.m_theColorOptionPage.m_theBackColorCombo[i].SetCurColor (CLIP (0, m_theColorOption.m_lBackColor[i], 0x00FFFFFF));
+ }
+ for (i = 0; i < 2; i++) {
+ theSheet.m_theColorOptionPage.m_theHorzColorCombo[i].SetCurColor (CLIP (0, m_theColorOption.m_lHorzColor[i], 0x00FFFFFF));
+ }
+ for (i = 0; i < 2; i++) {
+ theSheet.m_theColorOptionPage.m_theVertColorCombo[i].SetCurColor (CLIP (0, m_theColorOption.m_lVertColor[i], 0x00FFFFFF));
+ }
+
+ theSheet.m_theTrackListOption1Page.m_lDefRowZoom = CLIP (16, m_theTrackListOption1.m_lDefRowZoom, 64);
+ theSheet.m_theTrackListOption1Page.m_lDefColumnZoom = CLIP (2, m_theTrackListOption1.m_lDefColumnZoom, 16);
+ theSheet.m_theTrackListOption1Page.m_lDefTimeZoom = CLIP (2, m_theTrackListOption1.m_lDefTimeZoom, 16);
+ theSheet.m_theTrackListOption1Page.m_lDefNameWidth = CLIP (1, m_theTrackListOption1.m_lDefNameWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefColorWidth = CLIP (1, m_theTrackListOption1.m_lDefColorWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefInputOnWidth = CLIP (1, m_theTrackListOption1.m_lDefInputOnWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefInputPortWidth = CLIP (1, m_theTrackListOption1.m_lDefInputPortWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefInputChWidth = CLIP (1, m_theTrackListOption1.m_lDefInputChWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefOutputOnWidth = CLIP (1, m_theTrackListOption1.m_lDefOutputOnWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefOutputPortWidth = CLIP (1, m_theTrackListOption1.m_lDefOutputPortWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefOutputChWidth = CLIP (1, m_theTrackListOption1.m_lDefOutputChWidth, 32);
+ theSheet.m_theTrackListOption1Page.m_lDefViewModeWidth = CLIP (1, m_theTrackListOption1.m_lDefViewModeWidth, 32);
+
+ theSheet.m_theTrackListOption2Page.m_lDefCC000Width = CLIP (1, m_theTrackListOption2.m_lDefCC000Width, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefCC032Width = CLIP (1, m_theTrackListOption2.m_lDefCC032Width, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefPCWidth = CLIP (1, m_theTrackListOption2.m_lDefPCWidth, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefCC007Width = CLIP (1, m_theTrackListOption2.m_lDefCC007Width, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefCC010Width = CLIP (1, m_theTrackListOption2.m_lDefCC010Width, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefCC091Width = CLIP (1, m_theTrackListOption2.m_lDefCC091Width, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefCC093Width = CLIP (1, m_theTrackListOption2.m_lDefCC093Width, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefCC094Width = CLIP (1, m_theTrackListOption2.m_lDefCC094Width, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefKeyShiftWidth = CLIP (1, m_theTrackListOption2.m_lDefKeyShiftWidth, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefVelShiftWidth = CLIP (1, m_theTrackListOption2.m_lDefVelShiftWidth, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefTimeShiftWidth = CLIP (1, m_theTrackListOption2.m_lDefTimeShiftWidth, 32);
+ theSheet.m_theTrackListOption2Page.m_lDefNumEventWidth = CLIP (1, m_theTrackListOption2.m_lDefNumEventWidth, 32);
+ theSheet.m_theTrackListOption2Page.m_bEnableRowZoomKey = m_theTrackListOption2.m_bEnableRowZoomKey;
+ theSheet.m_theTrackListOption2Page.m_bEnableColumnZoomKey = m_theTrackListOption2.m_bEnableColumnZoomKey;
+ theSheet.m_theTrackListOption2Page.m_bEnableTimeZoomKey = m_theTrackListOption2.m_bEnableTimeZoomKey;
+
+ theSheet.m_thePianoRollOptionPage.m_lDefKeyZoom = CLIP (4, m_thePianoRollOption.m_lDefKeyZoom, 16);
+ theSheet.m_thePianoRollOptionPage.m_lDefVelZoom = CLIP (1, m_thePianoRollOption.m_lDefVelZoom, 4);
+ theSheet.m_thePianoRollOptionPage.m_lDefTimeZoom = CLIP (1, m_thePianoRollOption.m_lDefTimeZoom, 16);
+ theSheet.m_thePianoRollOptionPage.m_bEnableKeyZoomKey = m_thePianoRollOption.m_bEnableKeyZoomKey;
+ theSheet.m_thePianoRollOptionPage.m_bEnableVelZoomKey = m_thePianoRollOption.m_bEnableVelZoomKey;
+ theSheet.m_thePianoRollOptionPage.m_bEnableTimeZoomKey = m_thePianoRollOption.m_bEnableTimeZoomKey;
+ theSheet.m_thePianoRollOptionPage.m_bSpeakerModeVisibleTrack = m_thePianoRollOption.m_bSpeakerModeVisibleTrack;
+ theSheet.m_thePianoRollOptionPage.m_lGraphLineWidth = CLIP (1, m_thePianoRollOption.m_lGraphLineWidth, 4);
+
+ theSheet.m_theEventListOptionPage.m_lDefRowZoom = CLIP (16, m_theEventListOption.m_lDefRowZoom, 32);
+ theSheet.m_theEventListOptionPage.m_lDefColumnZoom = CLIP (2, m_theEventListOption.m_lDefColumnZoom, 16);
+ theSheet.m_theEventListOptionPage.m_lDefTrackWidth = CLIP (1, m_theEventListOption.m_lDefTrackWidth, 32);
+ theSheet.m_theEventListOptionPage.m_lDefMillisecWidth = CLIP (1, m_theEventListOption.m_lDefMillisecWidth, 32);
+ theSheet.m_theEventListOptionPage.m_lDefTimeWidth = CLIP (1, m_theEventListOption.m_lDefTimeWidth, 32);
+ theSheet.m_theEventListOptionPage.m_lDefKindWidth = CLIP (1, m_theEventListOption.m_lDefKindWidth, 32);
+ theSheet.m_theEventListOptionPage.m_lDefChWidth = CLIP (1, m_theEventListOption.m_lDefChWidth, 32);
+ theSheet.m_theEventListOptionPage.m_lDefVal1Width = CLIP (1, m_theEventListOption.m_lDefVal1Width, 32);
+ theSheet.m_theEventListOptionPage.m_lDefVal2Width = CLIP (1, m_theEventListOption.m_lDefVal2Width, 32);
+ theSheet.m_theEventListOptionPage.m_lDefVal3Width = CLIP (1, m_theEventListOption.m_lDefVal3Width, 32);
+ theSheet.m_theEventListOptionPage.m_bInsertEventAfter = m_theEventListOption.m_bInsertEventAfter;
+ theSheet.m_theEventListOptionPage.m_bDuplicateEventAfter = m_theEventListOption.m_bDuplicateEventAfter;
+ theSheet.m_theEventListOptionPage.m_bDeleteEventAfter = m_theEventListOption.m_bDeleteEventAfter;
+ theSheet.m_theEventListOptionPage.m_bEnableRowZoomKey = m_theEventListOption.m_bEnableRowZoomKey;
+ theSheet.m_theEventListOptionPage.m_bEnableColumnZoomKey = m_theEventListOption.m_bEnableColumnZoomKey;
+
+ theSheet.m_theMusicalScoreOptionPage.m_lDefTrackZoom = CLIP (1, m_theMusicalScoreOption.m_lDefTrackZoom, 8);
+ theSheet.m_theMusicalScoreOptionPage.m_lDefTimeZoom = CLIP (1, m_theMusicalScoreOption.m_lDefTimeZoom, 16);
+ theSheet.m_theMusicalScoreOptionPage.m_bEnableTrackZoomKey = m_theMusicalScoreOption.m_bEnableTrackZoomKey;
+ theSheet.m_theMusicalScoreOptionPage.m_bEnableTimeZoomKey = m_theMusicalScoreOption.m_bEnableTimeZoomKey;
+ theSheet.m_theMusicalScoreOptionPage.m_bSpeakerModeVisibleTrack = m_theMusicalScoreOption.m_bSpeakerModeVisibleTrack;
+
+ if (theSheet.DoModal () == IDOK) {
+ m_theGeneralOption.m_bEnableMultiExec = theSheet.m_theGeneralOptionPage.m_bEnableMultiExec;
+ m_theGeneralOption.m_bEnableMultiOpen = theSheet.m_theGeneralOptionPage.m_bEnableMultiOpen;
+ m_theGeneralOption.m_bRestoreWindowPlacement = theSheet.m_theGeneralOptionPage.m_bRestoreWindowPlacement;
+ m_theGeneralOption.m_bExecOpen = theSheet.m_theGeneralOptionPage.m_bExecOpen;
+ m_theGeneralOption.m_bOpenPlay = theSheet.m_theGeneralOptionPage.m_bOpenPlay;
+ m_theGeneralOption.m_bPlayUpdate = theSheet.m_theGeneralOptionPage.m_bPlayUpdate;
+ m_theGeneralOption.m_bSearchUpdate = theSheet.m_theGeneralOptionPage.m_bSearchUpdate;
+ m_theGeneralOption.m_bEnableCC111Loop = theSheet.m_theGeneralOptionPage.m_bEnableCC111Loop;
+ m_theGeneralOption.m_bPatchSearch = theSheet.m_theGeneralOptionPage.m_bPatchSearch;
+ m_theGeneralOption.m_bInvertCtrlMouseWheel = theSheet.m_theGeneralOptionPage.m_bInvertCtrlMouseWheel;
+ m_theGeneralOption.m_bTrackZeroOrigin = theSheet.m_theGeneralOptionPage.m_bTrackZeroOrigin;
+ m_theGeneralOption.m_bEventZeroOrigin = theSheet.m_theGeneralOptionPage.m_bEventZeroOrigin;
+ m_theGeneralOption.m_bEnableAutoPageUpdate = theSheet.m_theGeneralOptionPage.m_bEnableAutoPageUpdate;
+ m_theGeneralOption.m_bSendNoteOffHoldOffAtEnd = theSheet.m_theGeneralOptionPage.m_bSendNoteOffHoldOffAtEnd;
+
+ for (i = 0; i < 8; i++) {
+ m_theColorOption.m_lForeColor[i] = theSheet.m_theColorOptionPage.m_theForeColorCombo[i].GetCurColor ();
+ }
+ for (i = 0; i < 2; i++) {
+ m_theColorOption.m_lBackColor[i] = theSheet.m_theColorOptionPage.m_theBackColorCombo[i].GetCurColor ();
+ }
+ for (i = 0; i < 2; i++) {
+ m_theColorOption.m_lHorzColor[i] = theSheet.m_theColorOptionPage.m_theHorzColorCombo[i].GetCurColor ();
+ }
+ for (i = 0; i < 2; i++) {
+ m_theColorOption.m_lVertColor[i] = theSheet.m_theColorOptionPage.m_theVertColorCombo[i].GetCurColor ();
+ }
+
+ m_theGeneralOption.m_lUpDownDelta1 = theSheet.m_theGeneralOptionPage.m_lUpDownDelta1;
+ m_theGeneralOption.m_lUpDownDelta2 = theSheet.m_theGeneralOptionPage.m_lUpDownDelta2;
+ m_theGeneralOption.m_lKeyVelocity1 = theSheet.m_theGeneralOptionPage.m_lKeyVelocity1;
+ m_theGeneralOption.m_lKeyVelocity2 = theSheet.m_theGeneralOptionPage.m_lKeyVelocity2;
+ m_theGeneralOption.m_lSpeedSlow = theSheet.m_theGeneralOptionPage.m_lSpeedSlow * 100;
+ m_theGeneralOption.m_lSpeedNormal = theSheet.m_theGeneralOptionPage.m_lSpeedNormal * 100;
+ m_theGeneralOption.m_lSpeedFast = theSheet.m_theGeneralOptionPage.m_lSpeedFast * 100;
+ m_theGeneralOption.m_lPlayRecordInterval = theSheet.m_theGeneralOptionPage.m_lPlayRecordInterval;
+ m_theGeneralOption.m_lOctaveSignature = theSheet.m_theGeneralOptionPage.m_lOctaveSignature;
+
+ m_theTrackListOption1.m_lDefRowZoom = theSheet.m_theTrackListOption1Page.m_lDefRowZoom;
+ m_theTrackListOption1.m_lDefColumnZoom = theSheet.m_theTrackListOption1Page.m_lDefColumnZoom;
+ m_theTrackListOption1.m_lDefTimeZoom = theSheet.m_theTrackListOption1Page.m_lDefTimeZoom;
+ m_theTrackListOption1.m_lDefNameWidth = theSheet.m_theTrackListOption1Page.m_lDefNameWidth;
+ m_theTrackListOption1.m_lDefColorWidth = theSheet.m_theTrackListOption1Page.m_lDefColorWidth;
+ m_theTrackListOption1.m_lDefInputOnWidth = theSheet.m_theTrackListOption1Page.m_lDefInputOnWidth;
+ m_theTrackListOption1.m_lDefInputPortWidth = theSheet.m_theTrackListOption1Page.m_lDefInputPortWidth;
+ m_theTrackListOption1.m_lDefInputChWidth = theSheet.m_theTrackListOption1Page.m_lDefInputChWidth;
+ m_theTrackListOption1.m_lDefOutputOnWidth = theSheet.m_theTrackListOption1Page.m_lDefOutputOnWidth;
+ m_theTrackListOption1.m_lDefOutputPortWidth = theSheet.m_theTrackListOption1Page.m_lDefOutputPortWidth;
+ m_theTrackListOption1.m_lDefOutputChWidth = theSheet.m_theTrackListOption1Page.m_lDefOutputChWidth;
+ m_theTrackListOption1.m_lDefViewModeWidth = theSheet.m_theTrackListOption1Page.m_lDefViewModeWidth;
+
+ m_theTrackListOption2.m_lDefCC000Width = theSheet.m_theTrackListOption2Page.m_lDefCC000Width;
+ m_theTrackListOption2.m_lDefCC032Width = theSheet.m_theTrackListOption2Page.m_lDefCC032Width;
+ m_theTrackListOption2.m_lDefPCWidth = theSheet.m_theTrackListOption2Page.m_lDefPCWidth;
+ m_theTrackListOption2.m_lDefCC007Width = theSheet.m_theTrackListOption2Page.m_lDefCC007Width;
+ m_theTrackListOption2.m_lDefCC010Width = theSheet.m_theTrackListOption2Page.m_lDefCC010Width;
+ m_theTrackListOption2.m_lDefCC091Width = theSheet.m_theTrackListOption2Page.m_lDefCC091Width;
+ m_theTrackListOption2.m_lDefCC093Width = theSheet.m_theTrackListOption2Page.m_lDefCC093Width;
+ m_theTrackListOption2.m_lDefCC094Width = theSheet.m_theTrackListOption2Page.m_lDefCC094Width;
+ m_theTrackListOption2.m_lDefKeyShiftWidth = theSheet.m_theTrackListOption2Page.m_lDefKeyShiftWidth;
+ m_theTrackListOption2.m_lDefVelShiftWidth = theSheet.m_theTrackListOption2Page.m_lDefVelShiftWidth;
+ m_theTrackListOption2.m_lDefTimeShiftWidth = theSheet.m_theTrackListOption2Page.m_lDefTimeShiftWidth;
+ m_theTrackListOption2.m_lDefNumEventWidth= theSheet.m_theTrackListOption2Page.m_lDefNumEventWidth;
+ m_theTrackListOption2.m_bEnableRowZoomKey = theSheet.m_theTrackListOption2Page.m_bEnableRowZoomKey;
+ m_theTrackListOption2.m_bEnableColumnZoomKey = theSheet.m_theTrackListOption2Page.m_bEnableColumnZoomKey;
+ m_theTrackListOption2.m_bEnableTimeZoomKey = theSheet.m_theTrackListOption2Page.m_bEnableTimeZoomKey;
+
+ m_thePianoRollOption.m_lDefKeyZoom = theSheet.m_thePianoRollOptionPage.m_lDefKeyZoom;
+ m_thePianoRollOption.m_lDefVelZoom = theSheet.m_thePianoRollOptionPage.m_lDefVelZoom;
+ m_thePianoRollOption.m_lDefTimeZoom = theSheet.m_thePianoRollOptionPage.m_lDefTimeZoom;
+ m_thePianoRollOption.m_bEnableKeyZoomKey = theSheet.m_thePianoRollOptionPage.m_bEnableKeyZoomKey;
+ m_thePianoRollOption.m_bEnableVelZoomKey = theSheet.m_thePianoRollOptionPage.m_bEnableVelZoomKey;
+ m_thePianoRollOption.m_bEnableTimeZoomKey = theSheet.m_thePianoRollOptionPage.m_bEnableTimeZoomKey;
+ m_thePianoRollOption.m_bSpeakerModeVisibleTrack = theSheet.m_thePianoRollOptionPage.m_bSpeakerModeVisibleTrack;
+ m_thePianoRollOption.m_lGraphLineWidth = theSheet.m_thePianoRollOptionPage.m_lGraphLineWidth;
+
+ m_theEventListOption.m_lDefRowZoom = theSheet.m_theEventListOptionPage.m_lDefRowZoom;
+ m_theEventListOption.m_lDefColumnZoom = theSheet.m_theEventListOptionPage.m_lDefColumnZoom;
+ m_theEventListOption.m_lDefTrackWidth = theSheet.m_theEventListOptionPage.m_lDefTrackWidth;
+ m_theEventListOption.m_lDefMillisecWidth = theSheet.m_theEventListOptionPage.m_lDefMillisecWidth;
+ m_theEventListOption.m_lDefTimeWidth = theSheet.m_theEventListOptionPage.m_lDefTimeWidth;
+ m_theEventListOption.m_lDefKindWidth = theSheet.m_theEventListOptionPage.m_lDefKindWidth;
+ m_theEventListOption.m_lDefChWidth = theSheet.m_theEventListOptionPage.m_lDefChWidth;
+ m_theEventListOption.m_lDefVal1Width = theSheet.m_theEventListOptionPage.m_lDefVal1Width;
+ m_theEventListOption.m_lDefVal2Width = theSheet.m_theEventListOptionPage.m_lDefVal2Width;
+ m_theEventListOption.m_lDefVal3Width = theSheet.m_theEventListOptionPage.m_lDefVal3Width;
+ m_theEventListOption.m_bInsertEventAfter = theSheet.m_theEventListOptionPage.m_bInsertEventAfter;
+ m_theEventListOption.m_bDuplicateEventAfter = theSheet.m_theEventListOptionPage.m_bDuplicateEventAfter;
+ m_theEventListOption.m_bDeleteEventAfter = theSheet.m_theEventListOptionPage.m_bDeleteEventAfter;
+ m_theEventListOption.m_bEnableRowZoomKey = theSheet.m_theEventListOptionPage.m_bEnableRowZoomKey;
+ m_theEventListOption.m_bEnableColumnZoomKey = theSheet.m_theEventListOptionPage.m_bEnableColumnZoomKey;
+
+ m_theMusicalScoreOption.m_lDefTrackZoom = theSheet.m_theMusicalScoreOptionPage.m_lDefTrackZoom;
+ m_theMusicalScoreOption.m_lDefTimeZoom = theSheet.m_theMusicalScoreOptionPage.m_lDefTimeZoom;
+ m_theMusicalScoreOption.m_bEnableTrackZoomKey = theSheet.m_theMusicalScoreOptionPage.m_bEnableTrackZoomKey;
+ m_theMusicalScoreOption.m_bEnableTimeZoomKey = theSheet.m_theMusicalScoreOptionPage.m_bEnableTimeZoomKey;
+ m_theMusicalScoreOption.m_bSpeakerModeVisibleTrack = theSheet.m_theMusicalScoreOptionPage.m_bSpeakerModeVisibleTrack;
+
+ // 開いている全ドキュメントのMIDIクロックのスピードと同期モード再設定
+ POSITION docpos = m_pSekaijuDocTemplate->GetFirstDocPosition ();
+ while (docpos) {
+ CSekaijuDoc* pSekaijuDoc =(CSekaijuDoc*)(m_pSekaijuDocTemplate->GetNextDoc (docpos));
+ long lRunning = MIDIClock_IsRunning (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRunning) {
+ MIDIClock_Stop (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->ApplyAppCurSpeedIndex ();
+ if (lRunning) {
+ MIDIClock_Start (pSekaijuDoc->m_pMIDIClock);
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, 0xFFFFFFFF);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+ // メニューの更新
+ UpdateMenu ();
+ }
+}
+
+// オプションプロパティシートで『適用』を押したとき
+void CSekaijuApp::ApplyOptionSheet (CPropertySheet* pSheet) {
+
+}
+
+// 『ヘルプ(&H)』-『readme(&R)...』
+void CSekaijuApp::OnHelpReadMe () {
+ // ShellExecuteやGetOpenFileNameやGetSaveFileNameは
+ // デバッグ版ではアクセス違反が発生するが、
+ // リリース版では問題ないとの情報あり。
+ CString strMsg;
+ CString strMsg2;
+ CString strFileName1;
+ CString strFileName2;
+ strFileName1.LoadString (IDS_READMEFILENAME);
+ strFileName2 = m_strExeFilePath + strFileName1;
+ long lRet = (long)::ShellExecute (this->m_pMainWnd->GetSafeHwnd (),
+ _T("open"), (LPCTSTR)strFileName2, NULL, NULL, SW_SHOW);
+ if (lRet == 0) {
+ // "メモリ不足又はリソース不足です。"
+ strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_OR_INSUFFICIENT_RESOURCE);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ }
+ else if (1 <= lRet && lRet < 32) {
+ // "%s\n-ファイルが開けません。"
+ strMsg.LoadString (IDS_S_N_FILE_OPEN_FAILED);
+ strMsg2.Format (strMsg, strFileName2);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ }
+}
+
+// 『ヘルプ(&H)』-『ライセンス(&L)...』
+void CSekaijuApp::OnHelpLicense () {
+ CString strMsg;
+ CString strMsg2;
+ CString strFileName1;
+ CString strFileName2;
+ strFileName1.LoadString (IDS_LICENSEFILENAME);
+ strFileName2 = m_strExeFilePath + strFileName1;
+ long lRet = (long)::ShellExecute (this->m_pMainWnd->GetSafeHwnd (),
+ _T("open"), (LPCTSTR)strFileName2, NULL, NULL, SW_SHOW);
+ if (lRet == 0) {
+ // "メモリ不足又はリソース不足です。"
+ strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_OR_INSUFFICIENT_RESOURCE);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ }
+ else if (1 <= lRet && lRet < 32) {
+ // "%s\n-ファイルが開けません。"
+ strMsg.LoadString (IDS_S_N_FILE_OPEN_FAILED);
+ strMsg2.Format (strMsg, strFileName2);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ }
+}
+
+// 『ヘルプ(&H)』-『取扱説明書(PDF)(&M)...』
+void CSekaijuApp::OnHelpManual () {
+ CString strMsg;
+ CString strMsg2;
+ CString strFileName1;
+ CString strFileName2;
+ strFileName1.LoadString (IDS_MANUALFILENAME);
+ strFileName2 = m_strExeFilePath + strFileName1;
+ long lRet = (long)::ShellExecute (this->m_pMainWnd->GetSafeHwnd (),
+ _T("open"), (LPCTSTR)strFileName2, NULL, NULL, SW_SHOW);
+ if (lRet == 0) {
+ // "メモリ不足又はリソース不足です。"
+ strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_OR_INSUFFICIENT_RESOURCE);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ }
+ else if (1 <= lRet && lRet < 32) {
+ // "%s\n-ファイルが開けません。"
+ strMsg.LoadString (IDS_S_N_FILE_OPEN_FAILED);
+ strMsg2.Format (strMsg, strFileName2);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ }
+}
+
+
+// 『ヘルプ(&H)』-『プロジェクトホームページ(&P)...』
+void CSekaijuApp::OnHelpProjectHomePage () {
+ CString strMsg;
+ CString strMsg2;
+ CString strFileName1;
+ strFileName1.LoadString (IDS_HOMEPAGEADDRESS);
+ long lRet = (long)::ShellExecute (this->m_pMainWnd->GetSafeHwnd (),
+ _T("open"), (LPCTSTR)strFileName1, NULL, NULL, SW_SHOW);
+ if (lRet == 0) {
+ // "メモリ不足又はリソース不足です。"
+ strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_OR_INSUFFICIENT_RESOURCE);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ }
+ else if (1 <= lRet && lRet < 32) {
+ // "%s\n-ファイルが開けません。"
+ strMsg.LoadString (IDS_S_N_FILE_OPEN_FAILED);
+ strMsg2.Format (strMsg, strFileName1);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ }
+}
+
+
+// 『ヘルプ(&H)』-『ヴァージョン情報(&A)...』
+void CSekaijuApp::OnHelpAbout () {
+ CAboutDlg theDlg;
+ theDlg.DoModal();
+}
diff --git a/src/SekaijuApp.h b/src/SekaijuApp.h
new file mode 100644
index 0000000..131d04c
--- /dev/null
+++ b/src/SekaijuApp.h
@@ -0,0 +1,600 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹アプリケーションクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _AFXWIN_H_
+#define _AFXWIN_H_
+
+#include <afxmt.h>
+
+#define MAXMIDIINDEVICENUM 16 // 最大MIDI入力デバイス数
+#define MAXMIDIOUTDEVICENUM 16 // 最大MIDI出力デバイス数
+#define MAXMIDITRACKNUM 65536 // 最大MIDIトラック数(1つのMIDIデータに付き)
+#define MAXMIDIINSTRUMENTNUM 256 // 最大MIDIインストゥルメント(*.ins)数
+
+#define WM_COMMANDWAKEUP (WM_USER + 0)
+#define WM_COMMANDREADSHM (WM_USER + 1)
+#define WM_COMMANDFILEOPEN (WM_USER + 2)
+#define SHMSIZE 1024
+
+// 汎用マクロ(最小、最大、挟み込み)
+#ifndef MIN
+#define MIN(A,B) ((A)>(B)?(B):(A)) // AとBの小さいほうを返す
+#endif
+#ifndef MAX
+#define MAX(A,B) ((A)>(B)?(A):(B)) // AとBの大きいほうを返す
+#endif
+#ifndef CLIP
+#define CLIP(A,B,C) ((A)>(B)?(A):((B)>(C)?(C):(B))) //BをAとCの間で丸めた値を返す
+#endif
+
+// TSIZEOFマクロ //20120211追加
+#ifndef TSIZEOF
+#define TSIZEOF(STR) (sizeof(STR)/sizeof(TCHAR))
+#endif
+#ifndef TCSLEN
+#ifdef UNICODE
+#define TCSLEN(STRING) wcslen(STRING)
+#else
+#define TCSLEN(STRING) strlen(STRING)
+#endif
+#endif
+#ifndef TCSNCPY
+#ifdef UNICODE
+#define TCSNCPY(STRING1,STRING2,N) wcsncpy(STRING1,STRING2,N)
+#else
+#define TCSNCPY(STRING1,STRING2,N) strncpy(STRING1,STRING2,N)
+#endif
+#endif
+
+// SendDiffrentStatusのフラグ用
+#define SDS_NOTEOFF 0x0001 // ノートオフの状態を最新状態に復元する
+#define SDS_NOTEON 0x0002 // ノートオンの状態を最新状態に復元する
+#define SDS_NOTE (SDS_NOTEOFF | SDS_NOTEON) // ノートの状態を最新状態に復元する
+#define SDS_KEYAFTER 0x0004 // キーアフタータッチの値をを最新状態に復元する
+#define SDS_CONTROLCHANGE 0x0008 // コントロールチェンジの値を最新状態に復元する
+#define SDS_PROGRAMCHANGE 0x0010 // プログラムチェンジの値を最新状態に復元する
+#define SDS_CHANNELAFTER 0x0020 // チャンネルアフタータッチの値を最新状態に復元する
+#define SDS_PITCHBEND 0x0040 // ピッチベンドの値を最新状態に復元する
+#define SDS_RPN 0x0100 // RPNの値を最新状態に復元する
+#define SDS_NRPN 0x0200 // NRPNの値を最新状態に復元する
+#define SDS_MASTERVOLUME 0x0400 // マスターボリュームの値を最新状態に復元する
+#define SDS_ALL 0xFFFF // すべての値を最新状態に復元する
+
+#include "resource.h" // メイン シンボル
+
+// ウィンドウの配置
+typedef struct {
+ int m_bIconic; // アイコン化されているか?
+ int m_bZoomed; // 最大化されているか?
+ int m_nX; // メインウィンドウ左上のX座標[pixel]
+ int m_nY; // メインウィンドウ左上のY座標[pixel]
+ int m_nWidth; // メインウィンドウの幅[pixel]
+ int m_nHeight; // メインウィンドウの高さ[pixel]
+} WindowPlacement;
+
+// トラックの変更ダイアログ状態
+typedef struct {
+ int m_nAmount; // トラック番号又は変更量
+ int m_nUnit; // 単位(0=絶対指定,1=相対変化)
+ int m_nFitChannel; // 各イベントのチャンネルを出力トラックのチャンネルに合わせる。
+} EditTrackDlgStatus;
+
+// タイムの変更(TPQNベース用)ダイアログ状態
+typedef struct {
+ int m_nAmount; // タイムの変更量
+ int m_nUnit; // 単位(0=小節,1=拍,2=ティック,3=パーセント)
+} EditTimeDlgStatus;
+
+// タイムの変更(SMPTEベース用)ダイアログ状態
+typedef struct {
+ int m_nAmount; // タイムの変更量
+ int m_nUnit; // 単位(0=サブフレーム,1=フレーム,2=パーセント)
+} EditTimeSmpDlgStatus;
+
+// チャンネルの変更ダイアログの状態
+typedef struct {
+ int m_nAmount; // トラック番号又は変更量
+ int m_nUnit; // 単位(0=絶対指定,1=相対変化)
+} EditChannelStatus;
+
+// キーの変更ダイアログの状態
+typedef struct {
+ int m_nAmount; // 音程の変更量
+ int m_nUnit; // 単位(0=半音, 1=オクターブ)
+ int m_nTargetNote; // ノートオン・ノートオフを対象とする(0/1)
+ int m_nTargetKeyAfter; // キーアフタータッチを対象とする(0/1)
+} EditKeyDlgStatus;
+
+// ベロシティの変更ダイアログの状態
+typedef struct {
+ int m_nAmount; // ベロシティの変更量
+ int m_nUnit; // 単位(0=増減,1=パーセント)
+ int m_nTargetNoteOn; // ノートオンを対象にする(0/1)
+ int m_nTargetNoteOff; // ノートオフを対象にする(0/1)
+} EditVelocityDlgStatus;
+
+// 音長さの変更ダイアログの状態
+typedef struct {
+ int m_nAmount; // 音長さの変更量
+ int m_nUnit; // 単位(0=ティック, 1=パーセント)
+} EditDurationDlgStatus;
+
+// 値の変更ダイアログの状態
+typedef struct {
+ int m_nAmount; // 値の変更量
+ int m_nUnit; // 単位(0=増減,1=パーセント)
+ int m_nTargetKeyAfter; // キーアフタータッチを対象とする(0/1)
+ int m_nTargetControlChange; // コントロールチェンジを対象とする(0/1)
+ int m_nTargetChannelAfter; // チャンネルアフタータッチを対象とする(0/1)
+ int m_nTargetPitchBend; // ピッチベンドを対象とする(0/1)
+} EditValueDlgStatus;
+
+// 音符の細分化とトリル化ダイアログの状態
+typedef struct {
+ int m_nDurationIndex; // 細分化後の1音の音長さインデックス(0=4分音符〜)
+ int m_nEnableTrill; // トリルを有効にするか?
+ int m_nKeyShift; // トリル音のキーシフト
+} EditBreakupAndTrillDlgStatus;
+
+// クォンタイズダイアログの状態
+typedef struct {
+ int m_nSnapTimeIndex; // スナップタイムインデックス(0=4分音符〜)
+ int m_nStrength; // 強度[%]
+ int m_nTargetNoteOn; // ターゲットノートオン
+ int m_nTargetNoteOff; // ターゲットノートオフ
+} EditQuantizeDlgStatus;
+
+
+// ビート検出とテンポ自動挿入ダイアログの状態
+typedef struct {
+ int m_nBeatTrackIndex; // ビートが記述されたトラック番号(0〜65535)
+ int m_nBeatIntervalIndex; // ビート間隔(1〜)[tick]
+ int m_nInsertTempo; // テンポを自動挿入するか?
+} EditBeatScanDlgStatus;
+
+// 小節の挿入ダイアログの状態
+typedef struct {
+ int m_nPosition; // 位置
+ int m_nNumMeasure; // 小節数
+} EditInsertMeasureDlgStatus;
+
+// 小節の除去ダイアログの状態
+typedef struct {
+ int m_nPosition; // 位置
+ int m_nNumMeasure; // 小節数
+} EditRemoveMeasureDlgStatus;
+
+// メトロノームダイアログの状態
+typedef struct {
+ int m_nOn; // メトロノームオン
+ int m_nOutputPort; // 出力ポート(0〜15)
+ int m_nOutputChannel; // 出力チャンネル(0〜15)
+ int m_nNoteKey1; // 強打ノートキー(0〜127)
+ int m_nNoteVel1; // 強打ベロシティ(1〜127)
+ int m_nNoteKey2; // 弱打ノートキー(0〜127)
+ int m_nNoteVel2; // 弱打ベロシティ(1〜127)
+} MetronomeDlgStatus;
+
+// 自動保存ダイアログの状態
+typedef struct {
+ int m_nOn; // 自動保存オン
+ long m_lInterval; // 自動保存間隔(1〜7200)[秒]
+ int m_nDisableWhilePlaying; // 演奏中は自動保存しない
+ int m_nDisableWhileRecording; // リアルタイム入力中は自動保存しない
+} AutoSaveDlgStatus;
+
+// オプション(一般)ページの状態
+typedef struct {
+ BOOL m_bEnableMultiExec; // 複数の世界樹を起動することを許可する
+ BOOL m_bEnableMultiOpen; // 複数のMIDIデータを開くことを許可する
+ BOOL m_bRestoreWindowPlacement; // 起動時に前回のウィンドウ位置を復元する
+ BOOL m_bExecOpen; // 起動時に最後に開いたMIDIデータを自動的に開く
+ BOOL m_bOpenPlay; // MIDIデータを開くと自動的に演奏を開始する
+ BOOL m_bPlayUpdate; // 演奏位置移動時にパッチ・コントローラ・ピッチベンド・RPN・NRPNを最新値に更新する
+ BOOL m_bSearchUpdate; // 演奏開始時にパッチ・コントローラ・ピッチベンド・RPN・NRPNを最新値に更新する
+ BOOL m_bSearchSysx; // 演奏開始時にシステムエクスクルーシヴ(マスターヴォリュームなど)を最新値に更新する
+ BOOL m_bEnableCC111Loop; // オートリピート時にCC#111の位置からループ開始する
+ BOOL m_bInvertCtrlMouseWheel; // Ctrl+マウスホイール回転時の演奏位置移動方向を反転にする
+ BOOL m_bTrackZeroOrigin; // トラック番号を0から数える
+ BOOL m_bEventZeroOrigin; // イベント番号を0から数える
+ BOOL m_bPatchSearch; // CC#0・CC#32・プログラムチェンジ操作時に有効な音色だけを検索する
+ BOOL m_bEnableAutoPageUpdate; // 演奏開始時・位置移動時に自動的ページ更新をオンにする
+ BOOL m_bSendNoteOffHoldOffAtEnd; // 曲の終端に達したときノートオフやホールドオフを送信する
+ long m_lUpDownDelta1; // ▲▼の左クリック又は[+][-]キーで増減する量(1〜127)
+ long m_lUpDownDelta2; // ▲▼の右クリック又は[Shift]+[+][-]キーで増減する量(1〜127)
+ long m_lKeyVelocity1; // 鍵盤の左クリック又は[Z]-[\]キーで発音するベロシティ(1〜127)
+ long m_lKeyVelocity2; // 鍵盤の右クリック又は[Shift]+[Z]-[\]キーで発音するベロシティ(1〜127)
+ long m_lSpeedSlow; // スピード=低速で演奏時のテンポ倍率(1〜<5000>〜100000)[*1/100%]
+ long m_lSpeedNormal; // スピード=標準で演奏時のテンポ倍率(1〜<10000>〜100000)[*1/100%]
+ long m_lSpeedFast; // スピード=高速で演奏時のテンポ倍率(1〜<20000>〜100000)[*1/100%]
+ long m_lPlayRecordInterval; // MIDIデータ録音演奏時のwhileループ呼び出し間隔(1〜1000)[ミリ秒]
+ long m_lOctaveSignature; // 中央のド(キー60)のオクターブ番号表記(3〜5)
+} GeneralOption;
+
+// オプション(色)ページの状態
+typedef struct {
+ long m_lForeColor[8]; // 前景色[8](デフォルトトラック色)
+ long m_lBackColor[2]; // 背景色[2]
+ long m_lHorzColor[2]; // 水平線の色[2]
+ long m_lVertColor[2]; // 垂直線の色[2]
+} ColorOption;
+
+// トラックリストオプションページ1の設定
+typedef struct TTrackListOption1 {
+ long m_lDefRowZoom; // デフォルトの行方向拡大倍率[倍]
+ long m_lDefColumnZoom; // デフォルトの列方向拡大倍率[倍]
+ long m_lDefTimeZoom; // デフォルトの時間方向拡大倍率[倍]
+ long m_lDefNameWidth; // デフォルトの名前の幅[pixel]
+ long m_lDefColorWidth; // デフォルトの色の幅[pixel]
+ long m_lDefInputOnWidth; // デフォルトの入力ONの幅[pixel]
+ long m_lDefInputPortWidth; // デフォルトの入力ポートの幅[pixel]
+ long m_lDefInputChWidth; // デフォルトの入力CHの幅[pixel]
+ long m_lDefOutputOnWidth; // デフォルトの出力ONの幅[pixel]
+ long m_lDefOutputPortWidth; // デフォルトの出力ポートの幅[pixel]
+ long m_lDefOutputChWidth; // デフォルトの出力CHの幅[pixel]
+ long m_lDefViewModeWidth; // デフォルトの表示モードの幅[pixel]
+} TrackListOption1;
+
+// トラックリストオプションページ2の設定
+typedef struct TTrackListOption2 {
+ long m_lDefCC000Width; // デフォルトのCC#0の幅[pixel]
+ long m_lDefCC032Width; // デフォルトのCC#32の幅[pixel]
+ long m_lDefPCWidth; // デフォルトのプログラムナンバーの幅[pixel]
+ long m_lDefCC007Width; // デフォルトのボリュームの幅[pixel]
+ long m_lDefCC010Width; // デフォルトのパンの幅[pixel]
+ long m_lDefCC091Width; // デフォルトのリバーブの幅[pixel]
+ long m_lDefCC093Width; // デフォルトのコーラスの幅[pixel]
+ long m_lDefCC094Width; // デフォルトのディレイの幅[pixel]
+ long m_lDefKeyShiftWidth; // デフォルトのキーシフトの幅[pixel]
+ long m_lDefVelShiftWidth; // デフォルトのベロシティシフトの幅[pixel]
+ long m_lDefTimeShiftWidth; // デフォルトのタイムシフトの幅[pixel]
+ long m_lDefNumEventWidth; // デフォルトのイベント数の幅[pixel]
+ BOOL m_bEnableRowZoomKey; // Ctrl+'+''-'キーで行方向ズームするかどうか
+ BOOL m_bEnableColumnZoomKey; // Ctrl+'+''-'キーで列方向ズームするかどうか
+ BOOL m_bEnableTimeZoomKey; // Ctrl+'+''-'キーで時間方向ズームするかどうか
+} TrackListOption2;
+
+// ピアノロールオプションページの設定
+typedef struct {
+ long m_lDefKeyZoom; // デフォルトのキー方向拡大倍率[倍]
+ long m_lDefVelZoom; // デフォルトのベロシティ方向拡大倍率[倍]
+ long m_lDefTimeZoom; // デフォルトの時間方向拡大倍率[倍]
+ BOOL m_bEnableKeyZoomKey; // Ctrl+'+''-'キーでキー方向ズームするかどうか
+ BOOL m_bEnableVelZoomKey; // Ctrl+'+''-'キーでベロシティ方向ズームするかどうか
+ BOOL m_bEnableTimeZoomKey; // Ctrl+'+''-'キーで時間方向トラックズームするかどうか
+ BOOL m_bSpeakerModeVisibleTrack; // 可視状態のトラックを試聴する
+ long m_lGraphLineWidth; // グラフの線幅[pixel]
+} PianoRollOption;
+
+// イベントリストオプションページの設定
+typedef struct {
+ long m_lDefRowZoom; // デフォルトの行方向拡大倍率[倍]
+ long m_lDefColumnZoom; // デフォルトの列方向拡大倍率[倍]
+ long m_lDefTrackWidth; // デフォルトのトラックの幅[pixel]
+ long m_lDefMillisecWidth; // デフォルトのミリ秒の幅[pixel]
+ long m_lDefTimeWidth; // デフォルトのタイムの幅[pixel]
+ long m_lDefKindWidth; // デフォルトのイベントの種類の幅[pixel]
+ long m_lDefChWidth; // デフォルトのチャンネルの幅[pixel]
+ long m_lDefVal1Width; // デフォルトの値1の幅[pixel]
+ long m_lDefVal2Width; // デフォルトの値2の幅[pixel]
+ long m_lDefVal3Width; // デフォルトの値3の幅[pixel]
+ BOOL m_bInsertEventAfter; // 同時刻のイベントの直後に挿入する
+ BOOL m_bDuplicateEventAfter; // 現在のイベントの直後に挿入する
+ BOOL m_bDeleteEventAfter; // 削除したイベントの次のイベントにフォーカスを合わせる
+ BOOL m_bEnableRowZoomKey; // Ctrl+'+''-'キーで行方向ズームするかどうか
+ BOOL m_bEnableColumnZoomKey; // Ctrl+'+''-'キーで列方向ズームするかどうか
+} EventListOption;
+
+// 譜面オプションページの設定
+typedef struct {
+ long m_lDefTrackZoom; // デフォルトのトラック方向拡大倍率[倍]
+ long m_lDefTimeZoom; // デフォルトの時間方向拡大倍率[倍]
+ BOOL m_bEnableTrackZoomKey; // Ctrl+'+''-'キーでトラック方向ズームするかどうか
+ BOOL m_bEnableTimeZoomKey; // Ctrl+'+''-'キーで時間方向ズームするかどうか
+ BOOL m_bSpeakerModeVisibleTrack; // 可視状態のトラックを試聴する
+} MusicalScoreOption;
+
+// プロパティシートの現在のページ
+typedef struct {
+ long m_lMIDIDevice; // MIDIデバイス
+ long m_lOption; // オプション
+} CurrentPage;
+
+
+class CSekaijuApp : public CWinApp {
+
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuApp(); // コンストラクタ
+
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ HINSTANCE m_hResourceDLL;
+public:
+ // ドキュメントテンプレートへのポインタを保持
+ CDocTemplate* m_pSekaijuDocTemplate;
+public:
+ // MIDIデバイスオブジェクトとMIDIステータスオブジェクト
+ MIDIIn* m_pMIDIIn[MAXMIDIINDEVICENUM];
+ MIDIOut* m_pMIDIOut[MAXMIDIOUTDEVICENUM];
+ MIDIStatus* m_pMIDIInStatus[MAXMIDIINDEVICENUM];
+ MIDIStatus* m_pMIDIOutStatus[MAXMIDIOUTDEVICENUM];
+ MIDIStatus* m_pTempMIDIStatus[MAXMIDIOUTDEVICENUM];
+ MIDIInstrument* m_pMIDIInstrument[MAXMIDIINSTRUMENTNUM]; // 20100220修正
+ MIDIInstrumentDefinition* m_pMIDIInstDefNorm[MAXMIDIOUTDEVICENUM];
+ MIDIInstrumentDefinition* m_pMIDIInstDefDrum[MAXMIDIOUTDEVICENUM];
+public:
+ // MIDI入出力などに対するクリティカルセクション
+ CCriticalSection m_theCriticalSection;
+public:
+ // パス名
+ CString m_strExeFilePath; // 実行ファイルのあるパス名
+ CString m_strInitialPath; // iniファイルのあるパス名
+ CString m_strFileOpenPath; // ファイルオープンダイアログのパス名
+ CString m_strSysxOpenPath; // SYSXオープンダイアログのパス名
+
+ // MIDI入出力デバイスの名前
+ CString m_strMIDIInName[MAXMIDIINDEVICENUM];
+ CString m_strMIDIOutName[MAXMIDIOUTDEVICENUM];
+
+ // MIDIインストゥルメント定義の名前
+ CString m_strMIDIInstDefNormName[MAXMIDIOUTDEVICENUM];
+ CString m_strMIDIInstDefDrumName[MAXMIDIOUTDEVICENUM];
+
+ // MIDI同期モード
+ long m_lMIDIInSyncMode[MAXMIDIINDEVICENUM];
+ long m_lMIDIOutSyncMode[MAXMIDIOUTDEVICENUM];
+
+ // コントロール状態
+ BOOL m_bPlaying; // 演奏フラグ (0=停止中,1=演奏中)
+ BOOL m_bRecording; // 録音フラグ (0=停止中,1=録音中)
+ BOOL m_bAutoRepeat; // オートリピート(0=OFF,1=ON)
+ long m_lCurSpeedIndex; // スピード (0=静止,1=低速,2=標準,3=高速,4=他機器にスレーブ)
+ long m_lOldSpeedIndex; // スピード (0=静止,1=低速,2=標準,3=高速,4=他機器にスレーブ)
+
+ // 全般オプション状態
+ GeneralOption m_theGeneralOption;
+
+ // 色オプション状態
+ ColorOption m_theColorOption;
+
+ // トラックリストオプション1状態
+ TrackListOption1 m_theTrackListOption1;
+
+ // トラックリストオプション2状態
+ TrackListOption2 m_theTrackListOption2;
+
+ // ピアノロールオプション状態
+ PianoRollOption m_thePianoRollOption;
+
+ // イベントリストオプション状態
+ EventListOption m_theEventListOption;
+
+ // 譜面オプション状態
+ MusicalScoreOption m_theMusicalScoreOption;
+
+ // プロパティシートの現在のページ
+ CurrentPage m_theCurrentPage;
+
+ // ウィンドウ配置状態
+ WindowPlacement m_theWindowPlacement;
+
+ // EditTrackダイアログ状態
+ EditTrackDlgStatus m_theEditTrackDlgStatus;
+
+ // EditTimeダイアログ状態
+ EditTimeDlgStatus m_theEditTimeDlgStatus;
+
+ // EditTimeSmpダイアログ状態
+ EditTimeSmpDlgStatus m_theEditTimeSmpDlgStatus;
+
+ // EditChannelダイアログ状態
+ EditChannelStatus m_theEditChannelDlgStatus;
+
+ // EditKeyダイアログ状態
+ EditKeyDlgStatus m_theEditKeyDlgStatus;
+
+ // EditVelocityダイアログ状態
+ EditVelocityDlgStatus m_theEditVelocityDlgStatus;
+
+ // EditDurationダイアログ状態
+ EditDurationDlgStatus m_theEditDurationDlgStatus;
+
+ // EditValueダイアログ状態
+ EditValueDlgStatus m_theEditValueDlgStatus;
+
+ // EditBreakupAndTrillダイアログ状態
+ EditBreakupAndTrillDlgStatus m_theEditBreakupAndTrillDlgStatus;
+
+ // EditQuantizeダイアログ状態
+ EditQuantizeDlgStatus m_theEditQuantizeDlgStatus;
+
+ // EditBeatScanダイアログ状態
+ EditBeatScanDlgStatus m_theEditBeatScanDlgStatus;
+
+ // EditInsertMeasureダイアログ状態
+ EditInsertMeasureDlgStatus m_theEditInsertMeasureDlgStatus;
+
+ // EditRemoveMeasureダイアログ状態
+ EditRemoveMeasureDlgStatus m_theEditRemoveMeasureDlgStatus;
+
+ // Metronomeダイアログ状態
+ MetronomeDlgStatus m_theMetronomeDlgStatus;
+
+ // 自動保存ダイアログ状態
+ AutoSaveDlgStatus m_theAutoSaveDlgStatus;
+
+ // 最後に開いたファイル名
+ CString m_strLastOpenFileName[16];
+
+ // 言語
+ CString m_strLanguage;
+
+ // デフォルトフォント
+ CFont m_theDefaultFont;
+
+ // カーソル
+ HCURSOR m_hCursorArrow;
+ HCURSOR m_hCursorCross;
+ HCURSOR m_hCursorSizeWE;
+ HCURSOR m_hCursorSizeNS;
+ HCURSOR m_hCursorSizeAll;
+ HCURSOR m_hCursorSizeAllCopy;
+ HCURSOR m_hCursorNo;
+ HCURSOR m_hCursorResizeWE;
+ HCURSOR m_hCursorResizeNS;
+ HCURSOR m_hCursorResizeAll;
+ HCURSOR m_hCursorDraw;
+ HCURSOR m_hCursorLine;
+ HCURSOR m_hCursorEraser;
+ HCURSOR m_hCursorSelect;
+ HCURSOR m_hCursorSelectAdd;
+ HCURSOR m_hCursorSelect2;
+ HCURSOR m_hCursorSelectAdd2;
+ HCURSOR m_hCursorSpeaker;
+
+ // イベントの種類名
+ CString m_strEventKindName[256];
+
+ // ノートキー名
+ CString m_strNoteKeyName[256];
+
+ // 一時的な変数
+ BOOL m_bIgnoreNoteEvent;
+ BOOL m_bFirstMetronome;
+ CPtrArray m_theTempRecordedEventArray;
+ BOOL m_bInplaceEditing;
+ BOOL m_bInplaceListing;
+ BOOL m_bValueUpDowning;
+
+ // 現在の子ウィンドウと現在のドキュメント
+ CMDIChildWnd* m_pCurChildWnd;
+ CDocument* m_pCurDocument;
+ CMDIChildWnd* m_pOldChildWnd;
+ CDocument* m_pOldDocument;
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL InitInstance ();
+ virtual int ExitInstance ();
+ virtual void AddDocTemplate (CDocTemplate* pTemplate);
+ virtual BOOL PreTranslateMessage (MSG* pMsg);
+ virtual BOOL OnIdle (LONG lCount);
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual BOOL LoadResourceDLL ();
+ virtual BOOL FreeResourceDLL ();
+ virtual BOOL CheckMultiExec (CCommandLineInfo* pCmdInfo);
+ virtual BOOL LoadIniFile ();
+ virtual BOOL SaveIniFile ();
+ virtual void UpdateMenu ();
+ virtual void UpdateCurWndAndDocPtr ();
+ virtual void ResetMIDIStatusArray ();
+ virtual void ResetTempMIDIStatusArray ();
+ virtual void SendAllHold1Off ();
+ virtual void SendAllSostenutoOff ();
+ virtual void SendAllHold2Off ();
+ virtual void SendAllSoundOff ();
+ virtual void SendResetAllController ();
+ virtual void SendAllNoteOff ();
+ virtual void SendDifferentStatus (long lFlags);
+ virtual void OpenAllMIDIInDevice ();
+ virtual void OpenAllMIDIOutDevice ();
+ virtual long LoadAllMIDIInstrument ();
+ virtual long SelectAllMIDIInstDefNorm ();
+ virtual long SelectAllMIDIInstDefDrum ();
+ virtual long SetPlayPosition (CDocument* pDocument, long lTargetTime);
+ virtual long StartPlaying (CDocument* pDocument);
+ virtual long StopPlaying (CDocument* pDocument);
+ virtual long StartRecording (CDocument* pDocument);
+ virtual long StopRecording (CDocument* pDocument);
+ virtual void ApplyMIDIDeviceSheet (CPropertySheet* pSheet);
+ virtual void ApplyMIDISyncModeSheet (CPropertySheet* pSheet);
+ virtual void ApplyOptionSheet (CPropertySheet* pSheet);
+ virtual BOOL GetCurSyncInputPortAndMode (long* pPort, long* pMode);
+
+public:
+ // 演奏・録音用スレッド関連
+ static UINT PlayRecordThread (LPVOID pInfo);
+ virtual BOOL PlayRecordProc (LPVOID pInfo);
+ CWinThread* m_pPlayRecordThread;
+ BOOL m_bPlayRecordThreadRunning;
+
+ //--------------------------------------------------------------------------
+ // インプリメンテーション
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnUpdateFileNewUI (CCmdUI* pCmdUI);
+ afx_msg void OnUpdateFileOpenUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlToBegin ();
+ afx_msg void OnUpdateControlToBeginUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlToEnd ();
+ afx_msg void OnUpdateControlToEndUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlPlay ();
+ afx_msg void OnUpdateControlPlayUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlRecord ();
+ afx_msg void OnUpdateControlRecordUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlPrevMeasure ();
+ afx_msg void OnUpdateControlPrevMeasureUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlNextMeasure ();
+ afx_msg void OnUpdateControlNextMeasureUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlPrevBeat ();
+ afx_msg void OnUpdateControlPrevBeatUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlNextBeat ();
+ afx_msg void OnUpdateControlNextBeatUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlSpeedNone ();
+ afx_msg void OnUpdateControlSpeedNoneUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlSpeedSlow ();
+ afx_msg void OnUpdateControlSpeedSlowUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlSpeedNormal ();
+ afx_msg void OnUpdateControlSpeedNormalUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlSpeedFast ();
+ afx_msg void OnUpdateControlSpeedFastUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlSpeedSlave ();
+ afx_msg void OnUpdateControlSpeedSlaveUI (CCmdUI* pCmdUI);
+ afx_msg void OnControlAutoRepeat ();
+ afx_msg void OnUpdateControlAutoRepeatUI (CCmdUI* pCmdUI);
+ afx_msg void OnSetupMIDIDevice ();
+ afx_msg void OnSetupMIDISyncMode ();
+ afx_msg void OnSetupInstrument ();
+ afx_msg void OnSetupMetronome ();
+ afx_msg void OnSetupAutoSave ();
+ afx_msg void OnSetupLanguage ();
+ afx_msg void OnSetupOptions ();
+ afx_msg void OnHelpReadMe ();
+ afx_msg void OnHelpLicense ();
+ afx_msg void OnHelpManual ();
+ afx_msg void OnHelpProjectHomePage ();
+ afx_msg void OnHelpAbout ();
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif
diff --git a/src/SekaijuDoc.cpp b/src/SekaijuDoc.cpp
new file mode 100644
index 0000000..270bd17
--- /dev/null
+++ b/src/SekaijuDoc.cpp
@@ -0,0 +1,8999 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ドキュメントクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "common.h"
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDocTemplate.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "FilePropertyDlg.h"
+#include "EditTrackDlg.h"
+#include "EditTimeDlg.h"
+#include "EditTimeSmpDlg.h"
+#include "EditChannelDlg.h"
+#include "EditKeyDlg.h"
+#include "EditVelocityDlg.h"
+#include "EditDurationDlg.h"
+#include "EditValueDlg.h"
+#include "EditBreakupAndTrillDlg.h"
+#include "EditQuantizeDlg.h"
+#include "EditBeatScanDlg.h"
+#include "EditInsertMeasureDlg.h"
+#include "EditRemoveMeasureDlg.h"
+#include "PropertyTempoDlg.h"
+#include "PropertyTimeSignatureDlg.h"
+#include "PropertyKeySignatureDlg.h"
+#include "PropertyMarkerDlg.h"
+
+
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+
+#include "TrackListFrame.h"
+#include "PianoRollFrame.h"
+#include "EventListFrame.h"
+#include "MusicalScoreFrame.h"
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CSekaijuDoc, CDocument)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CSekaijuDoc, CDocument)
+ ON_UPDATE_COMMAND_UI (ID_FILE_SAVE, OnUpdateFileSaveUI)
+ ON_UPDATE_COMMAND_UI (ID_FILE_SAVE_AS,OnUpdateFileSaveAsUI)
+ ON_COMMAND (ID_FILE_PROPERTY, OnFileProperty)
+ ON_UPDATE_COMMAND_UI (ID_FILE_PROPERTY,OnUpdateFilePropertyUI)
+ ON_COMMAND (ID_EDIT_UNDO, OnEditUndo)
+
+ ON_UPDATE_COMMAND_UI (ID_EDIT_UNDO, OnUpdateEditUndoUI)
+ ON_COMMAND (ID_EDIT_REDO, OnEditRedo)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_REDO, OnUpdateEditRedoUI)
+ ON_COMMAND (ID_EDIT_INITHISTORY, OnEditInitHistory)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_INITHISTORY, OnUpdateEditInitHistoryUI)
+ ON_COMMAND (ID_EDIT_CUT, OnEditCut)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_CUT, OnUpdateEditCutUI)
+ ON_COMMAND (ID_EDIT_COPY, OnEditCopy)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_COPY, OnUpdateEditCopyUI)
+ ON_COMMAND (ID_EDIT_PASTE, OnEditPaste)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_PASTE, OnUpdateEditPasteUI)
+ ON_COMMAND (ID_EDIT_DELETE, OnEditDelete)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_DELETE, OnUpdateEditDeleteUI)
+ ON_COMMAND (ID_EDIT_SELECTALL, OnEditSelectAll)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_SELECTALL, OnUpdateEditSelectAllUI)
+ ON_COMMAND (ID_EDIT_SELECTNONE,OnEditSelectNone)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_SELECTNONE, OnUpdateEditSelectNoneUI)
+ ON_COMMAND (ID_EDIT_SELECTBEFORE,OnEditSelectBefore)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_SELECTBEFORE, OnUpdateEditSelectBeforeUI)
+ ON_COMMAND (ID_EDIT_DESELECTBEFORE,OnEditDeselectBefore)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_DESELECTBEFORE, OnUpdateEditDeselectBeforeUI)
+ ON_COMMAND (ID_EDIT_SELECTAFTER,OnEditSelectAfter)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_SELECTAFTER, OnUpdateEditSelectAfterUI)
+ ON_COMMAND (ID_EDIT_DESELECTAFTER,OnEditDeselectAfter)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_DESELECTAFTER, OnUpdateEditDeselectAfterUI)
+
+ ON_COMMAND (ID_EDIT_TRACK, OnEditTrack)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_TRACK, OnUpdateEditTrackUI)
+ ON_COMMAND (ID_EDIT_TIME, OnEditTime)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_TIME, OnUpdateEditTimeUI)
+ ON_COMMAND (ID_EDIT_CHANNEL, OnEditChannel)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_CHANNEL, OnUpdateEditChannelUI)
+ ON_COMMAND (ID_EDIT_KEY, OnEditKey)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_KEY, OnUpdateEditKeyUI)
+ ON_COMMAND (ID_EDIT_VELOCITY, OnEditVelocity)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_VELOCITY, OnUpdateEditVelocityUI)
+ ON_COMMAND (ID_EDIT_DURATION, OnEditDuration)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_DURATION, OnUpdateEditDurationUI)
+ ON_COMMAND (ID_EDIT_VALUE, OnEditValue)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_VALUE, OnUpdateEditValueUI)
+ ON_COMMAND (ID_EDIT_QUANTIZE, OnEditQuantize)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_QUANTIZE, OnUpdateEditQuantizeUI)
+ ON_COMMAND (ID_EDIT_BREAKUPANDTRILL, OnEditBreakupAndTrill)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_BREAKUPANDTRILL, OnUpdateEditBreakupAndTrillUI)
+ ON_COMMAND (ID_EDIT_BEATSCAN, OnEditBeatScan)
+ ON_UPDATE_COMMAND_UI (ID_EDIT_BEATSCAN, OnUpdateEditBeatScanUI)
+
+ ON_COMMAND (ID_EDIT_INSERTMEASURE, OnEditInsertMeasure) // 20100728追加
+ ON_UPDATE_COMMAND_UI (ID_EDIT_INSERTMEASURE, OnUpdateEditInsertMeasureUI) // 20100728追加
+ ON_COMMAND (ID_EDIT_REMOVEMEASURE, OnEditRemoveMeasure) // 20100728追加
+ ON_UPDATE_COMMAND_UI (ID_EDIT_REMOVEMEASURE, OnUpdateEditRemoveMeasureUI) // 20100728追加
+
+ ON_COMMAND (ID_VIEW_REDRAW, OnViewRedraw)
+ ON_COMMAND (ID_VIEW_TRACKLIST, OnViewTrackList)
+ ON_COMMAND (ID_VIEW_PIANOROLL, OnViewPianoRoll)
+ ON_COMMAND (ID_VIEW_EVENTLIST, OnViewEventList)
+ ON_COMMAND (ID_VIEW_MUSICALSCORE, OnViewMusicalScore) // 20090629使用不可状態に設定(仮)
+
+ ON_COMMAND (ID_POPUP_SHOWTRACKLIST, OnPopupShowTrackList)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_SHOWTRACKLIST, OnUpdatePopupShowTrackListUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_SHOWPIANOROLL, OnPopupShowPianoRoll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_SHOWPIANOROLL, OnUpdatePopupShowPianoRollUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_SHOWEVENTLIST, OnPopupShowEventList)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_SHOWEVENTLIST, OnUpdatePopupShowEventListUI) // 20100429追加
+ ON_COMMAND (ID_POPUP_SHOWMUSICALSCORE, OnPopupShowMusicalScore) // 20090629使用不可状態に設定(仮)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_SHOWMUSICALSCORE, OnUpdatePopupShowMusicalScoreUI) // 20100429追加 // 20110104修正
+
+ ON_COMMAND (ID_POPUP_TRACKINPUTON, OnPopupTrackInputOn)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKINPUTON, OnUpdatePopupTrackInputOnUI)
+ ON_COMMAND (ID_POPUP_TRACKINPUTOFF, OnPopupTrackInputOff)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKINPUTOFF, OnUpdatePopupTrackInputOffUI)
+ ON_COMMAND (ID_POPUP_TRACKINPUTALL, OnPopupTrackInputAll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKINPUTALL, OnUpdatePopupTrackInputAllUI)
+ ON_COMMAND (ID_POPUP_TRACKOUTPUTON, OnPopupTrackOutputOn)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKOUTPUTON, OnUpdatePopupTrackOutputOnUI)
+ ON_COMMAND (ID_POPUP_TRACKOUTPUTOFF, OnPopupTrackOutputOff)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKOUTPUTOFF, OnUpdatePopupTrackOutputOffUI)
+ ON_COMMAND (ID_POPUP_TRACKOUTPUTALL, OnPopupTrackOutputAll)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_TRACKOUTPUTALL, OnUpdatePopupTrackOutputAllUI)
+
+ ON_COMMAND (ID_POPUP_CUT, OnPopupCut)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_CUT, OnUpdatePopupCutUI)
+ ON_COMMAND (ID_POPUP_COPY, OnPopupCopy)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_COPY, OnUpdatePopupCopyUI)
+ ON_COMMAND (ID_POPUP_PASTE, OnPopupPaste)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_PASTE, OnUpdatePopupPasteUI)
+
+ ON_COMMAND (ID_POPUP_INSERTTEMPO, OnPopupInsertTempo)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_INSERTTEMPO, OnUpdatePopupInsertTempoUI)
+ ON_COMMAND (ID_POPUP_INSERTTIMESIGNATURE, OnPopupInsertTimeSignature)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_INSERTTIMESIGNATURE, OnUpdatePopupInsertTimeSignatureUI)
+ ON_COMMAND (ID_POPUP_INSERTKEYSIGNATURE, OnPopupInsertKeySignature)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_INSERTKEYSIGNATURE, OnUpdatePopupInsertKeySignatureUI)
+ ON_COMMAND (ID_POPUP_INSERTMARKER, OnPopupInsertMarker)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_INSERTMARKER, OnUpdatePopupInsertMarkerUI)
+
+ ON_COMMAND (ID_POPUP_MODIFYTEMPO, OnPopupModifyTempo)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_MODIFYTEMPO, OnUpdatePopupModifyTempoUI)
+ ON_COMMAND (ID_POPUP_MODIFYTIMESIGNATURE, OnPopupModifyTimeSignature)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_MODIFYTIMESIGNATURE, OnUpdatePopupModifyTimeSignatureUI)
+ ON_COMMAND (ID_POPUP_MODIFYKEYSIGNATURE, OnPopupModifyKeySignature)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_MODIFYKEYSIGNATURE, OnUpdatePopupModifyKeySignatureUI)
+ ON_COMMAND (ID_POPUP_MODIFYMARKER, OnPopupModifyMarker)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_MODIFYMARKER, OnUpdatePopupModifyMarkerUI)
+
+ ON_COMMAND (ID_POPUP_DELETETEMPO, OnPopupDeleteTempo)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_DELETETEMPO, OnUpdatePopupDeleteTempoUI)
+ ON_COMMAND (ID_POPUP_DELETETIMESIGNATURE, OnPopupDeleteTimeSignature)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_DELETETIMESIGNATURE, OnUpdatePopupDeleteTimeSignatureUI)
+ ON_COMMAND (ID_POPUP_DELETEKEYSIGNATURE, OnPopupDeleteKeySignature)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_DELETEKEYSIGNATURE, OnUpdatePopupDeleteKeySignatureUI)
+ ON_COMMAND (ID_POPUP_DELETEMARKER, OnPopupDeleteMarker)
+ ON_UPDATE_COMMAND_UI (ID_POPUP_DELETEMARKER, OnUpdatePopupDeleteMarkerUI)
+
+
+END_MESSAGE_MAP ()
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CSekaijuDoc::CSekaijuDoc () {
+ m_pMIDIClock = NULL;
+ m_pMIDIData = NULL;
+ m_lOldTime = 0L;
+ m_lNewTime = 0L;
+ m_bEditLocked = FALSE;
+ m_bSaveLocked = FALSE;
+ m_lCurHistoryPosition = 0L;
+ m_tmFileOpenTime = 0L;
+ m_tmLastAutoSaveTime = 0L;
+ m_lTempTime = 0;
+ m_pTempTrack = NULL;
+ m_pTempEvent = NULL;
+ m_pTempTempoEvent = NULL;
+ m_pTempTimeSignatureEvent = NULL;
+ m_pTempMarkerEvent = NULL;
+ m_pTempKeySignatureEvent = NULL;
+}
+
+// デストラクタ
+CSekaijuDoc::~CSekaijuDoc() {
+ // クリティカルセクションのロック
+ m_theCriticalSection.Lock ();
+ // 履歴の削除
+ DeleteAllHistoryUnit ();
+ // MIDIデータの削除
+ if (m_pMIDIData) {
+ MIDIData_Delete (m_pMIDIData);
+ }
+ m_pMIDIData = NULL;
+ // MIDIクロックの削除
+ if (m_pMIDIClock) {
+ MIDIClock_Stop (m_pMIDIClock);
+ MIDIClock_Delete (m_pMIDIClock);
+ }
+ m_pMIDIClock = NULL;
+ // アプリケーションに旧ドキュメントが消滅したことを伝える。
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ pSekaijuApp->m_pOldDocument = NULL;
+ // クリティカルセクションの解除
+ m_theCriticalSection.Unlock ();
+ // ビューの更新
+ UpdateAllViews (NULL);
+}
+
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ドキュメントを新規作成するときのオーバーライド
+BOOL CSekaijuDoc::OnNewDocument () {
+ if (!CDocument::OnNewDocument()) {
+ return FALSE;
+ }
+ // OnNewDocumentがFALSEを返したときの反応テスト
+ // TODO:FALSEを返したときでも正常に動作するようにせよ。
+ // return FALSE;
+
+ BeginWaitCursor ();
+ CString strMsg;
+ // クリティカルセクションのロック
+ m_theCriticalSection.Lock ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 既存MIDIデータの削除
+ if (m_pMIDIData != NULL) {
+ MIDIData_Delete (m_pMIDIData);
+ m_pMIDIData = NULL;
+ }
+ // 既存MIDIクロックの削除
+ if (m_pMIDIClock != NULL) {
+ MIDIClock_Delete (m_pMIDIClock);
+ m_pMIDIClock = NULL;
+ }
+ // 新規MIDIデータの作成
+ m_pMIDIData = MIDIData_Create (MIDIDATA_FORMAT1, 17, MIDIDATA_TPQNBASE, 120);
+ if (m_pMIDIData == NULL) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ VERIFY (strMsg.LoadString (IDS_MIDIDATA_CREATE_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ // 各トラックのデフォルトの属性設定
+ long i = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ m_pMIDIData->m_lUser1 = m_lOldTime;
+ m_pMIDIData->m_lUser2 = MIDIData_GetFormat (m_pMIDIData) == 1 ? 1 : 0;
+ m_pMIDIData->m_lUser3 = 0;
+ m_pMIDIData->m_lUserFlag = MIDIDATA_VISIBLE | MIDITRACK_ENABLE;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDITrack_SetInputOn (pMIDITrack, 1);
+ MIDITrack_SetInputPort (pMIDITrack, 0);
+ MIDITrack_SetInputChannel (pMIDITrack, i == 0 ? - 1 : ((i + 15) % 16));
+ MIDITrack_SetOutputOn (pMIDITrack, 1);
+ MIDITrack_SetOutputPort (pMIDITrack, 0);
+ MIDITrack_SetOutputChannel (pMIDITrack, i == 0 ? -1 : ((i + 15) % 16));
+ MIDITrack_SetViewMode (pMIDITrack, (i == 10 ? 1 : 0));
+ MIDITrack_SetForeColor (pMIDITrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]);
+ MIDITrack_SetBackColor (pMIDITrack, 0x00FFFFFF);
+ pMIDITrack->m_lUser1 = 0;
+ pMIDITrack->m_lUser2 = 0;
+ pMIDITrack->m_lUser3 = 0;
+ pMIDITrack->m_lUserFlag = MIDITRACK_VISIBLE | MIDITRACK_ENABLE;
+ this->AddDefaultEventToTrack (pMIDITrack, i == 0 ? 0x000B : 0x0007, NULL);
+ i++;
+ }
+
+ // フラグの初期化
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASINSERTED;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASREMOVED;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASINSERTED;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASREMOVED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASINSERTED;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASREMOVED;
+ }
+ }
+
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+ // MIDIクロックの生成
+ m_pMIDIClock = MIDIClock_Create (MIDICLOCK_MASTERTPQNBASE, 120, 60000000 / 120);
+ if (m_pMIDIClock == NULL) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ VERIFY (strMsg.LoadString (IDS_MIDICLOCK_CREATE_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ // MIDIクロックのタイムモードと速度をアプリケーションに合わせる(20090625追加)
+ ApplyAppCurSpeedIndex ();
+
+ // 状態の初期化
+ m_lOldTime = 0L;
+ m_lNewTime = 0L;
+ time (&m_tmFileOpenTime);
+ time (&m_tmLastAutoSaveTime);
+ m_lCurHistoryPosition = -1;
+ // クリティカルセクションの解除
+ m_theCriticalSection.Unlock ();
+ // ビューの更新
+ UpdateAllViews (NULL, 0xFFFFFFFF);
+ EndWaitCursor ();
+ ::Sleep (0);
+ return TRUE;
+}
+
+// ドキュメントを開く時のオーバーライド
+BOOL CSekaijuDoc::OnOpenDocument (LPCTSTR lpszPathName) {
+ BeginWaitCursor ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ // クリティカルセクションのロック
+ m_theCriticalSection.Lock ();
+ // 旧MIDIDataはあるはずがないが、もしあれば削除。
+ if (m_pMIDIData) {
+ MIDIData_Delete (m_pMIDIData);
+ m_pMIDIData = NULL;
+ }
+ // 旧MIDIClockはあるはずもないが、もしあれば削除。
+ if (m_pMIDIClock) {
+ MIDIClock_Delete (m_pMIDIClock);
+ m_pMIDIClock = NULL;
+ }
+ // アプリケーションオブジェクトへのポインタ取得
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // MIDIデータの読み込み
+ CString strPathName = lpszPathName;
+ CString strExt = strPathName.Right (4);
+ // 世界樹シーケンスファイル(*.skj)の場合
+ if (strExt.CompareNoCase (_T(".skj")) == 0) {
+ m_pMIDIData = MIDIData_LoadFromBinary (lpszPathName);
+ if (m_pMIDIData == NULL) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_N_FILE_LOAD_FAILED));
+ CString strMsg;
+ strMsg.Format (strFormat, lpszPathName);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ // フラグの初期化
+ m_pMIDIData->m_lUser1 = m_lOldTime;
+ m_pMIDIData->m_lUser2 = MIDIData_GetFormat (m_pMIDIData) == 1 ? 1 : 0;
+ m_pMIDIData->m_lUser3 = 0;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_VISIBLE | MIDITRACK_ENABLE;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASINSERTED;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASREMOVED;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASINSERTED;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASREMOVED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASINSERTED;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASREMOVED;
+ }
+ }
+ }
+ // Cherryシーケンスファイルの場合(*.chy)の場合
+ else if (strExt.CompareNoCase (_T(".chy")) == 0) {
+ m_pMIDIData = MIDIData_LoadFromCherry (lpszPathName);
+ if (m_pMIDIData == NULL) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_N_FILE_LOAD_FAILED));
+ CString strMsg;
+ strMsg.Format (strFormat, lpszPathName);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ // 各トラックのデフォルトの属性設定
+ long i = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDITrack_SetForeColor (pMIDITrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]);
+ pMIDITrack->m_lUser1 = 0;
+ pMIDITrack->m_lUser2 = 0;
+ pMIDITrack->m_lUser3 = 0;
+ pMIDITrack->m_lUserFlag = MIDITRACK_VISIBLE | MIDITRACK_ENABLE;
+ i++;
+ }
+ // フラグの初期化
+ m_pMIDIData->m_lUser1 = m_lOldTime;
+ m_pMIDIData->m_lUser2 = MIDIData_GetFormat (m_pMIDIData) == 1 ? 1 : 0;
+ m_pMIDIData->m_lUser3 = 0;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_VISIBLE | MIDITRACK_ENABLE;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASINSERTED;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASREMOVED;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASINSERTED;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASREMOVED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASINSERTED;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASREMOVED;
+ }
+ }
+ }
+ // スタンダードMIDIファイル(*.mid)の場合
+ else if (strExt.CompareNoCase (_T(".mid")) == 0 ||
+ strExt.CompareNoCase (_T(".vsq")) == 0) {
+ m_pMIDIData = MIDIData_LoadFromSMF (lpszPathName);
+ if (m_pMIDIData == NULL) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_N_FILE_LOAD_FAILED));
+ CString strMsg;
+ strMsg.Format (strFormat, lpszPathName);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ // フォーマット0のMIDIデータの場合、フォーマット1に変換する。
+ if (MIDIData_GetFormat (m_pMIDIData) == 0) {
+ m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_THIS_MIDIDATA_IS_FORMAT0_N_CONVERT_TO_FORMAT1));
+ long lRet = AfxMessageBox (strMsg, MB_ICONQUESTION | MB_YESNO);
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ VERIFY (MIDIData_SetFormat (m_pMIDIData, 1));
+ }
+ }
+ // TPQNベースで分解能が961TPQN以上の場合、960TPQNに修正する。
+ if (MIDIData_GetTimeMode (m_pMIDIData) == MIDIDATA_TPQNBASE &&
+ MIDIData_GetTimeResolution (m_pMIDIData) > 960) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_THIS_MIDIDATA_TIMERESOLUTION_IS_TOO_HIGH_D_N_MODIFY_TO_960));
+ CString strMsg;
+ strMsg.Format (strFormat, MIDIData_GetTimeResolution (m_pMIDIData));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ m_theCriticalSection.Lock ();
+ VERIFY (MIDIData_SetTimeBase (m_pMIDIData, MIDIDATA_TPQNBASE, 960));
+ }
+ // 入力ポート番号・出力ポート番号の値を0x00〜0x0Fの範囲に修正する。
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (pMIDITrack->m_lInputPort >= 16 || pMIDITrack->m_lOutputPort >= 16) {
+ pMIDITrack->m_lInputPort = 0;
+ pMIDITrack->m_lOutputPort = 0;
+ }
+ }
+ // 各トラックのデフォルトの属性設定
+ long i = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDITrack_SetForeColor (pMIDITrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]);
+ pMIDITrack->m_lUser1 = 0;
+ pMIDITrack->m_lUser2 = 0;
+ pMIDITrack->m_lUser3 = 0;
+ pMIDITrack->m_lUserFlag = MIDITRACK_VISIBLE | MIDITRACK_ENABLE;
+ i++;
+ }
+ // ノートイベントの結合
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ MIDIEvent_Combine (pMIDIEvent);
+ }
+ }
+ }
+ // フラグの初期化
+ m_pMIDIData->m_lUser1 = m_lOldTime;
+ m_pMIDIData->m_lUser2 = MIDIData_GetFormat (m_pMIDIData) == 1 ? 1 : 0;
+ m_pMIDIData->m_lUser3 = 0;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_VISIBLE | MIDITRACK_ENABLE;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASINSERTED;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASREMOVED;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASINSERTED;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASREMOVED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASINSERTED;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASREMOVED;
+ }
+ }
+ }
+ // MIDICSVファイル(*.csv)の場合
+ else if (strExt.CompareNoCase (_T(".csv")) == 0) {
+ m_pMIDIData = MIDIData_LoadFromMIDICSV (lpszPathName);
+ if (m_pMIDIData == NULL) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_N_FILE_LOAD_FAILED));
+ CString strMsg;
+ strMsg.Format (strFormat, lpszPathName);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ // フォーマット0のMIDIデータの場合、フォーマット1に変換する。
+ if (MIDIData_GetFormat (m_pMIDIData) == 0) {
+ m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_THIS_MIDIDATA_IS_FORMAT0_N_CONVERT_TO_FORMAT1));
+ long lRet = AfxMessageBox (strMsg, MB_ICONQUESTION | MB_YESNO);
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ VERIFY (MIDIData_SetFormat (m_pMIDIData, 1));
+ }
+ }
+ // TPQNベースで分解能が961TPQN以上の場合、960TPQNに修正する。
+ if (MIDIData_GetTimeMode (m_pMIDIData) == MIDIDATA_TPQNBASE &&
+ MIDIData_GetTimeResolution (m_pMIDIData) > 960) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_THIS_MIDIDATA_TIMERESOLUTION_IS_TOO_HIGH_D_N_MODIFY_TO_960));
+ CString strMsg;
+ strMsg.Format (strFormat, MIDIData_GetTimeResolution (m_pMIDIData));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION | MB_OK);
+ m_theCriticalSection.Lock ();
+ VERIFY (MIDIData_SetTimeBase (m_pMIDIData, MIDIDATA_TPQNBASE, 960));
+ }
+ // 入力ポート番号・出力ポート番号の値を0x00〜0x0Fの範囲に修正する。
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (pMIDITrack->m_lInputPort >= 16 || pMIDITrack->m_lOutputPort >= 16) {
+ pMIDITrack->m_lInputPort = 0;
+ pMIDITrack->m_lOutputPort = 0;
+ }
+ }
+ // 各トラックのデフォルトの属性設定
+ long i = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDITrack_SetForeColor (pMIDITrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]);
+ pMIDITrack->m_lUser1 = 0;
+ pMIDITrack->m_lUser2 = 0;
+ pMIDITrack->m_lUser3 = 0;
+ pMIDITrack->m_lUserFlag = MIDITRACK_VISIBLE | MIDITRACK_ENABLE;
+ i++;
+ }
+ // ノートイベントの結合
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ MIDIEvent_Combine (pMIDIEvent);
+ }
+ }
+ }
+ // フラグの初期化
+ m_pMIDIData->m_lUser1 = m_lOldTime;
+ m_pMIDIData->m_lUser2 = MIDIData_GetFormat (m_pMIDIData) == 1 ? 1 : 0;
+ m_pMIDIData->m_lUser3 = 0;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_VISIBLE | MIDITRACK_ENABLE;
+ m_pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASINSERTED;
+ m_pMIDIData->m_lUserFlag &= ~MIDIDATA_RESISTEREDASREMOVED;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASINSERTED;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_RESISTEREDASREMOVED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASINSERTED;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_RESISTEREDASREMOVED;
+ }
+ }
+ }
+ // 未定義のフォーマットの場合
+ else {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_S_N_INVALID_EXT_N_FILE_LOAD_FAILED));
+ CString strMsg;
+ strMsg.Format (strFormat, lpszPathName);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+ // MIDIクロックの生成
+ m_pMIDIClock = MIDIClock_Create (lTimeMode, lTimeResolution, 60000000 / 120);
+ if (m_pMIDIClock == NULL) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_MIDICLOCK_CREATE_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ // MIDIクロックのタイムモードと速度をアプリケーションに合わせる(20090625追加)
+ ApplyAppCurSpeedIndex ();
+
+ // 状態の初期化
+ m_lOldTime = 0L;
+ m_lNewTime = 0L;
+ time (&m_tmFileOpenTime);
+ time (&m_tmLastAutoSaveTime);
+ m_lCurHistoryPosition = -1;
+
+ // フォーマット1の場合のMIDIデータの正当性チェック(1)(20100128追加)
+ if (MIDIData_GetFormat (m_pMIDIData) == 1) {
+ long lNumErrorEvent = 0;
+ CPtrArray theErrorEventArray;
+ // 最初のトラックにMIDIチャンネルイベントが混入していないかチェック
+ pMIDITrack = MIDIData_GetFirstTrack (m_pMIDIData);
+ if (pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ lNumErrorEvent++;
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ theErrorEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ }
+ // 最初のトラックにMIDIチャンネルイベントが混入していた場合
+ if (lNumErrorEvent > 0) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_MIDICHANNELEVENTS_ARE_IN_THE_FIRST_TRACK_ARE_YOU_SURE_TO_REPAIR_THEM));
+ CString strMsg;
+ strMsg.Format (strFormat, lNumErrorEvent);
+ long lRet = AfxMessageBox (strMsg, MB_ICONQUESTION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ // 異常なMIDIチャンネルイベントを他のトラックに移動
+ if (lRet == IDYES) {
+ long i = 0;
+ long j = 0;
+ MIDITrack* pNewTrack[16] = {NULL};
+ for (i = 0; i < 16; i++) {
+ VERIFY (pNewTrack[i] = MIDITrack_Create ());
+ }
+ for (j = 0; j < theErrorEventArray.GetSize (); j++) {
+ MIDIEvent* pErrorEvent = (MIDIEvent*)(theErrorEventArray.GetAt (j));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pErrorEvent));
+ long lChannel = MIDIEvent_GetChannel (pErrorEvent);
+ if (0 <= lChannel && lChannel < 16) {
+ VERIFY (MIDITrack_InsertEvent (pNewTrack[lChannel], pErrorEvent));
+ }
+ }
+ MIDITrack* pPrevTrack = MIDIData_GetFirstTrack (m_pMIDIData);
+ for (i = 0; i < 16; i++) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pNewTrack[i]);
+ if (pLastEvent) {
+ if (!MIDIEvent_IsEndofTrack (pLastEvent)) {
+ long lLastTime = MIDIEvent_GetTime (pLastEvent);
+ VERIFY (MIDITrack_InsertEndofTrack (pNewTrack[i], lLastTime));
+ }
+ VERIFY (MIDITrack_SetForeColor (pNewTrack[i], pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]));
+ VERIFY (MIDITrack_SetInputPort (pNewTrack[i], 0)); // 20120109追加
+ VERIFY (MIDITrack_SetInputChannel (pNewTrack[i], i)); // 20120109追加
+ VERIFY (MIDITrack_SetOutputPort (pNewTrack[i], 0)); // 20120109追加
+ VERIFY (MIDITrack_SetOutputChannel (pNewTrack[i], i)); // 20120109追加
+ pNewTrack[i]->m_lUser1 = 0;
+ pNewTrack[i]->m_lUser2 = 0;
+ pNewTrack[i]->m_lUser3 = 0;
+ pNewTrack[i]->m_lUserFlag = MIDITRACK_VISIBLE | MIDITRACK_ENABLE;
+ VERIFY (MIDIData_InsertTrackAfter (m_pMIDIData, pNewTrack[i], pPrevTrack));
+ pPrevTrack = pNewTrack[i];
+ }
+ }
+ VERIFY (MIDITrack_SetInputPort (pMIDITrack, 0)); // 20120109追加
+ VERIFY (MIDITrack_SetInputChannel (pMIDITrack, -1)); // 20120109追加
+ VERIFY (MIDITrack_SetOutputPort (pMIDITrack, 0)); // 20120109追加
+ VERIFY (MIDITrack_SetOutputChannel (pMIDITrack, -1)); // 20120109追加
+ }
+ // 異常なまま読み込む場合、編集・保存とも不可とする
+ else {
+ m_bEditLocked = TRUE;
+ m_bSaveLocked = TRUE;
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_THIS_MIDIDATA_CANT_BE_EDITED_OR_SAVED_BECAUSE_IT_IS_ABNORMAL));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ }
+ }
+ }
+
+ // フォーマット1の場合のMIDIデータの正当性チェック(2)(20100128追加)
+ if (MIDIData_GetFormat (m_pMIDIData) == 1) {
+ long i = 0;
+ long lNumErrorEvent = 0;
+ CPtrArray theErrorEventArray;
+ // 2番目以降のトラックにテンポ・SMPTEオフセット・拍子記号・調性記号イベントが混入していないかチェック
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (i >= 1) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsTempo (pMIDIEvent) ||
+ MIDIEvent_IsSMPTEOffset (pMIDIEvent) ||
+ MIDIEvent_IsTimeSignature (pMIDIEvent) ||
+ MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ lNumErrorEvent++;
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ theErrorEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ }
+ i++;
+ }
+ // 2番目以降のトラックにテンポ・SMPTEオフセット・拍子記号・調性記号イベントが混入していた場合
+ if (lNumErrorEvent > 0) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_TEMPOEVENTS_ARE_IN_THE_SECOND_TRACK_ARE_YOU_SURE_TO_REPAIR_THEM));
+ CString strMsg;
+ strMsg.Format (strFormat, lNumErrorEvent);
+ long lRet = AfxMessageBox (strMsg, MB_ICONQUESTION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ // 異常なMIDIチャンネルイベントを他のトラックに移動
+ if (lRet == IDYES) {
+ long j = 0;
+ MIDITrack* pMIDITrack = MIDIData_GetFirstTrack (m_pMIDIData);
+ for (j = 0; j < theErrorEventArray.GetSize (); j++) {
+ MIDIEvent* pErrorEvent = (MIDIEvent*)(theErrorEventArray.GetAt (j));
+ MIDITrack* pErrorTrack = (MIDITrack*)MIDIEvent_GetParent (pErrorEvent);
+ VERIFY (MIDITrack_RemoveEvent (pErrorTrack, pErrorEvent));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pErrorEvent));
+ }
+ }
+ // 異常なまま読み込む場合、編集・保存とも不可とする
+ else {
+ m_bEditLocked = TRUE;
+ m_bSaveLocked = TRUE;
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_THIS_MIDIDATA_CANT_BE_EDITED_OR_SAVED_BECAUSE_IT_IS_ABNORMAL));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ }
+ }
+ }
+
+ // ビューの更新
+ UpdateAllViews (NULL, 0xFFFFFFFF);
+
+ // 最後に開いたファイル名の更新
+ pSekaijuApp->m_strLastOpenFileName[0] = lpszPathName;
+
+ // 自動演奏開始
+ if (pSekaijuApp->m_theGeneralOption.m_bOpenPlay == TRUE &&
+ pSekaijuApp->m_bPlaying == FALSE) {
+ AfxGetMainWnd ()->PostMessage (WM_COMMAND, ID_CONTROL_PLAY, 0);
+ }
+
+ // クリティカルセクションの解除
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ return TRUE;
+}
+
+// ドキュメントを保存するときのオーバーライド
+BOOL CSekaijuDoc::OnSaveDocument (LPCTSTR lpszPathName) {
+ BeginWaitCursor ();
+ CString strPathName (lpszPathName);
+ CString strExt = strPathName.Right (4);
+ CString strMsg1;
+ CString strMsg2;
+ long lRet = 0;
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_theCriticalSection.Lock ();
+ // 録音中の場合は録音停止
+ if (pSekaijuApp->m_bRecording) {
+ pSekaijuApp->StopRecording (this);
+ }
+
+ if (m_bSaveLocked) {
+ return FALSE;
+ }
+
+
+ // 世界樹シーケンスファイル(*.skj)の場合
+ if (strExt.CompareNoCase (_T(".skj")) == 0) {
+ lRet = MIDIData_SaveAsBinary (m_pMIDIData, lpszPathName);
+ if (lRet == 0) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ VERIFY (strMsg1.LoadString (IDS_S_N_MIDIDATA_SAVE_FAILED));
+ strMsg2.Format (strMsg1, lpszPathName);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ }
+ // Cherryシーケンスファイル(*.chy)の場合
+ else if (strExt.CompareNoCase (_T(".chy")) == 0) {
+ lRet = MIDIData_SaveAsCherry (m_pMIDIData, lpszPathName);
+ if (lRet == 0) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ VERIFY (strMsg1.LoadString (IDS_S_N_MIDIDATA_SAVE_FAILED));
+ strMsg2.Format (strMsg1, lpszPathName);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ }
+ // スタンダードMIDIファイル(*.mid)の場合
+ else if (strExt.CompareNoCase (_T(".mid")) == 0 ||
+ strExt.CompareNoCase (_T(".vsq")) == 0) {
+ // MIDIイベントのチャンネルチェック
+ long lCount = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ // 出力先トラック番号が1〜16のいずれかに指定されているならば
+ if (0 <= lOutputChannel && lOutputChannel < 16) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ long lChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ if (lOutputChannel != lChannel) {
+ lCount++;
+ }
+ }
+ }
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_MIDIEVENTS_CHANNEL_IS_CONFLICTED_N_CONVERT_TO_MIDITRACKS_CHANNEL));
+ strMsg2.Format (strMsg1, lCount);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDICHANNEL));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ // 出力先トラック番号が1〜16のいずれかに指定されているならば
+ if (0 <= lOutputChannel && lOutputChannel < 16) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // MIDIチャンネルイベントで前方向に非結合イベントならば
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ // トラックの出力チャンネルとMIDIチャンネルが異なっているならば
+ if (MIDIEvent_GetChannel (pMIDIEvent) != lOutputChannel) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ pCloneEvent = ReplaceMIDIEvent (pMIDIEvent);
+ MIDIEvent_SetChannel (pCloneEvent, lOutputChannel);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // ノートイベントの長さ>0であることのチェック
+ lCount = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ if (lDuration <= 0) {
+ lCount++;
+ }
+ }
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_MIDIEVENTS_DURATION_IS_LESS_THAN_0_N_DELETE_THESE_MIDIEVENTS));
+ strMsg2.Format (strMsg1,lCount);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_NOTEEVENT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ CPtrArray theEventArray;
+ theEventArray.RemoveAll ();
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) &&
+ MIDIEvent_IsNote (pMIDIEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ if (lDuration <= 0) {
+ theEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ long j;
+ for (j = 0; j < theEventArray.GetSize (); j++) {
+ pMIDIEvent = (MIDIEvent*)theEventArray.GetAt (j);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent);
+ }
+ }
+ }
+ }
+ // トラックの最後ではないエンドオブトラックイベントのチェック
+ lCount = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent) && pMIDIEvent != pLastEvent) {
+ lCount++;
+ }
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_ENDOFTRACKEVENT_IS_NOT_LAST_PLACE_N_DELETE_THESE_ENDOFTRACKEVENTS));
+ strMsg2.Format (strMsg1, lCount);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_ENDOFTRACKEVENT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent) && pMIDIEvent != pLastEvent) {
+ MIDIEvent* pTempEvent = MIDIEvent_GetPrevEvent (pMIDIEvent);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent));
+ pMIDIEvent = pTempEvent;
+ }
+ }
+ }
+ }
+ }
+ // トラックの最後のエンドオブトラックイベントの付け忘れチェック
+ lCount = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (!MIDIEvent_IsEndofTrack (pLastEvent)) {
+ lCount++;
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_MIDITRACK_DOESNT_HAVE_ENDOFTRACKEVENT_N_INSERT_ENDOFTRACKEVENTS));
+ strMsg2.Format (strMsg1, lCount);
+ EndWaitCursor ();
+ m_theCriticalSection.Unlock ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ m_theCriticalSection.Lock ();
+ BeginWaitCursor ();
+ if (lRet == IDYES) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ADD_ENDOFTRACKEVENT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (!MIDIEvent_IsEndofTrack (pLastEvent)) {
+ long lTime = (pLastEvent ? MIDIEvent_GetTime (pLastEvent) : 0);
+ VERIFY (pMIDIEvent = MIDIEvent_CreateEndofTrack (lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pMIDIEvent));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pMIDIEvent));
+ }
+ }
+ }
+ }
+
+ // 保存
+ lRet = MIDIData_SaveAsSMF (m_pMIDIData, lpszPathName);
+ if (lRet == 0) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ VERIFY (strMsg1.LoadString (IDS_S_N_MIDIDATA_SAVE_FAILED));
+ strMsg2.Format (strMsg1, lpszPathName);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ }
+
+ // MIDICSVファイル(*.csv)の場合
+ else if (strExt.CompareNoCase (_T(".csv")) == 0) {
+ // MIDIイベントのチャンネルチェック
+ long lCount = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ // 出力先トラック番号が1〜16のいずれかに指定されているならば
+ if (0 <= lOutputChannel && lOutputChannel < 16) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ long lChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ if (lOutputChannel != lChannel) {
+ lCount++;
+ }
+ }
+ }
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_MIDIEVENTS_CHANNEL_IS_CONFLICTED_N_CONVERT_TO_MIDITRACKS_CHANNEL));
+ strMsg2.Format (strMsg1, lCount);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_MIDICHANNEL));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ // 出力先トラック番号が1〜16のいずれかに指定されているならば
+ if (0 <= lOutputChannel && lOutputChannel < 16) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // MIDIチャンネルイベントで前方向に非結合イベントならば
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ // トラックの出力チャンネルとMIDIチャンネルが異なっているならば
+ if (MIDIEvent_GetChannel (pMIDIEvent) != lOutputChannel) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ pCloneEvent = ReplaceMIDIEvent (pMIDIEvent);
+ MIDIEvent_SetChannel (pCloneEvent, lOutputChannel);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // ノートイベントの長さ>0であることのチェック
+ lCount = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsNote (pMIDIEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ if (lDuration <= 0) {
+ lCount++;
+ }
+ }
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_MIDIEVENTS_DURATION_IS_LESS_THAN_0_N_DELETE_THESE_MIDIEVENTS));
+ strMsg2.Format (strMsg1,lCount);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_NOTEEVENT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ CPtrArray theEventArray;
+ theEventArray.RemoveAll ();
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) &&
+ MIDIEvent_IsNote (pMIDIEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ if (lDuration <= 0) {
+ theEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ long j;
+ for (j = 0; j < theEventArray.GetSize (); j++) {
+ pMIDIEvent = (MIDIEvent*)theEventArray.GetAt (j);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent);
+ }
+ }
+ }
+ }
+ // トラックの最後ではないエンドオブトラックイベントのチェック
+ lCount = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent) && pMIDIEvent != pLastEvent) {
+ lCount++;
+ }
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_ENDOFTRACKEVENT_IS_NOT_LAST_PLACE_N_DELETE_THESE_ENDOFTRACKEVENTS));
+ strMsg2.Format (strMsg1, lCount);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ if (lRet == IDYES) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_ENDOFTRACKEVENT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent) && pMIDIEvent != pLastEvent) {
+ MIDIEvent* pTempEvent = MIDIEvent_GetPrevEvent (pMIDIEvent);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent));
+ pMIDIEvent = pTempEvent;
+ }
+ }
+ }
+ }
+ }
+ // トラックの最後のエンドオブトラックイベントの付け忘れチェック
+ lCount = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (!MIDIEvent_IsEndofTrack (pLastEvent)) {
+ lCount++;
+ }
+ }
+ if (lCount > 0) {
+ VERIFY (strMsg1.LoadString (IDS_D_MIDITRACK_DOESNT_HAVE_ENDOFTRACKEVENT_N_INSERT_ENDOFTRACKEVENTS));
+ strMsg2.Format (strMsg1, lCount);
+ EndWaitCursor ();
+ m_theCriticalSection.Unlock ();
+ lRet = AfxMessageBox (strMsg2, MB_ICONINFORMATION | MB_YESNO);
+ m_theCriticalSection.Lock ();
+ BeginWaitCursor ();
+ if (lRet == IDYES) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ADD_ENDOFTRACKEVENT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (!MIDIEvent_IsEndofTrack (pLastEvent)) {
+ long lTime = (pLastEvent ? MIDIEvent_GetTime (pLastEvent) : 0);
+ VERIFY (pMIDIEvent = MIDIEvent_CreateEndofTrack (lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pMIDIEvent));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pMIDIEvent));
+ }
+ }
+ }
+ }
+
+ // 保存
+ lRet = MIDIData_SaveAsMIDICSV (m_pMIDIData, lpszPathName);
+ if (lRet == 0) {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ VERIFY (strMsg1.LoadString (IDS_S_N_MIDIDATA_SAVE_FAILED));
+ strMsg2.Format (strMsg1, lpszPathName);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+
+ }
+ // 未定義のフォーマットの場合
+ else {
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ VERIFY (strMsg1.LoadString (IDS_S_N_INVALID_EXT_N_FILE_SAVE_FAILED));
+ strMsg2.Format (strMsg1, lpszPathName);
+ AfxMessageBox (strMsg2, MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ SetModifiedFlag (0);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ UpdateAllViews (NULL,
+ SEKAIJUDOC_MIDIDATACHANGED | SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ EndWaitCursor ();
+ return TRUE;
+}
+
+// ドキュメントを閉じる時のオーバーライド
+void CSekaijuDoc::OnCloseDocument () {
+ _RPTF0 (_CRT_WARN, ("CSekaijuDoc::OnCloseDocument ()\n"));
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_theCriticalSection.Lock ();
+ // 録音中の場合は録音停止
+ // 注意:録音中に突然閉じられた場合、先にCSekaijuDoc::OnSaveDocumentが呼び出されることがある。
+ // よって、CSekaijuDoc::OnSaveDocumentの冒頭でStopRecordingを呼び出しておくこと。
+ if (pSekaijuApp->m_bRecording) {
+ pSekaijuApp->StopRecording (this);
+ }
+ m_theCriticalSection.Unlock ();
+ CDocument::OnCloseDocument ();
+ // CDocument::OnCloseDocument ()内でdelete thisされ、その際デストラクタが呼び出される。
+}
+
+
+
+
+
+
+//------------------------------------------------------------------------------
+// CSekaijuDoc クラスの診断
+//------------------------------------------------------------------------------
+
+#ifdef _DEBUG
+void CSekaijuDoc::AssertValid () const {
+ CDocument::AssertValid ();
+}
+
+void CSekaijuDoc::Dump (CDumpContext& dc) const {
+ CDocument::Dump (dc);
+}
+#endif
+
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// アプリケーションのスピードインデックスを適用する
+BOOL CSekaijuDoc::ApplyAppCurSpeedIndex () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 同期モードの取得
+ long lSyncInputPort = 0;
+ long lSyncInputMode = 0;
+ pSekaijuApp->GetCurSyncInputPortAndMode (&lSyncInputPort, &lSyncInputMode);
+ // タイムベースの取得
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+ // MIDIClockが動作している場合は強制停止
+ MIDIClock_Stop (m_pMIDIClock);
+ // MIDIクロックのタイムモードと速度をアプリケーションに合わせる(20090625追加)
+ switch (pSekaijuApp->m_lCurSpeedIndex) {
+ case 0: // スピード=静止
+ MIDIClock_SetTimeBase (m_pMIDIClock, lTimeMode, lTimeResolution);
+ MIDIClock_SetSpeed (m_pMIDIClock, 0);
+ MIDIClock_SetMIDIInSyncMode (m_pMIDIClock, MIDICLOCK_MASTER);
+ break;
+ case 1: // スピード=低速
+ MIDIClock_SetTimeBase (m_pMIDIClock, lTimeMode, lTimeResolution);
+ MIDIClock_SetSpeed (m_pMIDIClock, pSekaijuApp->m_theGeneralOption.m_lSpeedSlow);
+ MIDIClock_SetMIDIInSyncMode (m_pMIDIClock, MIDICLOCK_MASTER);
+ break;
+ case 2: // スピード=標準
+ MIDIClock_SetTimeBase (m_pMIDIClock, lTimeMode, lTimeResolution);
+ MIDIClock_SetSpeed (m_pMIDIClock, pSekaijuApp->m_theGeneralOption.m_lSpeedNormal);
+ MIDIClock_SetMIDIInSyncMode (m_pMIDIClock, MIDICLOCK_MASTER);
+ break;
+ case 3: // スピード=高速
+ MIDIClock_SetTimeBase (m_pMIDIClock, lTimeMode, lTimeResolution);
+ MIDIClock_SetSpeed (m_pMIDIClock, pSekaijuApp->m_theGeneralOption.m_lSpeedFast);
+ MIDIClock_SetMIDIInSyncMode (m_pMIDIClock, MIDICLOCK_MASTER);
+ break;
+ case 4: // スピード=他機器にスレーブ
+ if (lSyncInputMode == 1) { // MIDIタイミングクロックにスレーブ
+ MIDIClock_SetTimeBase (m_pMIDIClock, MIDICLOCK_SLAVEMIDITIMINGCLOCK, lTimeResolution);
+ MIDIClock_SetMIDIInSyncMode (m_pMIDIClock, MIDICLOCK_SLAVEMIDITIMINGCLOCK);
+ }
+ else if (lSyncInputMode == 2) { // SMPTE/MTCにスレーブ
+ MIDIClock_SetTimeBase (m_pMIDIClock, MIDICLOCK_SLAVESMPTEMTC, lTimeResolution);
+ MIDIClock_SetMIDIInSyncMode (m_pMIDIClock, MIDICLOCK_SLAVESMPTEMTC);
+ }
+ else {
+ ASSERT (FALSE);
+ // TODO:
+ }
+ MIDIClock_SetSpeed (m_pMIDIClock, 10000);
+ break;
+ }
+ return TRUE;
+}
+
+
+
+// 指定時刻のMIDIステータス(状態)を計算し、引数で指定されたpMIDIStatus[]に格納する。
+void CSekaijuDoc::TimeMIDIStatus (long lTargetTime, MIDIStatus* pMIDIStatus[]) {
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ lTargetTime = CLIP (0, lTargetTime, 0x7FFFFFFF);
+ // 20120106 システムエクスクルーシヴイベントはどこのトラックに挿入されるか未定なので、
+ // MIDIチャンネルイベントに先立って計算するように修正。
+ // システムエクスクルーシヴイベントによる状態の計算
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (MIDITrack_GetOutputOn (pMIDITrack)) {
+ long lOutputOn = MIDITrack_GetOutputOn (pMIDITrack);
+ long lOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (lOutputOn) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ lTime = CLIP (0, lTime + MIDITrack_GetTimePlus (pMIDITrack), 0x7FFFFFFF);
+ if (lTime > lTargetTime) { // 20111010符号
+ break;
+ }
+ // システムエクスクルーシブイベントの場合
+ if (MIDIEvent_IsSysExEvent (pMIDIEvent)) {
+ BYTE byMsg[256];
+ memset (byMsg, 0, sizeof (byMsg));
+ long lLen = MIDIEvent_GetLen (pMIDIEvent);
+ MIDIEvent_GetData (pMIDIEvent, byMsg, __min (lLen, sizeof (byMsg)));
+ // 出力ポートが存在する場合のみ
+ if (pMIDIStatus[lOutputPort] != NULL) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus[lOutputPort], byMsg, lLen);
+ }
+ }
+ }
+ }
+ }
+ }
+ // MIDIチャンネルイベントによる状態の計算
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (MIDITrack_GetOutputOn (pMIDITrack)) {
+ long lOutputOn = MIDITrack_GetOutputOn (pMIDITrack);
+ long lOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (lOutputOn) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ lTime = CLIP (0, lTime + MIDITrack_GetTimePlus (pMIDITrack), 0x7FFFFFFF);
+ if (lTime > lTargetTime) { // 20111010符号
+ break;
+ }
+ // MIDIチャンネルイベントの場合
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent)) {
+ BYTE byMsg[256];
+ memset (byMsg, 0, sizeof (byMsg));
+ long lLen = MIDIEvent_GetLen (pMIDIEvent);
+ MIDIEvent_GetData (pMIDIEvent, byMsg, __min (lLen, sizeof (byMsg)));
+ // トラックで設定された出力チャンネルの反映
+ if (0 <= lOutputChannel && lOutputChannel < 16) {
+ byMsg[0] &= 0xF0;
+ byMsg[0] |= (BYTE)lOutputChannel;
+ }
+ // キー+とベロシティ+の反映
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ byMsg[1] = (BYTE)CLIP (0, byMsg[1] + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ byMsg[2] = (BYTE)CLIP (1, byMsg[2] + MIDITrack_GetVelocityPlus (pMIDITrack), 127);
+ }
+ else if (MIDIEvent_IsNoteOff (pMIDIEvent) || MIDIEvent_IsKeyAftertouch (pMIDIEvent)) {
+ byMsg[1] = (BYTE)CLIP (0, byMsg[1] + MIDITrack_GetKeyPlus (pMIDITrack), 127);
+ }
+ // 出力ポートが存在する場合のみ
+ if (pMIDIStatus[lOutputPort] != NULL) {
+ MIDIStatus_PutMIDIMessage (pMIDIStatus[lOutputPort], byMsg, lLen);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// クリップボードに独自テキストを設定
+BOOL CSekaijuDoc::SetClipboardTextPrivate9 (CString& strData) {
+ TCHAR* p = NULL;
+ HGLOBAL hGlobalMem = NULL;
+ if ((hGlobalMem = GlobalAlloc (GHND, strData.GetLength() + 32)) == NULL) {
+ //_RPTF0 (_CRT_WARN, "グローバルメモリ確保不能。コピーは失敗しました。\n");
+ return FALSE;
+ }
+ if ((p = (TCHAR*)GlobalLock(hGlobalMem)) == NULL) {
+ //_RPTF0 (_CRT_WARN, "グローバルメモリ固定不能。コピーは失敗しました。\n");
+ GlobalFree(hGlobalMem);
+ return FALSE;
+ }
+ _tcscpy (p, (LPCTSTR)strData);
+ if (GlobalUnlock(hGlobalMem) == TRUE) {
+ //まだロックされてればTRUE,解放されたorエラーはFALSE。
+ //_RPTF0 (_CRT_WARN, "グローバルメモリ固定異常。コピーは失敗しました。\n");
+ GlobalFree(hGlobalMem);
+ return FALSE;
+ }
+ if(::OpenClipboard (AfxGetMainWnd()->m_hWnd) == FALSE) {
+ //_RPTF0 (_CRT_WARN, "クリップボードオープン不能。コピーは失敗しました。\n");
+ GlobalFree (hGlobalMem);
+ return FALSE;
+ }
+ if (::EmptyClipboard() == FALSE) {
+ ::CloseClipboard();//先に閉じないとダイアログ表示時にいじられる。
+ //_RPTF0 (_CRT_WARN, "クリップボード初期化不能。コピーは失敗しました。\n");
+ GlobalFree (hGlobalMem);
+ return FALSE;
+ }
+ if (::SetClipboardData(CF_PRIVATEFIRST + 9, hGlobalMem) == FALSE) {
+ ::CloseClipboard();
+ //_RPTF0 (_CRT_WARN, "クリップボード転送不能。コピーは失敗しました。\n");
+ GlobalFree (hGlobalMem);
+ }
+ CloseClipboard();
+ // hGlobalMemはもはやこのプログラムのものではない。
+ // 従って、GlobalFree(hGlobalMem)をかけない。
+ return TRUE;
+}
+
+// クリップボードの独自テキストを取得
+BOOL CSekaijuDoc::GetClipboardTextPrivate9 (CString& strText) {
+ if (IsClipboardFormatAvailable (CF_PRIVATEFIRST + 9) == FALSE) {
+ //_RPTF0 (_CRT_WARN, "クリップボードが有効な形式ではありません。貼り付けに失敗しました。\n");
+ return FALSE;
+ }
+ if (::OpenClipboard (AfxGetMainWnd()->m_hWnd) == FALSE) {
+ //_RPTF0 (_CRT_WARN, "クリップボードが開けません。貼り付けに失敗しました。\n");
+ return FALSE;
+ }
+ HGLOBAL hData = NULL;
+ if ((hData = GetClipboardData(CF_PRIVATEFIRST + 9)) == NULL) {
+ CloseClipboard (); // 先に閉じないとダイアログ表示中にいじられる。
+ //_RPTF0 (_CRT_WARN, "クリップボードから転送不能。貼り付けに失敗しました。\n");
+ return FALSE;
+ }
+ TCHAR* p = NULL; // 転送元バッファ。
+ if ((p = (TCHAR*)GlobalLock(hData)) == NULL) {
+ CloseClipboard ();
+ //_RPTF0 (_CRT_WARN, "グローバルメモリ固定不能。貼り付けに失敗しました。\n");
+ return FALSE;
+ }
+ CString strData = p;
+ if ((GlobalUnlock (hData)) == TRUE) {
+ // まだロックされてればTRUE,解放されたorエラーはFALSE。
+ // 20121103修正:いったんWindowsに管理を委託したメモリのロックカウントについては関与しない。
+ //CloseClipboard();
+ //_RPTF0 (_CRT_WARN, "グローバルメモリ固定異常(致命的)。貼り付けに失敗しました。\n");
+ //return FALSE;
+ }
+ //重要!プログラミングWindows95(アスキー) P.929 に以下のように記述。
+ //『クリップボードをクローズする前にデータブロックのロックをはずす。』
+ if (::CloseClipboard () == FALSE) {
+ //_RPTF0 (_CRT_WARN, "クリップボードを閉じられません。しかし処理を続けます。\n");
+ }
+ strText = strData;
+ return TRUE;
+}
+
+// クリップボードが独自テキストかどうか調べる
+BOOL CSekaijuDoc::IsClipboardTextPrivate9 () {
+ if (IsClipboardFormatAvailable (CF_PRIVATEFIRST + 9) == FALSE) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// コピー用文字列を作成
+long CSekaijuDoc::MakeCopyString (CString& strText, long lTempCopyMode, CHistoryUnit* pHistoryUnit) {
+ long i, j, k;
+ long lFormat;
+ long lTimeMode;
+ long lTimeResolution;
+ long lBeginTime = 0x7FFFFFFF;
+ long lEndTime = 0;
+ long lBeginTrack = 0x7FFFFFFF;
+ long lEndTrack = 0;
+ long lCopiedEventCount = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ //m_theCriticalSection.Lock ();
+ lFormat = MIDIData_GetFormat (m_pMIDIData);
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+ i = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_SELECTED;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_SELECTED;
+ if (i < lBeginTrack) {
+ lBeginTrack = i;
+ }
+ lEndTrack = i;
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime < lBeginTime) {
+ lBeginTime = lTime;
+ }
+ if (lTime > lEndTime) {
+ lEndTime = lTime;
+ }
+ }
+ }
+ i++;
+ }
+ if (lBeginTime == 0x7FFFFFFF || lBeginTrack == 0x7FFFFFFF) {
+ //m_theCriticalSection.Unlock ();
+ //AfxMessageBox ("イベントが何も選択されていません。", MB_ICONEXCLAMATION);
+ //m_theCriticalSection.Lock ();
+ ASSERT (FALSE);
+ return 0;
+ }
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (m_pMIDIData, lBeginTime, &lMeasure, &lBeat, &lTick);
+ MIDIData_MakeTime (m_pMIDIData, lMeasure, 0, 0, &lBeginTime);
+
+ // MIDIデータ情報をstrDataに設定
+ CString strData;
+ CString strTextLine;
+ CString strTextTemp;
+
+ strTextLine.Format (_T("MDa2 %X %X %X %X %X %X %X %X %X %X\n"),
+ (m_pMIDIData->m_lFormat == 0 ? 0 : 2),
+ (lTempCopyMode ? lEndTrack - lBeginTrack + 1 : lEndTrack + 1),
+ m_pMIDIData->m_lTimeBase,
+ m_pMIDIData->m_lReserved1,
+ m_pMIDIData->m_lReserved2,
+ m_pMIDIData->m_lReserved3,
+ m_pMIDIData->m_lReserved4,
+ m_pMIDIData->m_lUser1,
+ m_pMIDIData->m_lUser2,
+ m_pMIDIData->m_lUser3,
+ m_pMIDIData->m_lUserFlag);
+ strData += strTextLine;
+
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (pMIDITrack->m_lUserFlag & MIDITRACK_SELECTED) {
+ MIDITrack_CountEvent (pMIDITrack);
+ strTextLine.Format (_T("MTr2 %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X\n"),
+ pMIDITrack->m_lTempIndex - (lTempCopyMode ? lBeginTrack : 0),
+ pMIDITrack->m_lNumEvent,
+ pMIDITrack->m_lInputOn,
+ pMIDITrack->m_lInputPort,
+ pMIDITrack->m_lInputChannel,
+ pMIDITrack->m_lOutputOn,
+ pMIDITrack->m_lOutputPort,
+ pMIDITrack->m_lOutputChannel,
+ pMIDITrack->m_lViewMode,
+ pMIDITrack->m_lForeColor,
+ pMIDITrack->m_lBackColor,
+ pMIDITrack->m_lTimePlus,
+ pMIDITrack->m_lKeyPlus,
+ pMIDITrack->m_lVelocityPlus,
+ pMIDITrack->m_lReserved1,
+ pMIDITrack->m_lReserved2,
+ pMIDITrack->m_lReserved3,
+ pMIDITrack->m_lReserved4,
+ pMIDITrack->m_lUser1,
+ pMIDITrack->m_lUser2,
+ pMIDITrack->m_lUser3,
+ pMIDITrack->m_lUserFlag);
+ j = 0;
+ strData += strTextLine;
+
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ strTextLine = _T("");
+ if (IsEventSelected (pMIDIEvent)) {
+ strTextTemp.Format (_T("MEvt %X %X %X %X"),
+ pMIDIEvent->m_lTempIndex,
+ pMIDIEvent->m_lTime - lBeginTime,
+ pMIDIEvent->m_lKind,
+ pMIDIEvent->m_lLen);
+ strTextLine += strTextTemp;
+ for (k = 0; k < pMIDIEvent->m_lLen; k++) {
+ strTextTemp.Format (_T(" %X"), *(pMIDIEvent->m_pData + k));
+ strTextLine += strTextTemp;
+ }
+ strTextTemp.Format (_T(" %X %X %X %X %X %X\n"),
+ pMIDIEvent->m_pPrevCombinedEvent ? pMIDIEvent->m_pPrevCombinedEvent->m_lTempIndex : -1,
+ pMIDIEvent->m_pNextCombinedEvent ? pMIDIEvent->m_pNextCombinedEvent->m_lTempIndex : -1,
+ pMIDIEvent->m_lUser1,
+ pMIDIEvent->m_lUser2,
+ pMIDIEvent->m_lUser3,
+ pMIDIEvent->m_lUserFlag);
+ strTextLine += strTextTemp;
+ strData += strTextLine;
+ lCopiedEventCount++;
+ }
+ j++;
+ }
+ }
+ i++;
+ }
+
+ strText = strData;
+ return lCopiedEventCount;
+}
+
+// 独自テキストを展開して貼り付け
+long CSekaijuDoc::ParsePasteString
+(CString& strData, long lBeginTrackIndex, long lBeginTime, CHistoryUnit* pHistoryUnit) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CString strMsg;
+ CString strTextLine;
+ long lFormat;
+ long lNumTrack;
+ long lTimeBase;
+ long lTimeMode;
+ long lTimeResolution;
+ long lNumEvent;
+ long lTrackIndex;
+ long lEventIndex;
+ long lTime;
+ long lKind;
+ long lLen;
+ BYTE byData[1024];
+ long lPrevCombinedEvent;
+ long lNextCombinedEvent;
+ long lInputOn;
+ long lInputPort;
+ long lInputChannel;
+ long lOutputOn;
+ long lOutputPort;
+ long lOutputChannel;
+ long lViewMode;
+ long lForeColor;
+ long lBackColor;
+ long lTimePlus;
+ long lKeyPlus;
+ long lVelocityPlus;
+ long lReserved1;
+ long lReserved2;
+ long lReserved3;
+ long lReserved4;
+ long lUser1;
+ long lUser2;
+ long lUser3;
+ long lUserFlag;
+ TCHAR szType[256];
+ long i = 0;
+ long j = 0;
+ long k = 0;
+ long ret = 0;
+ long lErrorNo = 0;
+ long lDeletedEventCount = 0;
+ long lInsertedEventCount = 0;
+ MIDITrack* pClipTrack = NULL;
+ MIDIEvent* pClipEvent = NULL;
+ MIDIData* pClipData = NULL;
+
+ // クリップボードの内容から新しいMIDIDataオブジェクトを作成
+ while (1) {
+ int n = strData.Find(_T('\n'));
+ if (n < 0) {
+ break;
+ }
+ strTextLine = strData.Left (n + 1);
+ strData = strData.Mid (n + 1);
+ // MDa2行の場合
+ if (strTextLine.Left (4) == _T("MDa2")) {
+ // 2回以上MDatが現れた場合
+ if (pClipData != NULL) {
+ break;
+ }
+ // MDat情報の読み取り
+ _stscanf (strTextLine, _T("%s %x %x %x %x %x %x %x %x\n"),
+ szType,
+ &lFormat,
+ &lNumTrack,
+ &lTimeBase,
+ &lReserved1,
+ &lReserved2,
+ &lReserved3,
+ &lReserved4,
+ &lUser1,
+ &lUser2,
+ &lUser3,
+ &lUserFlag);
+ if (lFormat < 0 || lFormat > 2) {
+ VERIFY (strMsg.LoadString (IDS_ABNORMAL_FORMAT_MIDIDATA_IN_THE_CLIPBOARD));
+ m_theCriticalSection.Unlock ();
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ m_theCriticalSection.Lock ();
+ return -1;
+ }
+ if (lTimeBase & 0x00008000) {
+ lTimeMode = 256 - ((lTimeBase & 0x0000FF00) >> 8);
+ lTimeResolution = lTimeBase & 0x000000FF;
+ }
+ else {
+ lTimeMode = MIDIDATA_TPQNBASE;
+ lTimeResolution = lTimeBase & 0x00007FFF;
+ }
+ if (lTimeMode != MIDIDATA_TPQNBASE &&
+ lTimeMode != MIDIDATA_SMPTE24BASE &&
+ lTimeMode != MIDIDATA_SMPTE25BASE &&
+ lTimeMode != MIDIDATA_SMPTE29BASE &&
+ lTimeMode != MIDIDATA_SMPTE30BASE) {
+ VERIFY (strMsg.LoadString (IDS_TIMEMODE_OF_CLIPBOARD_IS_ABNORMAL));
+ m_theCriticalSection.Unlock ();
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ m_theCriticalSection.Lock ();
+ return -1;
+ }
+ // MIDIDataの生成
+ pClipData = MIDIData_Create
+ (2, lNumTrack, lTimeMode, lTimeResolution);
+ if (pClipData == NULL) {
+ VERIFY (strMsg.LoadString (IDS_INSUFFICIENT_MEMORY));
+ m_theCriticalSection.Unlock ();
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ m_theCriticalSection.Lock ();
+ return -1;
+ }
+ }
+ // MTr2行の場合
+ else if (strTextLine.Left (4) == _T("MTr2")) {
+ _stscanf (strTextLine, _T("%s %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n"),
+ szType,
+ &lTrackIndex,
+ &lNumEvent,
+ &lInputOn,
+ &lInputPort,
+ &lInputChannel,
+ &lOutputOn,
+ &lOutputPort,
+ &lOutputChannel,
+ &lViewMode,
+ &lForeColor,
+ &lBackColor,
+ &lTimePlus,
+ &lKeyPlus,
+ &lVelocityPlus,
+ &lReserved1,
+ &lReserved2,
+ &lReserved3,
+ &lReserved4,
+ &lUser1,
+ &lUser2,
+ &lUser3,
+ &lUserFlag);
+ // 挿入トラックをpClipTrackに決定
+ long i = 0;
+ forEachTrack (pClipData, pClipTrack) {
+ if (i == lTrackIndex) {
+ break;
+ }
+ i++;
+ }
+ }
+ // MEvt行の場合
+ else if (strTextLine.Left (4) == _T("MEvt")) {
+ if (pClipTrack == NULL) {
+ break;
+ }
+ TCHAR* p = (TCHAR*)(LPCTSTR)strTextLine;
+ _stscanf (p, _T("%s %x %x %x %x"),
+ szType, &lEventIndex, &lTime, &lKind, &lLen);
+ memset (byData, 0, sizeof (byData));
+ for (k = 0; k < 5; k++) {
+ p = _tcschr (p, _T(' '));
+ if (p == NULL) {
+ break;
+ }
+ while (*p == _T(' ')) {
+ p++;
+ }
+ }
+ for (k = 0; k < lLen; k++) {
+ _stscanf (p, _T("%x"), &byData[k]);
+ p = _tcschr (p, ' ');
+ if (p == NULL) {
+ break;
+ }
+ while (*p == ' ') {
+ p++;
+ }
+ }
+
+ _stscanf (p, _T("%x %x %x %x %x %d\n"),
+ &lPrevCombinedEvent, &lNextCombinedEvent,
+ &lUser1, &lUser2, &lUser3, &lUserFlag);
+
+ // 新しいMIDIイベントの生成
+ pClipEvent = MIDIEvent_Create (lTime, lKind, byData, lLen);
+ if (pClipEvent == NULL) {
+ continue;
+ }
+ pClipEvent->m_lUserFlag |= MIDIEVENT_SELECTED;
+ pClipEvent->m_lTempIndex = lEventIndex;
+
+ // トラックにイベントを挿入
+ ret = MIDITrack_InsertEvent (pClipTrack, pClipEvent);
+ if (ret <= 0) {
+ MIDIEvent_Delete (pClipEvent);
+ continue;
+ }
+
+ // 結合イベントである場合の結合処理(1)
+ if (lPrevCombinedEvent != -1) {
+ MIDIEvent* pTempEvent;
+ forEachEvent (pClipTrack, pTempEvent) {
+ if (pTempEvent->m_lTempIndex == lPrevCombinedEvent) {
+ pClipEvent->m_pPrevCombinedEvent = pTempEvent;
+ pTempEvent->m_pNextCombinedEvent = pClipEvent;
+ break;
+ }
+ }
+ }
+
+ // 結合イベントである場合の結合処理(2)
+ if (lNextCombinedEvent != -1) {
+ MIDIEvent* pTempEvent;
+ forEachEvent (pClipTrack, pTempEvent) {
+ if (pTempEvent->m_lTempIndex == lNextCombinedEvent) {
+ pClipEvent->m_pNextCombinedEvent = pTempEvent;
+ pTempEvent->m_pPrevCombinedEvent = pClipEvent;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // 現在のMIDIデータのすべてのMIDIイベント選択解除
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pNewMIDIEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pNewLastEvent = NULL;
+ SelectNoObject (pHistoryUnit);
+
+ // 現在のMIDIデータにクリップボードMIDIデータをマージ
+ //long lCurTime = MIDIClock_GetTickCount (m_pMIDIClock);
+ long lNumClipTrack = MIDIData_CountTrack (pClipData);
+
+ // マージ用MIDIデータのフォーマットをこのMIDIデータのフォーマットに合わせる。
+ if(m_pMIDIData->m_lFormat== 0) {
+ MIDIData_SetFormat (pClipData, 0);
+ }
+
+ // マージ用MIDIデータのタイムベースをこのMIDIデータのタイムベースに合わせる。
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+ if (m_pMIDIData->m_lTimeBase != pClipData->m_lTimeBase) {
+ MIDIData_SetTimeBase (pClipData, lTimeMode, lTimeResolution);
+ }
+
+ // 必要な数だけトラックを追加する
+ if (MIDIData_GetFormat (m_pMIDIData) != 0) {
+ long lClipTrackCount = MIDIData_CountTrack (pClipData);
+ long lNeedTrackCount = lBeginTrackIndex + lClipTrackCount;
+ this->AddTrack (lNeedTrackCount, 0x0002, pHistoryUnit);
+ }
+
+ // すべてのトラックのEOTイベントの履歴記録
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ pNewLastEvent = this->ReplaceMIDIEvent (pLastEvent);
+ }
+ }
+ }
+
+ // マージ用MIDIデータからイベントを除去し、このMIDIデータに挿入
+ if (MIDIData_GetFormat (m_pMIDIData) == 0) {
+ pMIDITrack = MIDIData_GetFirstTrack (m_pMIDIData);
+ }
+ else {
+ pMIDITrack = GetTrack (lBeginTrackIndex);
+ }
+ forEachTrack (pClipData, pClipTrack) {
+ ASSERT (pMIDITrack);
+ pClipEvent = pClipTrack->m_pFirstEvent;
+ while (pClipEvent) {
+ ret = MIDITrack_RemoveEvent (pClipTrack, pClipEvent);
+ ret = MIDIEvent_SetTime (pClipEvent, pClipEvent->m_lTime + lBeginTime);
+ ret = MIDITrack_InsertEvent (pMIDITrack, pClipEvent);
+ if (ret > 0) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pClipEvent));
+ }
+ lInsertedEventCount += ret;
+ pClipEvent = pClipTrack->m_pFirstEvent;
+ }
+ pMIDITrack = pMIDITrack->m_pNextTrack;
+ }
+
+ // すべてのトラックのEOTイベントの履歴記録
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent);
+ }
+ }
+ }
+
+ // クリップMIDIデータの削除
+ MIDIData_Delete (pClipData);
+ pClipData = NULL;
+ return lInsertedEventCount;
+}
+
+// 選択されているイベントの削除
+BOOL CSekaijuDoc::DeleteSelectedEvent (CHistoryUnit* pHistoryUnit) {
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pPrevEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ // 削除するので後方から
+ pMIDIEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ while (pMIDIEvent) {
+ pPrevEvent = MIDIEvent_GetPrevEvent (pMIDIEvent);
+ // 選択されているならば
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // 結合イベントの途中でないならば
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ // 最後のEndofTrackイベントでないならば
+ if (!(MIDIEvent_IsEndofTrack (pMIDIEvent) &&
+ MIDIEvent_GetNextEvent (pMIDIEvent) == NULL)) {
+ pHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent);
+ MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent);
+ }
+ }
+ }
+ pMIDIEvent = pPrevEvent;
+ }
+ }
+ return TRUE;
+}
+
+// MIDIイベントを選択又は非選択状態にする。
+long CSekaijuDoc::SetEventSelected (MIDIEvent* pMIDIEvent, BOOL bSelected) {
+ ASSERT (pMIDIEvent);
+ ASSERT (bSelected == 0 || bSelected == 1);
+ long lCount = 0;
+ MIDIEvent* pTempEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ while (pTempEvent) {
+ if (bSelected) {
+ pTempEvent->m_lUserFlag |= MIDIEVENT_SELECTED;
+ }
+ else {
+ pTempEvent->m_lUserFlag &= ~MIDIEVENT_SELECTED;
+ }
+ pTempEvent = pTempEvent->m_pNextCombinedEvent;
+ lCount++;
+ }
+ return lCount;
+}
+
+// MIDIイベントが選択状態か調べる
+long CSekaijuDoc::IsEventSelected (MIDIEvent* pMIDIEvent) {
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ return pMIDIEvent->m_lUserFlag & MIDIEVENT_SELECTED ? 1 : 0;
+}
+
+// すべてのMIDIイベントを非選択状態にし、履歴に記録する。
+long CSekaijuDoc::SelectNoObject (CHistoryUnit* pHistoryUnit) {
+ long lCount = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ ASSERT (pHistoryUnit);
+
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ pCloneEvent = this->SelectEvent (pMIDIEvent, 0, pHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ lCount++;
+ }
+ }
+ }
+ }
+ _RPTF1 (_CRT_WARN, "SelectNoObject returns %d.\n", lCount);
+ return lCount;
+}
+
+// すべてのMIDIイベントを選択状態にし、履歴に記録する。
+long CSekaijuDoc::SelectAllObject (CHistoryUnit* pHistoryUnit) {
+ return 1; // TODO;
+}
+
+// 指定のMIDIイベントを選択状態又は非選択状態にし、履歴に記録する。
+// 選択状態が変化した場合、新しいMIDIイベントを返す。変化しなかった場合、NULLを返す。
+MIDIEvent* CSekaijuDoc::SelectEvent (MIDIEvent* pMIDIEvent, long bSelected,
+ CHistoryUnit* pHistoryUnit) {
+ ASSERT (pMIDIEvent);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ MIDIEvent* pCloneEvent = NULL;
+ MIDIEvent* pFirstCombinedEvent = NULL;
+ ASSERT (pHistoryUnit);
+ // 現状と異なる選択状態を指定をした場合のみ
+ if (this->IsEventSelected (pMIDIEvent) != bSelected) {// &&
+ //pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ VERIFY (pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent));
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pFirstCombinedEvent));
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pFirstCombinedEvent));
+ // 結合イベントを先頭から順に選択状態又は非選択状態にする。
+ MIDIEvent* pTempEvent = pCloneEvent;
+ while (pTempEvent) {
+ if (bSelected) {
+ pTempEvent->m_lUserFlag |= MIDIEVENT_SELECTED;
+ }
+ else {
+ pTempEvent->m_lUserFlag &= ~MIDIEVENT_SELECTED;
+ }
+ pTempEvent = pTempEvent->m_pNextCombinedEvent;
+ }
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ return pCloneEvent;
+ }
+ return NULL;
+}
+
+// MIDIトラックを選択状態又は非選択状態にし、履歴に記録する
+MIDITrack* CSekaijuDoc::SelectTrack (MIDITrack* pMIDITrack, long bSelected,
+ CHistoryUnit* pHistoryUnit) {
+ ASSERT (pMIDITrack);
+ ASSERT (pHistoryUnit);
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ // トラック内のすべてのイベントを選択状態又は非選択状態にする。
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ pCloneEvent = this->SelectEvent (pMIDIEvent, bSelected, pHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ return NULL;
+}
+
+// MIDIトラックが選択状態か調べる
+long CSekaijuDoc::IsTrackSelected (MIDITrack* pMIDITrack) {
+ ASSERT (pMIDITrack);
+ // トラック内のすべてのイベントが選択されていれば1、そうでなければ0を返す。
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if ((pMIDIEvent->m_lUserFlag & MIDIEVENT_SELECTED) == 0) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+// 指定トラックの指定小節を選択状態又は非選択状態にし、履歴に記録する
+long CSekaijuDoc::SelectTrackMeasure (MIDITrack* pMIDITrack, long lMeasure, long bSelected,
+ CHistoryUnit* pHistoryUnit) {
+ ASSERT (pMIDITrack);
+ MIDIEvent* pMIDIEvent;
+ MIDIEvent* pCloneEvent;
+ // 指定小節の開始タイムと終了タイムを計算
+ long lMinTime, lMaxTime;
+ MIDIData_MakeTime (m_pMIDIData, lMeasure, 0, 0, &lMinTime);
+ MIDIData_MakeTime (m_pMIDIData, lMeasure + 1, 0, 0, &lMaxTime);
+ ASSERT (pHistoryUnit);
+ // 指定トラックの指定小節内のすべてのMIDIイベントが選択状態又は非選択状態にする
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime < lMaxTime) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) { // 20081102:前小節からのノートオフは除外
+ pCloneEvent = this->SelectEvent (pMIDIEvent, bSelected, pHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+// 指定トラックの指定小節が選択状態か調べる(20100517動作仕様修正)
+long CSekaijuDoc::IsTrackMeasureSelected (MIDITrack* pMIDITrack, long lMeasure) {
+ ASSERT (pMIDITrack);
+ MIDIEvent* pMIDIEvent;
+ // 指定小節の開始タイムと終了タイムを計算
+ long lMinTime, lMaxTime;
+ MIDIData_MakeTime (m_pMIDIData, lMeasure, 0, 0, &lMinTime);
+ MIDIData_MakeTime (m_pMIDIData, lMeasure + 1, 0, 0, &lMaxTime);
+ long lEventNum = 0; // 20100517追加
+ long lSelectedEventNum = 0; // 20100517追加
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lMinTime <= lTime && lTime < lMaxTime) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) { // 20081102:前小節からのノートオフは除外
+ lEventNum++;
+ if ((pMIDIEvent->m_lUserFlag & MIDIEVENT_SELECTED) != 0) {
+ lSelectedEventNum++;
+ }
+ }
+ }
+ }
+ // イベントが存在しない場合は0を返す。
+ if (lEventNum == 0) {
+ return 0;
+ }
+ // 選択されているイベントが存在しない場合は1を返す。
+ if (lSelectedEventNum == 0) {
+ return 1;
+ }
+ // 一部のイベントが選択されている場合は2を返す。
+ else if (lEventNum > lSelectedEventNum) {
+ return 2;
+ }
+ // すべてのイベントが選択されている場合は3を返す。
+ else { // if (lEventNum == lSelectedEventNum) {
+ return 3;
+ }
+}
+
+
+// 指定インデックスのトラックを取得
+MIDITrack* CSekaijuDoc::GetTrack (long lIndex) {
+ ASSERT (0 <= lIndex && lIndex < MAXMIDITRACKNUM);
+ long i = 0;
+ MIDITrack* pMIDITrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (i == lIndex) {
+ return pMIDITrack;
+ }
+ i++;
+ }
+ return NULL;
+}
+
+// トラックにデフォルトのイベントを追加する。
+// lModeは以下の値をOR
+// 0001:トラックにトラック名イベントを挿入
+// 0002:トラックにEOTイベントを挿入
+// 0004:トラックにコントロールチェンジ・プログラムチェンジを挿入
+// 0008:トラックにテンポ・拍子記号・調性記号を挿入(すべてタイム0)
+long CSekaijuDoc::AddDefaultEventToTrack (MIDITrack* pMIDITrack, long lMode, CHistoryUnit* pHistoryUnit) {
+ ASSERT (pMIDITrack);
+ long lCurTrackCount = MIDIData_CountTrack (m_pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (m_pMIDIData);
+ long lChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ MIDIEvent* pNewEvent = NULL;
+ // トラック名イベントの挿入
+ if (lMode & 0x0001) {
+ VERIFY (pNewEvent = MIDIEvent_CreateTrackName (lTimeResolution * 0 / 120, _T("")));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ }
+ // テンポ・拍子記号・調性記号
+ if (lMode & 0x0008) {
+ VERIFY (pNewEvent = MIDIEvent_CreateTempo (0, 60000000 / 120));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateTimeSignature (0, 4, 2, 24, 8));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateKeySignature (0, 0, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ }
+ // コントロールチェンジ・プログラムチェンジの挿入
+ if (lMode & 0x0004 && 0 <= lChannel && lChannel <= 15) {
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 120 / 120, lChannel, 0, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 130 / 120, lChannel, 32, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateProgramChange (lTimeResolution * 140 / 120, lChannel, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 150 / 120, lChannel, 1, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 160 / 120, lChannel, 7, 100));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 170 / 120, lChannel, 10, 64));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 180 / 120, lChannel, 11, 127));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 190 / 120, lChannel, 64, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 200 / 120, lChannel, 91, 40));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 210 / 120, lChannel, 93, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ VERIFY (pNewEvent = MIDIEvent_CreateControlChange (lTimeResolution * 220 / 120, lChannel, 94, 0));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ }
+ // エンドオブトラックイベントの挿入
+ if (lMode & 0x0002) {
+ VERIFY (pNewEvent = MIDIEvent_CreateEndofTrack (lTimeResolution * 4));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ if (pHistoryUnit) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ }
+ return 1;
+}
+
+// 必要な数だけトラックを追加し、履歴に記録する。
+// lNeedTrackCountは最終的なトラックの総数。追加されたトラックの数を返す。
+// lModeは以下の値をOR
+// 0001:追加されたトラックにトラック名イベントを挿入
+// 0002:追加されたトラックにEOTイベントを挿入
+// 0004:追加されたトラックにコントロールチェンジ・プログラムチェンジを挿入
+// 0008:追加されたトラックにテンポ・拍子記号・調整記号を挿入(タイム0)
+long CSekaijuDoc::AddTrack (long lNeedTrackCount, long lMode, CHistoryUnit* pHistoryUnit) {
+ ASSERT (0 <= lNeedTrackCount && lNeedTrackCount < MAXMIDITRACKNUM);
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lFormat = MIDIData_GetFormat (m_pMIDIData);
+ // フォーマット1又はフォーマット2の場合以外はトラックを追加できない。
+ if (!(lFormat == 1 || lFormat == 2)) {
+ return 0;
+ }
+ long i = 0;
+ long lCount = 0;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ long lCurTrackCount = MIDIData_CountTrack (m_pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (m_pMIDIData);
+ long lMode2 = lMode;
+ for (i = lCurTrackCount; i < lNeedTrackCount; i++) {
+ VERIFY (pTempTrack = MIDITrack_Create ());
+ pTempTrack->m_lTempIndex = i;
+ MIDITrack_SetViewMode (pTempTrack, 0);
+ MIDITrack_SetForeColor (pTempTrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]);
+ MIDITrack_SetBackColor (pTempTrack, 0x00FFFFFF);
+ MIDITrack_SetInputOn (pTempTrack, 1);
+ MIDITrack_SetInputPort (pTempTrack, 0);
+ MIDITrack_SetInputChannel (pTempTrack, (i + 15) % 16);
+ MIDITrack_SetOutputOn (pTempTrack, 1);
+ MIDITrack_SetOutputPort (pTempTrack, 0);
+ MIDITrack_SetOutputChannel (pTempTrack, (i + 15) % 16);
+ VERIFY (MIDIData_AddTrack (m_pMIDIData, pTempTrack));
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pTempTrack));
+ // フォーマット1の場合lModeを調整
+ if (lFormat == 1 && i == 0) {
+ lMode2 = lMode & ~0x0004; // 最初のトラックにコントロールチェンジ・プログラムチェンジを禁止
+ }
+ else if (lFormat == 1 && i != 0) {
+ lMode2 = lMode & ~0x0008; // 2番目以降のトラックにテンポ・拍子記号・調性記号を禁止
+ }
+ VERIFY (this->AddDefaultEventToTrack (pTempTrack, lMode2, pHistoryUnit));
+ lCount++;
+ }
+ return lCount;
+}
+
+
+// トラックの名前取得
+CString CSekaijuDoc::GetTrackName (MIDITrack* pMIDITrack) {
+ TCHAR szBuf[1024];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDITrack_GetName (pMIDITrack, szBuf, TSIZEOF (szBuf) - 1);
+ return CString (szBuf);
+}
+
+// トラックの名前設定
+BOOL CSekaijuDoc::SetTrackName (MIDITrack* pMIDITrack, CString strTrackName) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+ MIDIEvent* pTempEvent = MIDITrack_GetFirstKindEvent (pMIDITrack, MIDIEVENT_TRACKNAME);
+ MIDIEvent* pCloneEvent = NULL;
+ // 既にトラック名イベントがある場合
+ if (pTempEvent) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent);
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pTempEvent));
+ VERIFY (MIDIEvent_SetText (pCloneEvent, (LPCTSTR)strTrackName));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ // このトラックにトラック名イベントがない場合
+ else {
+ VERIFY (pCloneEvent = MIDIEvent_CreateTrackName (0, strTrackName));
+ MIDITrack_InsertEvent (pMIDITrack, pCloneEvent);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ return MIDITrack_SetName (pMIDITrack, (LPCTSTR)strTrackName);
+}
+
+
+// トラックのインデックスを取得
+long CSekaijuDoc::GetTrackIndex (MIDITrack* pMIDITrack) {
+ ASSERT (pMIDITrack);
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ MIDITrack* pTempTrack;
+ long i = 0;
+ forEachTrack (m_pMIDIData, pTempTrack) {
+ if (pTempTrack == pMIDITrack) {
+ return i;
+ }
+ i++;
+ }
+ ASSERT (FALSE);
+ return -1;
+}
+
+
+// トラックの可視性取得
+long CSekaijuDoc::GetTrackVisible (MIDITrack* pMIDITrack) {
+ ASSERT (pMIDITrack);
+ return pMIDITrack->m_lUserFlag & MIDITRACK_VISIBLE ? 1 : 0;
+}
+
+// トラックの可視性設定
+BOOL CSekaijuDoc::SetTrackVisible (MIDITrack* pMIDITrack, long lVisible) {
+ ASSERT (pMIDITrack);
+ ASSERT (0 <= lVisible && lVisible <= 1);
+ if (lVisible) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_VISIBLE;
+ }
+ else {
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_VISIBLE;
+ }
+ return TRUE;
+}
+
+// トラックのイネーブルON/OFF取得
+long CSekaijuDoc::GetTrackEnable (MIDITrack* pMIDITrack) {
+ ASSERT (pMIDITrack);
+ return pMIDITrack->m_lUserFlag & MIDITRACK_ENABLE ? 1 : 0;
+}
+
+// トラックのイネーブルON/OFF設定
+BOOL CSekaijuDoc::SetTrackEnable (MIDITrack* pMIDITrack, long lEnable) {
+ ASSERT (pMIDITrack);
+ ASSERT (0 <= lEnable && lEnable <= 1);
+ if (lEnable) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ENABLE;
+ }
+ else {
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_ENABLE;
+ }
+ return TRUE;
+}
+
+// トラックの選択状態の取得
+long CSekaijuDoc::GetTrackSelected (MIDITrack* pMIDITrack) {
+ ASSERT (pMIDITrack);
+ return pMIDITrack->m_lUserFlag & MIDITRACK_SELECTED ? 1 : 0;
+}
+
+// トラックの選択状態の設定
+BOOL CSekaijuDoc::SetTrackSelected (MIDITrack* pMIDITrack, long lSelected) {
+ ASSERT (pMIDITrack);
+ ASSERT (0 <= lSelected && lSelected <= 1);
+ if (lSelected) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_SELECTED;
+ }
+ else {
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_SELECTED;
+ }
+ return TRUE;
+}
+
+
+// 最初のコントロールチェンジイベントの取得
+MIDIEvent* CSekaijuDoc::GetTrackFirstControlChange (MIDITrack* pMIDITrack, long lNumber) {
+ _ASSERT (pMIDITrack);
+ _ASSERT (0 <= lNumber && lNumber < 128);
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == lNumber) {
+ return pMIDIEvent;
+ }
+ }
+ }
+ return NULL;
+}
+
+// 最初のプログラムチェンジイベントの取得
+MIDIEvent* CSekaijuDoc::GetTrackFirstProgramChange (MIDITrack* pMIDITrack) {
+ ASSERT (pMIDITrack);
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ return pMIDIEvent;
+ }
+ }
+ return NULL;
+}
+
+MIDIEvent* CSekaijuDoc::FindBankMSB (MIDIEvent* pMIDIEvent) {
+ ASSERT (pMIDIEvent);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ if (lNumber == 32) {
+ while (pMIDIEvent) { // 20110508修正
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == 0) {
+ return pMIDIEvent;
+ }
+ }
+ pMIDIEvent = MIDIEvent_GetPrevEvent (pMIDIEvent); // 20110508追加
+ }
+ }
+ }
+ else if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ while (pMIDIEvent) { // 20110508修正
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == 0) {
+ return pMIDIEvent;
+ }
+ }
+ pMIDIEvent = MIDIEvent_GetPrevEvent (pMIDIEvent); // 20110508追加
+ }
+ }
+ return NULL;
+}
+
+MIDIEvent* CSekaijuDoc::FindBankLSB (MIDIEvent* pMIDIEvent) {
+ ASSERT (pMIDIEvent);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ if (lNumber == 0) {
+ while (pMIDIEvent) { // 20110508修正
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == 32) {
+ return pMIDIEvent;
+ }
+ }
+ pMIDIEvent = MIDIEvent_GetNextEvent (pMIDIEvent); // 20110508追加
+ }
+ }
+ }
+ else if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ while (pMIDIEvent) { // 20110508修正
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == 32) {
+ return pMIDIEvent;
+ }
+ }
+ pMIDIEvent = MIDIEvent_GetPrevEvent (pMIDIEvent); // 20110508追加
+ }
+ }
+ return NULL;
+}
+
+MIDIEvent* CSekaijuDoc::FindProgramChange (MIDIEvent* pMIDIEvent) {
+ ASSERT (pMIDIEvent);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lNumber = MIDIEvent_GetNumber (pMIDIEvent);
+ if (lNumber == 0 || lNumber == 32) {
+ while (pMIDIEvent) { // 20110508修正
+ if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ return pMIDIEvent;
+ }
+ pMIDIEvent = MIDIEvent_GetNextEvent (pMIDIEvent); // 20110508追加
+ }
+ }
+ }
+ return NULL;
+}
+
+// 指定トラックのlTimeにおけるlKeyの名称(例:"C#6")を取得 // 20090501追加
+CString CSekaijuDoc::GetKeyName (MIDITrack* pMIDITrack, long lTime, long lKey) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ // このトラックの表示モードは「通常」の場合
+ if (lTrackViewMode == 0) {
+ long lsf, lmi;
+ long lOctaveSignature = pSekaijuApp->m_theGeneralOption.m_lOctaveSignature;
+ MIDIData_FindKeySignature (m_pMIDIData, lTime, &lsf, &lmi);
+ long lIndex = (lsf & 0x0000000F) * 16 + (lKey % 12);
+ CString strKeyName;
+ strKeyName.Format (_T("%s%d"),
+ pSekaijuApp->m_strNoteKeyName[lIndex],
+ lKey / 12 + lOctaveSignature - 5);
+ return strKeyName;
+ }
+ // このトラックの表示モードは「ドラム」の場合
+ else {
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ MIDIInstrumentDefinition* pMIDIInstDef = pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort];
+ // このトラックの指定するポートのインストゥルメント定義が見つかった
+ if (pMIDIInstDef) {
+ long lTrackCC0, lTrackCC32, lTrackPC;
+ MIDIEvent* pCC0Event = GetTrackFirstControlChange (pMIDITrack, 0);
+ if (pCC0Event) {
+ lTrackCC0 = MIDIEvent_GetValue (pCC0Event);
+ }
+ else {
+ lTrackCC0 = 0;
+ }
+ MIDIEvent* pCC32Event = GetTrackFirstControlChange (pMIDITrack, 32);
+ if (pCC32Event) {
+ lTrackCC32 = MIDIEvent_GetValue (pCC32Event);
+ }
+ else {
+ lTrackCC32 = 0;
+ }
+ MIDIEvent* pPCEvent = GetTrackFirstProgramChange (pMIDITrack);
+ if (pPCEvent) {
+ lTrackPC = MIDIEvent_GetNumber (pPCEvent);
+ }
+ else {
+ lTrackPC = 0;
+ }
+ MIDINoteNameTable* pNoteNameTable =
+ MIDIInstrumentDefinition_GetNoteNameTable
+ (pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort],
+ (lTrackCC0 << 7) | (lTrackCC32), lTrackPC);
+ // このインストゥルメント定義は指定バンク/プログラムの
+ // NoteNameTableを持っている
+ if (pNoteNameTable) {
+ TCHAR szKeyName[256];
+ memset (szKeyName, 0, sizeof (szKeyName));
+ MIDINoteNameTable_GetName
+ (pNoteNameTable, lKey, szKeyName, TSIZEOF (szKeyName) - 1);
+ CString strKeyName (szKeyName);
+ return strKeyName;
+ }
+ // このインストゥルメント定義は指定バンク/プログラムの
+ // NoteNameTableを持っていない
+ else {
+ return _T("");
+ }
+ }
+ // このトラックの指定するポートのインストゥルメント定義が見つからなかった
+ else {
+ return _T("");
+ }
+ }
+}
+
+// タイムを時:分:秒:ミリ秒文字列に変換 // 20100502追加
+BOOL CSekaijuDoc::LongTimeToStringMillisec (MIDIData* pMIDIData, long lTime, CString* pstrText) {
+ long lMilliSec, lHour, lMinute, lSec, lMSec;
+ lMilliSec = MIDIData_TimeToMillisec (pMIDIData, lTime);
+ lHour = lMilliSec / 3600000;
+ lMinute = (lMilliSec % 3600000) / 60000;
+ lSec = (lMilliSec % 60000) / 1000;
+ lMSec = (lMilliSec % 1000);
+ pstrText->Format (_T("%02d:%02d:%02d:%03d"), lHour, lMinute, lSec, lMSec);
+ return TRUE;
+}
+
+// タイムを小節:拍:ティック 又は フレーム番号:ティック文字列に変換 // 20100502追加
+BOOL CSekaijuDoc::LongTimeToStringTime (MIDIData* pMIDIData, long lTime, CString* pstrText) {
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ // TPQNベースの場合(標準)…long→"小節:拍:ティック"
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ pstrText->Format (_T("%05d:%02d:%03d"), lMeasure + 1, lBeat + 1, lTick);
+ return TRUE;
+ }
+ // SMPTE24ベース、SMPTE25ベース、SMPTE29.97ベース、SMPTE30ベースの場合…long→"フレーム:サブフレーム"
+ else if (lTimeMode == MIDIDATA_SMPTE24BASE || lTimeMode == MIDIDATA_SMPTE25BASE ||
+ lTimeMode == MIDIDATA_SMPTE29BASE || lTimeMode == MIDIDATA_SMPTE30BASE) {
+ long lFrameNumber, lTick;
+ lFrameNumber = lTime / lTimeResolution;
+ lTick = lTime % lTimeResolution;
+ pstrText->Format (_T("%08d:%03d"), lFrameNumber, lTick);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// 小節:拍:ティック 又は フレーム番号:ティック文字列をタイムに変換 // 20100502追加
+// 戻り値:正常=0, 異常=エラーメッセージ文字列リソースID(1〜)
+long CSekaijuDoc::StringTimeToLongTime (MIDIData* pMIDIData, CString strText, long* pTime) {
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lTemp = 0;
+ CString strToken;
+ // TPQNベースの場合(標準)…"小節:拍:ティック"→long
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lMeasure, lBeat, lTick;
+ // 小節と拍の間のセパレータチェック
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ return IDS_A_SEPARATOR_BETWEEN_MEASURE_AND_BEAT_IS_NOT_FOUND;
+ }
+ // 小節文字チェック
+ strToken = strText.Left (lTemp);
+ if (IsNumeric (strToken) <= 0) {
+ return IDS_MEASURE_MUST_BE_HALF_WIDTH_NUMBER;
+ }
+ // 小節値チェック
+ lMeasure = _ttol (strToken) - 1;
+ if (lMeasure < 0 || lMeasure >= 65535) {
+ return IDS_MEASURE_VALUE_IS_OUT_OF_RANGE;
+ }
+ // 拍とティックの間のセパレータチェック
+ strText = strText.Mid (lTemp + 1);
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ return IDS_A_SEPARATOR_BETWEEN_BEAT_AND_TICK_IS_NOT_FOUND;
+ }
+ // 拍文字チェック
+ strToken = strText.Left (lTemp);
+ if (IsNumeric (strToken) <= 0) {
+ return IDS_BEAT_MUST_BE_HALF_WIDTH_NUMBER;
+ }
+ // 拍値チェック
+ lBeat = _ttol (strToken) - 1;
+ if (lBeat < 0 || lBeat >= 100) {
+ return IDS_BEAT_VALUE_IS_OUT_OF_RANGE;
+ }
+ // ティック文字チェック
+ strText = strText.Mid (lTemp + 1);
+ if (IsNumeric (strToken) <= 0) {
+ return IDS_TICK_MUST_BE_HALF_WIDTH_NUMBER;
+ }
+ // ティック値チェック
+ lTick = _ttol (strText);
+ if (lTick < 0 || lTick > 960) {
+ return IDS_TICK_VALUE_IS_OUT_OF_RANGE;
+ }
+ MIDIData_MakeTime (pMIDIData, lMeasure, lBeat, lTick, pTime);
+ *pTime = CLIP (0x00000000, *pTime, 0x7FFFFFFF);
+ return 0;
+ }
+ // SMPTE24ベース、SMPTE25ベース、SMPTE29.97ベース、SMPTE30ベースの場合…"フレーム:サブフレーム"→long
+ else if (lTimeMode == MIDIDATA_SMPTE24BASE || lTimeMode == MIDIDATA_SMPTE25BASE ||
+ lTimeMode == MIDIDATA_SMPTE29BASE || lTimeMode == MIDIDATA_SMPTE30BASE) {
+ long lFrame, lSubFrame;
+ // フレームとサブフレームの間のセパレータチェック
+ lTemp = strText.Find (_T(":"));
+ if (lTemp < 0) {
+ return IDS_A_SEPARATOR_BETWEEN_FRAME_AND_TICK_IS_NOT_FOUND;
+ }
+ // フレーム文字チェック
+ strToken = strText.Left (lTemp);
+ if (IsNumeric (strToken) <= 0) {
+ return IDS_FRAME_MUST_BE_HALF_WIDTH_NUMBER;
+ }
+ // フレーム値チェック
+ lFrame = _ttol (strToken);
+ if (lFrame < 0 || lFrame > 99999999) {
+ return IDS_FRAME_VALUE_IS_OUT_OF_RANGE;
+ }
+ // サブフレーム文字チェック
+ strText = strText.Mid (lTemp + 1);
+ if (IsNumeric (strToken) <= 0) {
+ return IDS_SUBFRAME_MUST_BE_HALF_WIDTH_NUMBER;
+ }
+ // サブフレーム値チェック
+ lSubFrame = _ttol (strText);
+ if (lSubFrame < 0 || lSubFrame > 960) {
+ return IDS_SUBFRAME_VALUE_IS_OUT_OF_RANGE;
+ }
+ *pTime = lFrame * lTimeResolution + lSubFrame;
+ *pTime = CLIP (0x00000000, *pTime, 0x7FFFFFFF);
+ return 0;
+ }
+ else {
+ return 0;
+ }
+}
+
+// 新規トラックリスト表示
+void CSekaijuDoc::ShowTrackListFrame () {
+ CSekaijuDocTemplate* pDocTemplate = (CSekaijuDocTemplate*)GetDocTemplate ();
+ CTrackListFrame* pTrackListFrame =
+ (CTrackListFrame*)(pDocTemplate->CreateTrackListFrame (this));
+ pDocTemplate->InitialUpdateFrame (pTrackListFrame, this);
+}
+
+// 新規ピアノロール表示
+void CSekaijuDoc::ShowPianoRollFrame () {
+ CSekaijuDocTemplate* pDocTemplate = (CSekaijuDocTemplate*)GetDocTemplate ();
+ CPianoRollFrame* pPianoRollFrame =
+ (CPianoRollFrame*)(pDocTemplate->CreatePianoRollFrame (this));
+ pDocTemplate->InitialUpdateFrame (pPianoRollFrame, this);
+
+}
+
+// 新規イベントリスト表示
+void CSekaijuDoc::ShowEventListFrame () {
+ CSekaijuDocTemplate* pDocTemplate = (CSekaijuDocTemplate*)GetDocTemplate ();
+ CEventListFrame* pEventListFrame =
+ (CEventListFrame*)(pDocTemplate->CreateEventListFrame (this));
+ pDocTemplate->InitialUpdateFrame (pEventListFrame, this);
+
+}
+
+// 新規譜面表示
+void CSekaijuDoc::ShowMusicalScoreFrame () {
+ CSekaijuDocTemplate* pDocTemplate = (CSekaijuDocTemplate*)GetDocTemplate ();
+ CMusicalScoreFrame* pMusicalScoreFrame =
+ (CMusicalScoreFrame*)(pDocTemplate->CreateMusicalScoreFrame (this));
+ pDocTemplate->InitialUpdateFrame (pMusicalScoreFrame, this);
+
+}
+
+
+
+
+
+// MIDIEventを同じMIDIイベントで置き換え、新しい方のMIDIイベントを返す。
+// MIDIEventのプロパティを変更する際には必ずこの関数を呼び出し、旧状態を保存する。
+// (1)pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent);
+// (2)pCloneEvent = ReplaceMIDIevent (pMIDITrack, pMIDIEvent);
+// (3)MIDIEvent_Set* (pCloneEvent, *);
+// (4)pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+MIDIEvent* CSekaijuDoc::ReplaceMIDIEvent (MIDIEvent* pMIDIEvent) {
+ long lCount = 0;
+ long lPosition = 0;
+ ASSERT (pMIDIEvent);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ MIDIEvent* pTargetEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ MIDIEvent* pCloneEvent = MIDIEvent_CreateClone (pMIDIEvent);
+ if (pCloneEvent == NULL) {
+ return NULL;
+ }
+ MIDIEvent* pInsertEvent = MIDIEvent_GetFirstCombinedEvent (pCloneEvent);
+ while (pTargetEvent && pInsertEvent) {
+ MIDIEvent* pTargetPrevEvent = pTargetEvent->m_pPrevEvent;
+ MIDIEvent* pTargetNextEvent = pTargetEvent->m_pNextEvent;
+ pInsertEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE; // フラグはAddHistoryRecord内で決定
+ pInsertEvent->m_lUserFlag &= ~MIDIEVENT_DEAD; // フラグはAddHistoryRecord内で決定
+ VERIFY (MIDITrack_RemoveSingleEvent (pMIDITrack, pTargetEvent));
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pInsertEvent, pTargetPrevEvent));
+ pTargetEvent = pTargetEvent->m_pNextCombinedEvent;
+ pInsertEvent = pInsertEvent->m_pNextCombinedEvent;
+ lCount++;
+ }
+ ASSERT (pTargetEvent == NULL && pInsertEvent == NULL);
+ return pCloneEvent;
+}
+
+// MIDIイベントの複製を行う。複製したイベントは複製元イベントの直後に挿入されている。
+// 注意:EOTなどを複製してもNULLが返る。
+MIDIEvent* CSekaijuDoc::DuplicateMIDIEvent (MIDIEvent* pMIDIEvent) {
+ ASSERT (pMIDIEvent);
+ MIDITrack* pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+ long lCount = 0;
+ long lRet = 0;
+ MIDIEvent* pTargetEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent);
+ MIDIEvent* pCloneEvent = MIDIEvent_CreateClone (pMIDIEvent);
+ if (pCloneEvent == NULL) {
+ return NULL;
+ }
+ MIDIEvent* pInsertEvent = pCloneEvent;
+ while (pTargetEvent && pInsertEvent) {
+ pInsertEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ pInsertEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ lRet = MIDITrack_InsertSingleEventAfter (pMIDITrack, pInsertEvent, pTargetEvent);
+ if (lRet == 0) {
+ MIDIEvent_Delete (pCloneEvent);
+ pCloneEvent = NULL;
+ return NULL;
+ }
+ pTargetEvent = pTargetEvent->m_pNextCombinedEvent;
+ pInsertEvent = pInsertEvent->m_pNextCombinedEvent;
+ lCount++;
+ }
+ ASSERT (pTargetEvent == NULL && pInsertEvent == NULL);
+ return pCloneEvent;
+}
+
+// MIDITrackオブジェクトを差し替え、新しいMIDITrackオブジェクトを返す。
+// 内部のMIDIEventオブジェクトは、新しいMIDITrackの所有物となる。
+MIDITrack* CSekaijuDoc::ReplaceMIDITrack (MIDITrack* pMIDITrack) {
+ ASSERT (pMIDITrack);
+ MIDIData* pMIDIData = MIDITrack_GetParent (pMIDITrack);
+ ASSERT (pMIDIData);
+ // イベント数0の空のMIDITrackを作成
+ MIDITrack* pCloneTrack = NULL;
+ pCloneTrack = MIDITrack_Create ();
+ if (pCloneTrack == NULL) {
+ return NULL;
+ }
+ pCloneTrack->m_lInputOn = pMIDITrack->m_lInputOn;
+ pCloneTrack->m_lInputPort = pMIDITrack->m_lInputPort;
+ pCloneTrack->m_lInputChannel = pMIDITrack->m_lInputChannel;
+ pCloneTrack->m_lOutputOn = pMIDITrack->m_lOutputOn;
+ pCloneTrack->m_lOutputPort = pMIDITrack->m_lOutputPort;
+ pCloneTrack->m_lOutputChannel = pMIDITrack->m_lOutputChannel;
+ pCloneTrack->m_lTimePlus = pMIDITrack->m_lTimePlus;
+ pCloneTrack->m_lKeyPlus = pMIDITrack->m_lKeyPlus;
+ pCloneTrack->m_lVelocityPlus = pMIDITrack->m_lVelocityPlus;
+ pCloneTrack->m_lViewMode = pMIDITrack->m_lViewMode;
+ pCloneTrack->m_lForeColor = pMIDITrack->m_lForeColor;
+ pCloneTrack->m_lBackColor = pMIDITrack->m_lBackColor;
+ pCloneTrack->m_lUser1 = pMIDITrack->m_lUser1;
+ pCloneTrack->m_lUser2 = pMIDITrack->m_lUser2;
+ pCloneTrack->m_lUser3 = pMIDITrack->m_lUser3;
+ pCloneTrack->m_lUserFlag = pMIDITrack->m_lUserFlag;
+ // 前のトラックと次のトラックを保持しておく(なければNULL)。
+ MIDITrack* pTargetPrevTrack = pMIDITrack->m_pPrevTrack;
+ MIDITrack* pTargetNextTrack = pMIDITrack->m_pNextTrack;
+ // 差し替え元MIDIトラック内のMIDIイベントをすべて差し替え先MIDIトラックに移動する。
+ MIDITrack_CountEvent (pMIDITrack);
+ MIDIEvent* pMIDIEvent = MIDITrack_GetFirstEvent (pMIDITrack);
+ while (pMIDIEvent) {
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent));
+ VERIFY (MIDITrack_InsertEvent (pCloneTrack, pMIDIEvent));
+ pMIDIEvent = MIDITrack_GetFirstEvent (pMIDITrack);
+ }
+ // MIDIデータから古いMIDITrackを除去、新しいMIDITrackを追加
+ VERIFY (MIDIData_RemoveTrack (pMIDIData, pMIDITrack));
+ VERIFY (MIDIData_InsertTrackAfter (pMIDIData, pCloneTrack, pTargetPrevTrack));
+ return pCloneTrack;
+}
+
+// MIDIDataオブジェクトを差し替え、新しいMIDIDataオブジェクトを返す。
+// 内部のMIDITrackオブジェクトは、新しいMIDIDataの所有物となる。
+MIDIData* CSekaijuDoc::ReplaceMIDIData (MIDIData* pMIDIData) {
+ ASSERT (pMIDIData);
+ // トラック数0の空のMIDIデータを作成
+ MIDIData* pCloneData = NULL;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ pCloneData = MIDIData_Create (lFormat, 0, lTimeMode, lTimeResolution);
+ if (pCloneData == NULL) {
+ return NULL;
+ }
+ pCloneData->m_lUser1 = pMIDIData->m_lUser1;
+ pCloneData->m_lUser2 = pMIDIData->m_lUser2;
+ pCloneData->m_lUser3 = pMIDIData->m_lUser3;
+ pCloneData->m_lUserFlag = pMIDIData->m_lUserFlag;
+ // 差し替え元MIDIデータ内のMIDIトラックをすべて差し替え先MIDIデータに移動する。
+ MIDIData_CountTrack (pMIDIData);
+ MIDITrack* pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ while (pMIDITrack) {
+ VERIFY (MIDIData_RemoveTrack (pMIDIData, pMIDITrack));
+ VERIFY (MIDIData_AddTrack (pCloneData, pMIDITrack));
+ pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ }
+ // 古いMIDIDataを除去、新しいMIDIDataを設定
+ this->m_pMIDIData = pCloneData;
+ return pCloneData;
+}
+
+// 新規履歴ユニットの追加(履歴ユニット名)
+BOOL CSekaijuDoc::AddHistoryUnit (CString strName) {
+ // 現在の履歴ユニット以降にある不要な履歴ユニットを削除
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ for (long i = lNumHistoryUnit - 1; i > m_lCurHistoryPosition; i--) {
+ CHistoryUnit* pHistoryUnit = (CHistoryUnit*)m_theHistoryUnitArray.GetAt (i);
+ m_theHistoryUnitArray.RemoveAt (i);
+ delete pHistoryUnit;
+ }
+ // 新規履歴ユニット作成
+ CHistoryUnit* pHistoryUnit = new CHistoryUnit ();
+ pHistoryUnit->m_strName = strName;
+ pHistoryUnit->m_theTime = CTime::GetCurrentTime ();
+ // 履歴ユニット配列に追加
+ m_theHistoryUnitArray.Add (pHistoryUnit);
+ // この履歴ユニットのインデックスを現在の履歴ユニットとする。
+ m_lCurHistoryPosition = m_theHistoryUnitArray.GetSize () - 1;
+
+ //for Debug
+ //FILE* pFile = fopen ("history.txt", "at");
+ //fprintf (pFile, "// AddHistoryUnit Index=%d, Name=%s, Time=%d\n", i+1, strName, pHistoryUnit->m_theTime);
+ //fclose (pFile);
+
+ return TRUE;
+}
+
+// 現在の履歴ユニットを取得する
+CHistoryUnit* CSekaijuDoc::GetCurHistoryUnit () {
+ // 現在の履歴ユニット番号はm_lCurHistoryPositionが保持している。
+ // この値は、「元に戻す」でデクリメント、「やり直し」でインクリメントする。
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ if (0 <= m_lCurHistoryPosition && m_lCurHistoryPosition < lNumHistoryUnit) {
+ return (CHistoryUnit*)m_theHistoryUnitArray.GetAt (m_lCurHistoryPosition);
+ }
+ ASSERT (FALSE);
+ return NULL;
+}
+
+// 履歴ユニットの完全消去
+BOOL CSekaijuDoc::DeleteAllHistoryUnit () {
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ for (long i = lNumHistoryUnit - 1; i >= 0; i--) {
+ CHistoryUnit* pHistoryUnit = (CHistoryUnit*)m_theHistoryUnitArray.GetAt (i);
+ m_theHistoryUnitArray.RemoveAt (i);
+ delete pHistoryUnit;
+ }
+ m_lCurHistoryPosition = -1;
+ return TRUE;
+}
+
+
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// 『ファイル(&F)』-『上書き保存(&S)』
+void CSekaijuDoc::OnUpdateFileSaveUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+}
+
+// 『ファイル(&F)』-『名前を付けて保存(&A)』
+void CSekaijuDoc::OnUpdateFileSaveAsUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+// 『ファイル(&F)』-『プロパティ(&R)』
+void CSekaijuDoc::OnFileProperty () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ // 20120107 '\t''\r''\n''\\'の混入に対応
+ CString strFormat;
+ CFilePropertyDlg theDlg;
+ TCHAR szBuf1[2048];
+ TCHAR szBuf2[2048];
+ memset (szBuf1, 0, sizeof (szBuf1));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ MIDIData_GetTitle (m_pMIDIData, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, TSIZEOF (szBuf2) - 1);
+ theDlg.m_strTitle = szBuf2;
+ memset (szBuf1, 0, sizeof (szBuf1));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ MIDIData_GetSubTitle (m_pMIDIData, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, TSIZEOF (szBuf2) - 1);
+ theDlg.m_strSubTitle = szBuf2;
+ memset (szBuf1, 0, sizeof (szBuf1));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ MIDIData_GetCopyright (m_pMIDIData, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, TSIZEOF (szBuf2) - 1);
+ theDlg.m_strCopyright = szBuf2;
+ memset (szBuf1, 0, sizeof (szBuf1));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ MIDIData_GetComment (m_pMIDIData, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, TSIZEOF (szBuf2) - 1);
+ theDlg.m_strComment1 = szBuf2;
+ long lNumTrack = MIDIData_CountTrack (m_pMIDIData);
+ theDlg.m_strNumTrack.Format (_T("%d"), lNumTrack);
+ long lNumEvent = 0;
+ MIDITrack* pMIDITrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ lNumEvent += MIDITrack_CountEvent (pMIDITrack);
+ }
+ theDlg.m_strNumEvent.Format (_T("%d"), lNumEvent);
+
+ long lSMFFormat = MIDIData_GetFormat (m_pMIDIData);
+ theDlg.m_nSMFFormat = (int)lSMFFormat;
+ long lTimeMode = MIDIData_GetTimeMode (m_pMIDIData);
+ switch (lTimeMode) {
+ case MIDIDATA_TPQNBASE:
+ theDlg.m_nTimeMode = 0;
+ break;
+ case MIDIDATA_SMPTE24BASE:
+ theDlg.m_nTimeMode = 1;
+ break;
+ case MIDIDATA_SMPTE25BASE:
+ theDlg.m_nTimeMode = 2;
+ break;
+ case MIDIDATA_SMPTE29BASE:
+ theDlg.m_nTimeMode = 3;
+ break;
+ case MIDIDATA_SMPTE30BASE:
+ theDlg.m_nTimeMode = 4;
+ break;
+ }
+ long lTimeResolution = MIDIData_GetTimeResolution (m_pMIDIData);
+ theDlg.m_nResolution = (int)lTimeResolution;
+
+ long lEndTime = MIDIData_GetEndTime (m_pMIDIData);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (m_pMIDIData, lEndTime, &lMeasure, &lBeat, &lTick);
+ VERIFY (strFormat.LoadString (IDS_05D_02D_03D_MEASURE_BEAT_TICK));
+ theDlg.m_strEndTime.Format (strFormat, lMeasure + 1, lBeat + 1, lTick);
+ }
+ else if (lTimeMode == MIDIDATA_SMPTE24BASE ||
+ lTimeMode == MIDIDATA_SMPTE25BASE ||
+ lTimeMode == MIDIDATA_SMPTE29BASE ||
+ lTimeMode == MIDIDATA_SMPTE30BASE) {
+ long lFrameNumber, lTick;
+ lFrameNumber = lEndTime / lTimeResolution;
+ lTick = lEndTime % lTimeResolution;
+ VERIFY (strFormat.LoadString (IDS_08D_03D_FRAME_TICK));
+ theDlg.m_strEndTime.Format (strFormat, lFrameNumber, lTick);
+ }
+ long lEndMillisec = MIDIData_TimeToMillisec (m_pMIDIData, lEndTime);
+ long lHour = (lEndMillisec / 3600000) % 3600000;
+ long lMinute = (lEndMillisec / 60000) % 60;
+ long lSec = (lEndMillisec / 1000) % 60;
+ long lMillisec = lEndMillisec % 1000;
+ VERIFY (strFormat.LoadString (IDS_02D_02D_02D_03D_HOUR_MINUTE_SECOND_MILLISEC));
+ theDlg.m_strEndMillisec.Format (strFormat, lHour, lMinute, lSec, lMillisec);
+
+
+
+ if (theDlg.DoModal () == IDOK) {
+
+ if (m_bEditLocked) {
+ return;
+ }
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIData* pCloneData = NULL;
+
+ // 新しい履歴ユニットの用意
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_FILE_MODIFY_PROPERTY));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ VERIFY (pMIDITrack = MIDIData_GetFirstTrack (m_pMIDIData));
+
+ // タイトル設定
+ // 最初のトラック名イベントを探索
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_GetKind (pTempEvent) == MIDIEVENT_TRACKNAME) {
+ break;
+ }
+ }
+ // 最初のトラック名イベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strTitle,
+ theDlg.m_strTitle.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ VERIFY (pTempEvent = MIDIEvent_CreateTrackName (0, szBuf2));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 最初のトラック名が見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pTempEvent));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strTitle,
+ theDlg.m_strTitle.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ MIDIEvent_SetText (pCloneEvent, szBuf2);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+
+ // サブタイトルの設定(空文字列時はサブタイトル削除)
+ // 2番目のトラック名イベントを探索
+ long lCount = 0;
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_GetKind (pTempEvent) == MIDIEVENT_TRACKNAME) {
+ if (lCount == 1) {
+ break;
+ }
+ lCount++;
+ }
+ }
+ // サブタイトルを設定する場合
+ if (theDlg.m_strSubTitle != _T("")) {
+ // 2番目のトラック名イベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strSubTitle,
+ theDlg.m_strSubTitle.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ VERIFY (pTempEvent = MIDIEvent_CreateTrackName (0, szBuf2));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 2番目のトラック名が見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pTempEvent));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strSubTitle,
+ theDlg.m_strSubTitle.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ MIDIEvent_SetText (pCloneEvent, szBuf2);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ }
+ // サブタイトルを削除する場合
+ else {
+ // 2番目のトラック名が見つかった場合
+ if (pTempEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pTempEvent));
+ }
+ }
+
+ // 著作権設定(空文字時は著作権イベント削除)
+ // 最初の著作権イベントを探索
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_GetKind (pTempEvent) == MIDIEVENT_COPYRIGHTNOTICE) {
+ break;
+ }
+ }
+ // 著作権を設定する場合
+ if (theDlg.m_strCopyright != _T("")) {
+ // 最初の著作権イベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strCopyright,
+ theDlg.m_strCopyright.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ VERIFY (pTempEvent = MIDIEvent_CreateCopyrightNotice (0, szBuf2));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 最初の著作権イベントが見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pTempEvent));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strCopyright,
+ theDlg.m_strCopyright.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ MIDIEvent_SetText (pCloneEvent, szBuf2);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ }
+ // 著作権を削除する場合
+ else {
+ // 最初の著作権イベントが見つかった場合
+ if (pTempEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pTempEvent));
+ }
+ }
+
+ // コメント1設定(空文字時は最初のテキストイベント削除)
+ // 最初のテキストイベントを探索
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_GetKind (pTempEvent) == MIDIEVENT_TEXTEVENT) {
+ break;
+ }
+ }
+ // コメント1を設定する場合
+ if (theDlg.m_strComment1 != _T("")) {
+ // 最初のテキストイベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strComment1,
+ theDlg.m_strComment1.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ VERIFY (pTempEvent = MIDIEvent_CreateTextEvent (0, szBuf2));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 最初のテキストイベントが見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pTempEvent));
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)theDlg.m_strComment1,
+ theDlg.m_strComment1.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ MIDIEvent_SetText (pCloneEvent, szBuf2);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ }
+ // コメント1を削除する場合
+ else {
+ // 最初のテキストイベントが見つかった場合
+ if (pTempEvent) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pTempEvent));
+ }
+ }
+
+ // 新しいSMFフォーマットを検出
+ long lNewSMFFormat = theDlg.m_nSMFFormat;
+ // SMFフォーマットが変更された場合
+ if (lNewSMFFormat != lSMFFormat) {
+ // 全オブジェクトの履歴記録(20090116履歴記録方法修正)
+ forEachTrackInverse (m_pMIDIData, pMIDITrack) {
+ if (MIDITrack_GetFirstEvent (pMIDITrack)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_REMOVEEVENTALL, MIDITrack_GetFirstEvent (pMIDITrack)));
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEDATA, m_pMIDIData));
+
+ // 全オブジェクトの交換
+ forEachTrackInverse (m_pMIDIData, pMIDITrack) {
+ forEachEventInverse (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pMIDIEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ pMIDITrack = pCloneTrack;
+ }
+ VERIFY (m_pMIDIData = this->ReplaceMIDIData (m_pMIDIData));
+
+ // フォーマット0/1/2変換
+ MIDIData_SetFormat (m_pMIDIData, lNewSMFFormat);
+ MIDIData_CountTrack (m_pMIDIData);
+ long i = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDITrack_SetForeColor (pMIDITrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]);
+ i++;
+ }
+
+ // 全オブジェクトの履歴記録(20090116履歴記録方法修正)
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTDATA, m_pMIDIData));
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pMIDITrack));
+ if (MIDITrack_GetFirstEvent (pMIDITrack)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENTALL,
+ MIDITrack_GetFirstEvent (pMIDITrack)));
+ }
+ }
+ }
+
+ // 新しいタイムモードと分解能を検出
+ long lNewTimeMode = 0;
+ switch (theDlg.m_nTimeMode) {
+ case 0:
+ lNewTimeMode = MIDIDATA_TPQNBASE;
+ break;
+ case 1:
+ lNewTimeMode = MIDIDATA_SMPTE24BASE;
+ break;
+ case 2:
+ lNewTimeMode = MIDIDATA_SMPTE25BASE;
+ break;
+ case 3:
+ lNewTimeMode = MIDIDATA_SMPTE29BASE;
+ break;
+ case 4:
+ lNewTimeMode = MIDIDATA_SMPTE30BASE;
+ break;
+ }
+ long lNewTimeResolution = theDlg.m_nResolution;
+ // タイムモード又は分解能が変更された場合
+ if (lNewTimeMode != lTimeMode ||
+ lNewTimeResolution != lTimeResolution) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 演奏中の場合、演奏の一時停止
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllHold1Off ();
+ pSekaijuApp->SendAllSostenutoOff ();
+ pSekaijuApp->SendAllHold2Off ();
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Stop (m_pMIDIClock);
+ }
+ long lTempo = MIDIEVENT_DEFTEMPO;
+ VERIFY (MIDIData_FindTempo (m_pMIDIData, 0, &lTempo));
+
+ // 全オブジェクトの履歴記録(20090116履歴記録方法修正)
+ forEachTrackInverse (m_pMIDIData, pMIDITrack) {
+ if (MIDITrack_GetFirstEvent (pMIDITrack)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_REMOVEEVENTALL, MIDITrack_GetFirstEvent (pMIDITrack)));
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEDATA, m_pMIDIData));
+
+ // 全オブジェクトの交換
+ forEachTrackInverse (m_pMIDIData, pMIDITrack) {
+ forEachEventInverse (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pMIDIEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ pMIDITrack = pCloneTrack;
+ }
+ VERIFY (m_pMIDIData = this->ReplaceMIDIData (m_pMIDIData));
+
+ // タイムベース(タイムモード及び分解能)の変換
+ MIDIData_SetTimeBase (m_pMIDIData, lNewTimeMode, lNewTimeResolution);
+
+ // 全オブジェクトの履歴記録(20090116履歴記録方法修正)
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTDATA, m_pMIDIData));
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pMIDITrack));
+ if (MIDITrack_GetFirstEvent (pMIDITrack)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord
+ (HISTORYRECORD_INSERTEVENTALL, MIDITrack_GetFirstEvent (pMIDITrack)));
+ }
+ }
+
+ // MIDIクロックのタイムモードと速度をアプリケーションに合わせる(20090625追加)
+ ApplyAppCurSpeedIndex ();
+
+ MIDIClock_Reset (m_pMIDIClock);
+ MIDIClock_SetTempo (m_pMIDIClock, lTempo);
+
+ // 演奏中だった場合、演奏の続行
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Start (m_pMIDIClock);
+ }
+ }
+ SetModifiedFlag (TRUE);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED | SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ }
+}
+
+// 『ファイル(&F)』-『プロパティ(&R)』
+void CSekaijuDoc::OnUpdateFilePropertyUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+}
+
+
+// 『編集(&E)』-『元に戻す(&U)』
+void CSekaijuDoc::OnEditUndo () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CString strMsg;
+ this->m_theCriticalSection.Lock ();
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ // 現在の履歴ユニットがない場合
+ if (m_lCurHistoryPosition <= -1) {
+ this->m_theCriticalSection.Unlock ();
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_UNDO_ANYMORE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ BeginWaitCursor ();
+ // 現在の履歴ユニットを取得
+ CHistoryUnit* pHistoryUnit =
+ (CHistoryUnit*)m_theHistoryUnitArray.GetAt (m_lCurHistoryPosition);
+ long lHistoryRecordCount = pHistoryUnit->m_theHistoryRecordArray.GetSize ();
+ long i;
+ MIDIData* pMIDIData = NULL;
+ MIDITrack* pPrevTrack = NULL;
+ MIDITrack* pNextTrack = NULL;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pPrevEvent = NULL;
+ MIDIEvent* pNextEvent = NULL;
+ MIDIEvent* pFirstEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pFirstTrack = NULL;
+ MIDITrack* pLastTrack = NULL;
+ MIDIData* pTempData = NULL;
+
+ // 履歴ユニット内にあるすべての記録について、後方から評価
+ for (i = lHistoryRecordCount - 1; i >= 0; i--) {
+ CHistoryRecord* pHistoryRecord =
+ (CHistoryRecord*)(pHistoryUnit->m_theHistoryRecordArray.GetAt (i));
+ switch (pHistoryRecord->m_lType) {
+ // MIDIEventオブジェクトの挿入記録→MIDIEventオブジェクトの排除
+ case HISTORYRECORD_INSERTEVENT:
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ VERIFY (MIDITrack_RemoveSingleEvent (pMIDITrack, pMIDIEvent));
+ break;
+ // MIDIEventオブジェクトの除去記録→MIDIEventオブジェクトの復元
+ case HISTORYRECORD_REMOVEEVENT:
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pFirstEvent = (MIDIEvent*)(pHistoryRecord->m_pFirstChild);
+ pLastEvent = (MIDIEvent*)(pHistoryRecord->m_pLastChild);
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ // 20090116 MIDIEventの挿入位置決定方法変更
+ if (pNextEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else if (MIDIEvent_GetParent (pNextEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else if (pPrevEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else if (MIDIEvent_GetParent (pPrevEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else {
+ long lInsertTime = MIDIEvent_GetTime (pMIDIEvent);
+ pTempEvent = pMIDITrack->m_pLastEvent;
+ // トラックの後方から挿入位置を探索
+ while (1) {
+ // トラックにデータがない、又はトラックの先頭入れてよい
+ if (pTempEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, NULL));
+ break;
+ }
+ // pTempEventの直後に入れてよい
+ else {
+ // 挿入するものがノートオフイベントの場合(ベロシティ0のノートオンを含む)
+ if (MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ // 対応するノートオンイベントより前には絶対に来れない (20090111追加)
+ if (pTempEvent == pMIDIEvent->m_pPrevCombinedEvent) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ // 同時刻のイベントがある場合は同時刻の他のノートオフの直後に挿入
+ else if (pTempEvent->m_lTime == lInsertTime && MIDIEvent_IsNoteOff (pTempEvent)) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ else if (pTempEvent->m_lTime < lInsertTime) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ }
+ // その他のイベントの場合
+ else {
+ if (pTempEvent->m_lTime <= lInsertTime) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ }
+ }
+ pTempEvent = pTempEvent->m_pPrevEvent;
+ }
+ }
+ break;
+ // MIDIEventオブジェクトの全挿入記録→全MIDIEventオブジェクトの排除
+ case HISTORYRECORD_INSERTEVENTALL:
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ VERIFY (MIDITrack_RemoveSingleEvent (pMIDITrack, pMIDIEvent));
+ break;
+ // MIDIEventオブジェクトの全除去記録→全MIDIEventオブジェクトの復元
+ case HISTORYRECORD_REMOVEEVENTALL:
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pFirstEvent = (MIDIEvent*)(pHistoryRecord->m_pFirstChild);
+ pLastEvent = (MIDIEvent*)(pHistoryRecord->m_pLastChild);
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ // 20090116 MIDIEventの挿入位置決定方法変更
+ if (pNextEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else if (MIDIEvent_GetParent (pNextEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else if (pPrevEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else if (MIDIEvent_GetParent (pPrevEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else {
+ ASSERT (FALSE);
+ }
+ break;
+ // MIDITrackオブジェクトの挿入記録→MIDITrackオブジェクトの排除
+ case HISTORYRECORD_INSERTTRACK:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pObject);
+ pPrevTrack = (MIDITrack*)(pHistoryRecord->m_pPrevObject);
+ pNextTrack = (MIDITrack*)(pHistoryRecord->m_pNextObject);
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pParent);
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag |= MIDITRACK_DEAD;
+ VERIFY (MIDIData_RemoveTrack (pMIDIData, pMIDITrack));
+ break;
+ // MIDITrackオブジェクトの除去記録→MIDITrackオブジェクトの復元
+ case HISTORYRECORD_REMOVETRACK:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pObject);
+ pPrevTrack = (MIDITrack*)(pHistoryRecord->m_pPrevObject);
+ pNextTrack = (MIDITrack*)(pHistoryRecord->m_pNextObject);
+ pFirstEvent = (MIDIEvent*)(pHistoryRecord->m_pFirstChild);
+ pLastEvent = (MIDIEvent*)(pHistoryRecord->m_pLastChild);
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pParent);
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ if (pFirstEvent || pLastEvent) {
+ VERIFY (pTempEvent = pFirstEvent);
+ pTempTrack = MIDIEvent_GetParent (pFirstEvent);
+ if (pTempTrack != NULL && pTempTrack != pMIDITrack) {
+ while (pTempEvent) {
+ VERIFY (MIDITrack_RemoveEvent (pTempTrack, pTempEvent));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ pTempEvent = MIDITrack_GetFirstEvent (pTempTrack);
+ }
+ }
+ }
+ // 20090116 MIDITrackの挿入位置決定方法変更
+ if (pNextTrack == NULL) {
+ VERIFY (MIDIData_InsertTrackBefore (pMIDIData, pMIDITrack, pNextTrack));
+ }
+ else if (MIDITrack_GetParent (pNextTrack) == pMIDIData) {
+ VERIFY (MIDIData_InsertTrackBefore (pMIDIData, pMIDITrack, pNextTrack));
+ }
+ else if (pPrevTrack == NULL) {
+ VERIFY (MIDIData_InsertTrackAfter (pMIDIData, pMIDITrack, pPrevTrack));
+ }
+ else if (MIDITrack_GetParent (pPrevTrack) == pMIDIData) {
+ VERIFY (MIDIData_InsertTrackAfter (pMIDIData, pMIDITrack, pPrevTrack));
+ }
+ else {
+ ASSERT (FALSE);
+ }
+ break;
+ // MIDIDataオブジェクトの挿入記録→MIDIDataオブジェクトの排除
+ case HISTORYRECORD_INSERTDATA:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pObject);
+ pMIDIData->m_lUserFlag &= ~MIDIDATA_ALIVE;
+ pMIDIData->m_lUserFlag |= MIDIDATA_DEAD;
+ this->m_pMIDIData = NULL;
+ break;
+ // MIDIDataオブジェクトの除去記録→MIDIDataオブジェクトの復元
+ case HISTORYRECORD_REMOVEDATA:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pObject);
+ pFirstTrack = (MIDITrack*)(pHistoryRecord->m_pFirstChild);
+ pLastTrack = (MIDITrack*)(pHistoryRecord->m_pLastChild);
+ pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ if (pFirstTrack || pLastTrack) {
+ VERIFY (pTempTrack = pFirstTrack);
+ pTempData = MIDITrack_GetParent (pFirstTrack);
+ if (pTempData != NULL && pTempData != pMIDIData) {
+ while (pTempTrack) {
+ VERIFY (MIDIData_RemoveTrack (pTempData, pTempTrack));
+ VERIFY (MIDIData_AddTrack (pMIDIData, pTempTrack));
+ pTempTrack = MIDIData_GetFirstTrack (pTempData);
+ }
+ }
+ }
+ this->m_pMIDIData = pMIDIData;
+ break;
+ }
+ }
+
+ // 必要に応じてMIDIClockの補正
+ long lMIDIClockTimeMode;
+ long lMIDIClockTimeResolution;
+ MIDIClock_GetTimeBase (m_pMIDIClock, &lMIDIClockTimeMode, &lMIDIClockTimeResolution);
+ long lMIDIDataTimeMode;
+ long lMIDIDataTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lMIDIDataTimeMode, &lMIDIDataTimeResolution);
+ if (lMIDIClockTimeMode != lMIDIDataTimeMode ||
+ lMIDIClockTimeResolution != lMIDIDataTimeResolution) {
+ // 演奏中の場合、演奏の一時停止
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllHold1Off ();
+ pSekaijuApp->SendAllSostenutoOff ();
+ pSekaijuApp->SendAllHold2Off ();
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Stop (m_pMIDIClock);
+ }
+ long lTempo = MIDIEVENT_DEFTEMPO;
+ VERIFY (MIDIData_FindTempo (m_pMIDIData, 0, &lTempo));
+ MIDIClock_Reset (m_pMIDIClock);
+ MIDIClock_SetTimeBase (m_pMIDIClock, lMIDIDataTimeMode, lMIDIDataTimeResolution);
+ MIDIClock_SetTempo (m_pMIDIClock, lTempo);
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Start (m_pMIDIClock);
+ }
+ }
+
+ // 現在の履歴ユニット番号をデクリメント
+ this->m_lCurHistoryPosition--;
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ this->SetModifiedFlag (TRUE);
+ this->m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ return;
+}
+
+// 『編集(&E)』-『元に戻す(&U)』
+void CSekaijuDoc::OnUpdateEditUndoUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ // 元に戻せない場合
+ if (m_lCurHistoryPosition <= -1) {
+ CString strText;
+ VERIFY (strText.LoadString (IDS_UNABLE_TO_UNDO_T_CTRL_Z));
+ pCmdUI->SetText (strText);
+ pCmdUI->Enable (FALSE);
+ }
+ // 元に戻せる場合
+ else {
+ CHistoryUnit* pHistoryUnit =
+ (CHistoryUnit*)m_theHistoryUnitArray.GetAt (m_lCurHistoryPosition);
+ CString strFormat;
+ CString strText;
+ VERIFY (strFormat.LoadString (IDS_UNDO_02D_02D_02D_S_T_CTRL_Z));
+ strText.Format (strFormat,
+ pHistoryUnit->m_theTime.GetHour (),
+ pHistoryUnit->m_theTime.GetMinute (),
+ pHistoryUnit->m_theTime.GetSecond (),
+ pHistoryUnit->m_strName);
+ pCmdUI->SetText (strText);
+ pCmdUI->Enable (TRUE);
+ }
+ m_theCriticalSection.Unlock ();
+}
+
+
+// 『編集(&E)』-『やり直し(&R)』
+void CSekaijuDoc::OnEditRedo () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ this->m_theCriticalSection.Lock ();
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ // 次の履歴ユニットがない場合
+ if (m_lCurHistoryPosition >= lNumHistoryUnit - 1) {
+ this->m_theCriticalSection.Unlock ();
+ CString strText;
+ VERIFY (strText.LoadString (IDS_UNABLE_TO_REDO_ANYMORE));
+ AfxMessageBox (strText, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ BeginWaitCursor ();
+ // 次の履歴ユニットを取得
+ CHistoryUnit* pHistoryUnit =
+ (CHistoryUnit*)m_theHistoryUnitArray.GetAt (m_lCurHistoryPosition + 1);
+
+ long lHistoryRecordCount = pHistoryUnit->m_theHistoryRecordArray.GetSize ();
+ long i;
+ MIDIData* pMIDIData = NULL;
+ MIDITrack* pPrevTrack = NULL;
+ MIDITrack* pNextTrack = NULL;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pPrevEvent = NULL;
+ MIDIEvent* pNextEvent = NULL;
+ MIDIEvent* pFirstEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pFirstTrack = NULL;
+ MIDITrack* pLastTrack = NULL;
+ MIDIData* pTempData = NULL;
+
+ // 履歴ユニット内にあるすべての記録について、前方から評価
+ for (i = 0; i < lHistoryRecordCount; i++) {
+ CHistoryRecord* pHistoryRecord =
+ (CHistoryRecord*)(pHistoryUnit->m_theHistoryRecordArray.GetAt (i));
+ switch (pHistoryRecord->m_lType) {
+ // MIDIEventオブジェクトの挿入記録→MIDIEventオブジェクトの復元
+ case HISTORYRECORD_INSERTEVENT:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ // 20090116 MIDIEventの挿入位置決定方法変更
+ if (pPrevEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else if (MIDIEvent_GetParent (pPrevEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else if (pNextEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else if (MIDIEvent_GetParent (pNextEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else {
+ long lInsertTime = MIDIEvent_GetTime (pMIDIEvent);
+ pTempEvent = pMIDITrack->m_pLastEvent;
+ // トラックの後方から挿入位置を探索
+ while (1) {
+ // トラックにデータがない、又はトラックの先頭入れてよい
+ if (pTempEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, NULL));
+ break;
+ }
+ // pTempEventの直後に入れてよい
+ else {
+ // 挿入するものがノートオフイベントの場合(ベロシティ0のノートオンを含む)
+ if (MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ // 対応するノートオンイベントより前には絶対に来れない (20090111追加)
+ if (pTempEvent == pMIDIEvent->m_pPrevCombinedEvent) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ // 同時刻のイベントがある場合は同時刻の他のノートオフの直後に挿入
+ else if (pTempEvent->m_lTime == lInsertTime && MIDIEvent_IsNoteOff (pTempEvent)) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ else if (pTempEvent->m_lTime < lInsertTime) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ }
+ // その他のイベントの場合
+ else {
+ if (pTempEvent->m_lTime <= lInsertTime) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pTempEvent));
+ break;
+ }
+ }
+ }
+ pTempEvent = pTempEvent->m_pPrevEvent;
+ }
+ }
+ //if (MIDIEvent_IsNoteOff (pMIDIEvent)) {
+ // if (pMIDIEvent->m_pPrevEvent) {
+ // if (pMIDIEvent->m_pPrevEvent->m_lTime == pMIDIEvent->m_lTime) {
+ // ASSERT (MIDIEvent_IsNoteOff (pMIDIEvent->m_pPrevEvent));
+ // }
+ // }
+ //}
+ break;
+ // MIDIEventオブジェクトの除去記録→MIDIEventオブジェクトの排除
+ case HISTORYRECORD_REMOVEEVENT:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ VERIFY (MIDITrack_RemoveSingleEvent (pMIDITrack, pMIDIEvent));
+ break;
+
+ // MIDIEventオブジェクトの全挿入記録→全MIDIEventオブジェクトの復元
+ case HISTORYRECORD_INSERTEVENTALL:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_DEAD;
+ // 20090116 MIDIEventの挿入位置決定方法変更
+ if (pPrevEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else if (MIDIEvent_GetParent (pPrevEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventAfter (pMIDITrack, pMIDIEvent, pPrevEvent));
+ }
+ else if (pNextEvent == NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else if (MIDIEvent_GetParent (pNextEvent) != NULL) {
+ VERIFY (MIDITrack_InsertSingleEventBefore (pMIDITrack, pMIDIEvent, pNextEvent));
+ }
+ else {
+ ASSERT (FALSE);
+ }
+ break;
+ // MIDIEventオブジェクトの全除去記録→全MIDIEventオブジェクトの排除
+ case HISTORYRECORD_REMOVEEVENTALL:
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pParent);
+ pMIDIEvent = (MIDIEvent*)(pHistoryRecord->m_pObject);
+ pPrevEvent = (MIDIEvent*)(pHistoryRecord->m_pPrevObject);
+ pNextEvent = (MIDIEvent*)(pHistoryRecord->m_pNextObject);
+ pMIDIEvent->m_lUserFlag &= ~MIDIEVENT_ALIVE;
+ pMIDIEvent->m_lUserFlag |= MIDIEVENT_DEAD;
+ VERIFY (MIDITrack_RemoveSingleEvent (pMIDITrack, pMIDIEvent));
+ break;
+
+ // MIDITrackオブジェクトの挿入記録→MIDITrackオブジェクトの復元
+ case HISTORYRECORD_INSERTTRACK:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pParent);
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pObject);
+ pPrevTrack = (MIDITrack*)(pHistoryRecord->m_pPrevObject);
+ pNextTrack = (MIDITrack*)(pHistoryRecord->m_pNextObject);
+ pFirstEvent = (MIDIEvent*)(pHistoryRecord->m_pFirstChild);
+ pLastEvent = (MIDIEvent*)(pHistoryRecord->m_pLastChild);
+ pMIDITrack->m_lUserFlag |= MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_DEAD;
+ if (pFirstEvent || pLastEvent) {
+ VERIFY (pTempEvent = pFirstEvent);
+ pTempTrack = MIDIEvent_GetParent (pFirstEvent);
+ if (pTempTrack != NULL && pTempTrack != pMIDITrack) {
+ while (pTempEvent) {
+ VERIFY (MIDITrack_RemoveEvent (pTempTrack, pTempEvent));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ pTempEvent = MIDITrack_GetFirstEvent (pTempTrack);
+ }
+ }
+ }
+ // 20090116 MIDITrackの挿入位置決定方法変更
+ if (pPrevTrack == NULL) {
+ VERIFY (MIDIData_InsertTrackAfter (pMIDIData, pMIDITrack, pPrevTrack));
+ }
+ else if (MIDITrack_GetParent (pPrevTrack) == pMIDIData) {
+ VERIFY (MIDIData_InsertTrackAfter (pMIDIData, pMIDITrack, pPrevTrack));
+ }
+ else if (pNextTrack == NULL) {
+ VERIFY (MIDIData_InsertTrackBefore (pMIDIData, pMIDITrack, pNextTrack));
+ }
+ else if (MIDITrack_GetParent (pNextTrack) == pMIDIData) {
+ VERIFY (MIDIData_InsertTrackBefore (pMIDIData, pMIDITrack, pNextTrack));
+ }
+ else {
+ ASSERT (FALSE);
+ }
+ break;
+ // MIDITrackオブジェクトの除去記録→MIDITrackオブジェクトの排除
+ case HISTORYRECORD_REMOVETRACK:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pParent);
+ pMIDITrack = (MIDITrack*)(pHistoryRecord->m_pObject);
+ pPrevTrack = (MIDITrack*)(pHistoryRecord->m_pPrevObject);
+ pNextTrack = (MIDITrack*)(pHistoryRecord->m_pNextObject);
+ pFirstEvent = (MIDIEvent*)(pHistoryRecord->m_pFirstChild);
+ pLastEvent = (MIDIEvent*)(pHistoryRecord->m_pLastChild);
+ pMIDITrack->m_lUserFlag &= ~MIDITRACK_ALIVE;
+ pMIDITrack->m_lUserFlag |= MIDITRACK_DEAD;
+ VERIFY (MIDIData_RemoveTrack (pMIDIData, pMIDITrack));
+ break;
+ // MIDIDataオブジェクトの挿入記録→MIDIDataオブジェクトの復元
+ case HISTORYRECORD_INSERTDATA:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pObject);
+ pFirstTrack = (MIDITrack*)(pHistoryRecord->m_pFirstChild);
+ pLastTrack = (MIDITrack*)(pHistoryRecord->m_pLastChild);
+ pMIDIData->m_lUserFlag |= MIDIDATA_ALIVE;
+ pMIDIData->m_lUserFlag &= ~MIDIDATA_DEAD;
+ if (pFirstTrack || pLastTrack) {
+ VERIFY (pTempTrack = pFirstTrack);
+ pTempData = MIDITrack_GetParent (pFirstTrack);
+ if (pTempData != NULL && pTempData != pMIDIData) {
+ while (pTempTrack) {
+ VERIFY (MIDIData_RemoveTrack (pTempData, pTempTrack));
+ VERIFY (MIDIData_AddTrack (pMIDIData, pTempTrack));
+ pTempTrack = MIDIData_GetFirstTrack (pTempData);
+ }
+ }
+ }
+ this->m_pMIDIData = pMIDIData;
+ break;
+ // MIDIDataオブジェクトの除去記録→MIDIDataオブジェクトの排除
+ case HISTORYRECORD_REMOVEDATA:
+ pMIDIData = (MIDIData*)(pHistoryRecord->m_pObject);
+ pFirstTrack = (MIDITrack*)(pHistoryRecord->m_pFirstChild);
+ pLastTrack = (MIDITrack*)(pHistoryRecord->m_pLastChild);
+ pMIDIData->m_lUserFlag &= ~MIDIDATA_ALIVE;
+ pMIDIData->m_lUserFlag |= MIDIDATA_DEAD;
+ this->m_pMIDIData = NULL;
+ break;
+ }
+ }
+
+ // 必要に応じてMIDIClockの補正
+ long lMIDIClockTimeMode;
+ long lMIDIClockTimeResolution;
+ MIDIClock_GetTimeBase (m_pMIDIClock, &lMIDIClockTimeMode, &lMIDIClockTimeResolution);
+ long lMIDIDataTimeMode;
+ long lMIDIDataTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lMIDIDataTimeMode, &lMIDIDataTimeResolution);
+ if (lMIDIClockTimeMode != lMIDIDataTimeMode ||
+ lMIDIClockTimeResolution != lMIDIDataTimeResolution) {
+ // 演奏中の場合、演奏の一時停止
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllHold1Off ();
+ pSekaijuApp->SendAllSostenutoOff ();
+ pSekaijuApp->SendAllHold2Off ();
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Stop (m_pMIDIClock);
+ }
+ long lTempo = MIDIEVENT_DEFTEMPO;
+ VERIFY (MIDIData_FindTempo (m_pMIDIData, 0, &lTempo));
+ MIDIClock_Reset (m_pMIDIClock);
+ MIDIClock_SetTimeBase (m_pMIDIClock, lMIDIDataTimeMode, lMIDIDataTimeResolution);
+ MIDIClock_SetTempo (m_pMIDIClock, lTempo);
+ if (pSekaijuApp->m_bPlaying) {
+ MIDIClock_Start (m_pMIDIClock);
+ }
+ }
+
+ // 現在の履歴ユニット番号をインクリメント
+ this->m_lCurHistoryPosition++;
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ this->SetModifiedFlag (TRUE);
+ this->m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ return;
+}
+
+// 『編集(&E)』-『やり直し(&R)』
+void CSekaijuDoc::OnUpdateEditRedoUI (CCmdUI* pCmdUI) {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ // やり直しできない場合
+ if (m_lCurHistoryPosition >= lNumHistoryUnit - 1) {
+ CString strText;
+ VERIFY (strText.LoadString (IDS_UNABLE_TO_REDO_T_CTRL_Y));
+ pCmdUI->SetText (strText);
+ pCmdUI->Enable (FALSE);
+ }
+ // やり直しできる場合
+ else {
+ CHistoryUnit* pHistoryUnit =
+ (CHistoryUnit*)m_theHistoryUnitArray.GetAt (m_lCurHistoryPosition + 1);
+ CString strFormat;
+ CString strText;
+ VERIFY (strFormat.LoadString (IDS_REDO_02D_02D_02D_S_T_CTRL_Y));
+ strText.Format (strFormat,
+ pHistoryUnit->m_theTime.GetHour (),
+ pHistoryUnit->m_theTime.GetMinute (),
+ pHistoryUnit->m_theTime.GetSecond (),
+ pHistoryUnit->m_strName);
+ pCmdUI->SetText (strText);
+ pCmdUI->Enable (TRUE);
+ }
+ m_theCriticalSection.Unlock ();
+}
+
+
+// 『編集(&E)』-『作業履歴の初期化』
+void CSekaijuDoc::OnEditInitHistory () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INITIALIZE_HISTORY));
+ int nRet = AfxMessageBox (strMsg, MB_ICONINFORMATION | MB_YESNO);
+
+ if (nRet == IDYES) {
+ BeginWaitCursor ();
+ this->m_theCriticalSection.Lock ();
+ this->DeleteAllHistoryUnit ();
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ this->SetModifiedFlag (TRUE);
+ this->m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ }
+
+}
+
+
+
+// 『編集(&E)』-『作業履歴の初期化』
+void CSekaijuDoc::OnUpdateEditInitHistoryUI (CCmdUI* pCmdUI) {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ long lNumHistoryUnit = m_theHistoryUnitArray.GetSize ();
+ if (lNumHistoryUnit <= 0) {
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+
+
+
+// 『編集(E)』-『切り取り(T)』
+void CSekaijuDoc::OnEditCut () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ long lRet = 0;
+ long lCopiedEventCount = 0;
+ BeginWaitCursor ();
+
+ // クリップボードに転送する文字列を作成
+ CString strText;
+ m_theCriticalSection.Lock ();
+ lCopiedEventCount = this->MakeCopyString (strText, 0x0000, NULL);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ if (lCopiedEventCount == 0) {
+ EndWaitCursor ();
+ return;
+ }
+
+ // クリップボードに独自テキストを転送
+ lRet = this->SetClipboardTextPrivate9 (strText);
+ if (lRet == FALSE) {
+ EndWaitCursor ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_WRITE_TO_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // 選択イベントを削除
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_CUT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+
+ this->DeleteSelectedEvent (pCurHistoryUnit);
+
+ SetModifiedFlag (TRUE);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+
+}
+
+// 『編集(E)』-『切り取り(T)』
+void CSekaijuDoc::OnUpdateEditCutUI (CCmdUI* pCmdUI) {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ if (this->IsTrackSelected (pMIDITrack)) {
+ lEnable = 1;
+ }
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+// 『編集(E)』-『コピー(C)』
+void CSekaijuDoc::OnEditCopy () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ long lRet = 0;
+ long lCopiedEventCount = 0;
+ BeginWaitCursor ();
+
+ // クリップボードに転送する文字列を作成
+ CString strText;
+ m_theCriticalSection.Lock ();
+ lCopiedEventCount = this->MakeCopyString (strText, 0x0000, NULL);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ if (lCopiedEventCount == 0) {
+ EndWaitCursor ();
+ return;
+ }
+
+ // クリップボードに独自テキストを転送
+ lRet = this->SetClipboardTextPrivate9 (strText);
+ if (lRet == FALSE) {
+ EndWaitCursor ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_WRITE_TO_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ EndWaitCursor ();
+}
+
+// 『編集(E)』-『コピー(C)』
+void CSekaijuDoc::OnUpdateEditCopyUI (CCmdUI* pCmdUI) {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // ひとつでもMIDIイベントが選択されていればEnable
+ // そうでなければDisableとする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+
+// 『編集(E)』-『貼り付け(P)』
+void CSekaijuDoc::OnEditPaste () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ BeginWaitCursor ();
+ CString strMsg;
+
+ // クリップボードのテキストを取得
+ CString strText;
+ long lRet = this->GetClipboardTextPrivate9 (strText);
+ if (lRet == FALSE) {
+ EndWaitCursor ();
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_READ_FROM_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // テキストフォーマット検査
+ if (strText.Left(5) != _T("MDa2 ")) {
+ EndWaitCursor ();
+ VERIFY (strMsg.LoadString (IDS_NO_AVAILABLE_MIDIDATA_IN_THE_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // 貼り付け処理
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_PASTE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ m_theCriticalSection.Lock ();
+ m_lTempTrackIndex = 0;
+ long lMeasure, lBeat, lTick;
+ long lTime = m_lNewTime;
+ MIDIData_BreakTime (m_pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ MIDIData_MakeTime (m_pMIDIData, lMeasure, 0, 0, &lTime);
+ m_lTempTime = lTime;
+ long lInsertedEventCount = this->ParsePasteString (strText, m_lTempTrackIndex, m_lTempTime, pCurHistoryUnit);
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+
+ // 結果のメッセージボックス表示
+ if (lInsertedEventCount == -1) {
+ VERIFY (strMsg.LoadString (IDS_PASTE_FAILED));
+ }
+ else {
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_MIDIEVENTS_WERE_INSERTED));
+ strMsg.Format (strFormat, lInsertedEventCount);
+ }
+ AfxMessageBox (strMsg, MB_ICONINFORMATION);
+}
+
+// 『編集(E)』-『貼り付け(P)』
+void CSekaijuDoc::OnUpdateEditPasteUI (CCmdUI* pCmdUI) {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+
+ // クリップボードの形式が独自テキストか調べる
+ pCmdUI->Enable (this->IsClipboardTextPrivate9 ());
+}
+
+// 『編集(E)』-『削除(D)』
+void CSekaijuDoc::OnEditDelete () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ BeginWaitCursor ();
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_DELETE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+
+ this->DeleteSelectedEvent (pCurHistoryUnit);
+
+ SetModifiedFlag (TRUE);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『削除(D)』
+void CSekaijuDoc::OnUpdateEditDeleteUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+
+ // MIDIイベントがひとつでも選択状態ならEnable
+ // そうでなければDisable
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+// 『編集(E)』-『すべて選択(A)』
+void CSekaijuDoc::OnEditSelectAll () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ // すべてのMIDIイベントを選択状態にする
+ BeginWaitCursor ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_SELECT_ALL));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ pCloneEvent = this->SelectEvent (pMIDIEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『すべて選択(A)』
+void CSekaijuDoc::OnUpdateEditSelectAllUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+
+ // すべてのイベントが選択されていればこの項目をチェックする
+ m_theCriticalSection.Lock ();
+ long lCheck = 1;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent) == 0) {
+ lCheck = 0;
+ break;
+ }
+ }
+ if (lCheck == 0) {
+ break;
+ }
+ }
+ pCmdUI->SetCheck (lCheck);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// 『編集(E)』-『すべて選択解除(N)』
+void CSekaijuDoc::OnEditSelectNone () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+
+ // すべてのMIDIイベントを非選択状態にする
+ BeginWaitCursor ();
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_DESELECT_ALL));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ this->SelectNoObject (pCurHistoryUnit);
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『すべて選択解除(N)』
+void CSekaijuDoc::OnUpdateEditSelectNoneUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をチェックする
+ m_theCriticalSection.Lock ();
+ long lCheck = 1;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent) != 0) {
+ lCheck = 0;
+ break;
+ }
+ }
+ if (lCheck == 0) {
+ break;
+ }
+ }
+ pCmdUI->SetCheck (lCheck);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// 『編集(E)』-『現在位置より前のイベントを追加選択』
+void CSekaijuDoc::OnEditSelectBefore () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ // 現在位置より前のイベントを選択状態にする
+ BeginWaitCursor ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_SELECT_BEFORE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime < m_lNewTime) {
+ pCloneEvent = this->SelectEvent (pMIDIEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『現在位置より前のイベントを追加選択』
+void CSekaijuDoc::OnUpdateEditSelectBeforeUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『編集(E)』-『現在位置より前のイベントを選択解除』
+void CSekaijuDoc::OnEditDeselectBefore () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ // 現在位置より前のイベントを選択解除にする
+ BeginWaitCursor ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_DESELECT_BEFORE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime < m_lNewTime) {
+ pCloneEvent = this->SelectEvent (pMIDIEvent, 0, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);}
+
+// 『編集(E)』-『現在位置より前のイベントを選択解除』
+void CSekaijuDoc::OnUpdateEditDeselectBeforeUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『編集(E)』-『現在位置より後のイベントを追加選択』
+void CSekaijuDoc::OnEditSelectAfter () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ // 現在位置より後のイベントを選択状態にする
+ BeginWaitCursor ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_SELECT_AFTER));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime >= m_lNewTime) {
+ pCloneEvent = this->SelectEvent (pMIDIEvent, 1, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『現在位置より後のイベントを追加選択』
+void CSekaijuDoc::OnUpdateEditSelectAfterUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『編集(E)』-『現在位置より後のイベントを選択解除』
+void CSekaijuDoc::OnEditDeselectAfter () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ // 現在位置より後のイベントを選択解除にする
+ BeginWaitCursor ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_DESELECT_AFTER));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime >= m_lNewTime) {
+ pCloneEvent = this->SelectEvent (pMIDIEvent, 0, pCurHistoryUnit);
+ if (pCloneEvent) {
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『現在位置より後のイベントを選択解除』
+void CSekaijuDoc::OnUpdateEditDeselectAfterUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『編集(E)』-『トラックの変更...』
+void CSekaijuDoc::OnEditTrack () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+
+ CEditTrackDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditTrackDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditTrackDlgStatus.m_nUnit, 1);
+ theDlg.m_nFitChannel = pSekaijuApp->m_theEditTrackDlgStatus.m_nFitChannel;
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ long i, j;
+ long lErrorCount = 0;
+ long lFormat = MIDIData_GetFormat (m_pMIDIData);
+ long lTrackCount = MIDIData_CountTrack (m_pMIDIData);
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_TRACKINDEX));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+
+ // 同じイベントを2回移動しないように、選択されているイベントを一時配列に登録する。
+ CPtrArray theTempSelectedEventArray;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // 非結合イベントのみ、結合イベントの場合は前非結合のみ、最後のEOTは除外
+ if (MIDIEvent_IsCombined (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL ||
+ !MIDIEvent_IsCombined (pMIDIEvent) &&
+ !(MIDIEvent_IsEndofTrack (pMIDIEvent) &&
+ MIDITrack_GetLastEvent (pMIDITrack) == pMIDIEvent)) {
+ theTempSelectedEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ }
+
+ // すべての移動可能な選択されているイベントについて
+ long lTempSelectedEventCount = theTempSelectedEventArray.GetSize ();
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ pMIDIEvent = (MIDIEvent*)(theTempSelectedEventArray.GetAt (j));
+ long lKind = MIDIEvent_GetKind (pMIDIEvent);
+ pMIDITrack = MIDIEvent_GetParent (pMIDIEvent);
+ ASSERT (pMIDITrack);
+
+ // 移動先トラックを計算
+ long lTargetTrackIndex = 0;
+ if (theDlg.m_nUnit == 0) {
+ lTargetTrackIndex = (theDlg.m_nAmount - (bTrackZeroOrigin ? 0 : 1));
+ }
+ else {
+ long lTrackIndex = GetTrackIndex (pMIDITrack);
+ lTargetTrackIndex = lTrackIndex + theDlg.m_nAmount;
+ }
+ lTargetTrackIndex = CLIP (0, lTargetTrackIndex, (MAXMIDITRACKNUM - 1));
+ MIDITrack* pTargetTrack = this->GetTrack (lTargetTrackIndex);
+
+ // 移動可能なイベントの場合のみ
+ if (lFormat == 1 && !MIDIEvent_IsMIDIEvent (pMIDIEvent) && lTargetTrackIndex == 0 ||
+ lFormat == 1 && (lKind & 0xF0) != 0x50 && lTargetTrackIndex != 0 ||
+ lFormat == 2) {
+
+ // トラックがない場合、トラックの追加及びEOTの追加
+ MIDITrack* pNewTrack = NULL;
+ MIDIEvent* pNewEvent = NULL;
+ long lTrackCount = MIDIData_CountTrack (m_pMIDIData);
+ for (i = lTrackCount; i <= lTargetTrackIndex; i++) {
+ VERIFY (pNewTrack = MIDITrack_Create ());
+ VERIFY (MIDITrack_SetForeColor (pNewTrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]));
+ VERIFY (MIDITrack_SetInputOn (pNewTrack, TRUE));
+ VERIFY (MIDITrack_SetInputChannel (pNewTrack, (i + 15) % 16));
+ VERIFY (MIDITrack_SetOutputOn (pNewTrack, TRUE));
+ VERIFY (MIDITrack_SetOutputChannel (pNewTrack, (i + 15) % 16));
+ VERIFY (MIDIData_AddTrack (m_pMIDIData, pNewTrack));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pNewTrack));
+ VERIFY (pNewEvent = MIDIEvent_CreateEndofTrack (lTimeResolution * 4));
+ VERIFY (MIDITrack_InsertEvent (pNewTrack, pNewEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ if (pNewEvent) {
+ VERIFY (this->SelectEvent (pNewEvent, TRUE, pCurHistoryUnit));
+ }
+
+ // 現在トラックから除去し移動先トラックに挿入
+ VERIFY (pTargetTrack = this->GetTrack (lTargetTrackIndex));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = this->ReplaceMIDIEvent (pMIDIEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pCloneEvent));
+ VERIFY (MIDITrack_InsertEvent (pTargetTrack, pCloneEvent));
+ if (theDlg.m_nFitChannel) {
+ long lOutputChannel = MIDITrack_GetOutputChannel (pTargetTrack);
+ if (0 <= lOutputChannel && lOutputChannel < 16 &&
+ MIDIEvent_IsMIDIEvent (pCloneEvent)) {
+ MIDIEvent_SetChannel (pCloneEvent, lOutputChannel);
+ }
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ // 注意: EndofTrackイベントはRemoveすることはできるが,二重にInsertすることはできない。
+ // TODO: EndofTrackイベントの親トラックがなくなってしまうバグがまだあり。
+ }
+ else {
+ lErrorCount++;
+ }
+ }
+
+ theTempSelectedEventArray.RemoveAll ();
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ if (lErrorCount > 0) {
+ CString strMsg;
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_MIDIEVENTS_TRACKINDEX_ISNT_CHANGED));
+ strMsg.Format (strFormat, lErrorCount);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ }
+ pSekaijuApp->m_theEditTrackDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditTrackDlgStatus.m_nUnit = theDlg.m_nUnit;
+ pSekaijuApp->m_theEditTrackDlgStatus.m_nFitChannel = theDlg.m_nFitChannel;
+ }
+
+}
+
+// 『編集(E)』-『トラックの変更...』
+void CSekaijuDoc::OnUpdateEditTrackUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ long lFormat = MIDIData_GetFormat (m_pMIDIData);
+ if (lFormat == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ else {
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ }
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+
+// 『編集(E)』-『タイムの変更...』
+void CSekaijuDoc::OnEditTime () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+
+ // TPQNベース
+ if (lTimeMode == 0) {
+ CEditTimeDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditTimeDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditTimeDlgStatus.m_nUnit, 4);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_TIME));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+
+ // 選択されているイベントのうち、最初のイベントの時刻を求める
+ long lFirstTime = 0x7FFFFFFF;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime < lFirstTime) {
+ lFirstTime = lTime;
+ break;
+ }
+ }
+ }
+ }
+ long lnn, ldd, lbb, lcc;
+ MIDIData_FindTimeSignature (m_pMIDIData, lFirstTime, &lnn, &ldd, &lbb, &lcc);
+ // 同じイベントを2回移動しないように、選択されているイベントを一時配列に登録する。
+ CPtrArray theTempSelectedEventArray;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUser1 = 0;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // 非結合イベントのみ、結合イベントの場合は前非結合のみ
+ if (MIDIEvent_IsCombined (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL ||
+ !MIDIEvent_IsCombined (pMIDIEvent)) {
+ theTempSelectedEventArray.Add (pMIDIEvent);
+ pMIDITrack->m_lUser1++;
+ }
+ }
+ }
+ }
+ // EOTの履歴保持(EOTが選択されていない場合のみ)(20081102修正)
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent && pMIDITrack->m_lUser1 > 0) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent) && !this->IsEventSelected (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+ // 時刻の変更
+ // 一時配列のイベント1個につき1回の移動をかける。
+ long lTempSelectedEventArrayCount = theTempSelectedEventArray.GetSize ();
+ if (theDlg.m_nAmount < 0) {
+ // (EOTを最後に移動させるため、昇順に)(20081102修正)
+ for (long j = 0; j < lTempSelectedEventArrayCount; j++) {
+ pMIDIEvent = (MIDIEvent*)(theTempSelectedEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ if (theDlg.m_nUnit == 0) {
+ lTime += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lTime += theDlg.m_nAmount * lTimeResolution * 4 / (1 << ldd); // (20081110計算式修正)
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lTime += theDlg.m_nAmount * lTimeResolution * 4 * lnn / (1 << ldd);
+ }
+ else if (theDlg.m_nUnit == 3) {
+ lTime = lFirstTime + (lTime - lFirstTime) * theDlg.m_nAmount / 100;
+ // ノートオフに結合したノートオンイベントの場合は、音長さも変更する
+ if (MIDIEvent_IsNoteOn (pCloneEvent) && MIDIEvent_IsCombined (pCloneEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pCloneEvent);
+ lDuration = lDuration * theDlg.m_nAmount / 100;
+ lDuration = CLIP (1, lDuration, 65535);
+ MIDIEvent_SetDuration (pCloneEvent, lDuration);
+ }
+ }
+ else if (theDlg.m_nUnit == 4) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lTime += (lDelta - abs (theDlg.m_nAmount));
+ }
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ else {
+ // (EOTを最初に移動させるため、逆順に)(20081102修正)
+ for (long j = lTempSelectedEventArrayCount - 1; j >= 0; j--) {
+ pMIDIEvent = (MIDIEvent*)(theTempSelectedEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ if (theDlg.m_nUnit == 0) {
+ lTime += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lTime += theDlg.m_nAmount * lTimeResolution * 4 / (1 << ldd); // (20081110計算式修正)
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lTime += theDlg.m_nAmount * lTimeResolution * 4 * lnn / (1 << ldd);
+ }
+ else if (theDlg.m_nUnit == 3) {
+ lTime = lFirstTime + (lTime - lFirstTime) * theDlg.m_nAmount / 100;
+ // ノートオフに結合したノートオンイベントの場合は、音長さも変更する
+ if (MIDIEvent_IsNoteOn (pCloneEvent) && MIDIEvent_IsCombined (pCloneEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pCloneEvent);
+ lDuration = lDuration * theDlg.m_nAmount / 100;
+ lDuration = CLIP (1, lDuration, 65535);
+ MIDIEvent_SetDuration (pCloneEvent, lDuration);
+ }
+ }
+ else if (theDlg.m_nUnit == 4) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lTime += (lDelta - abs (theDlg.m_nAmount));
+ }
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ theTempSelectedEventArray.RemoveAll ();
+ // EOTの履歴保持(EOTが選択されていない場合のみ)(20081102修正)
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent && pMIDITrack->m_lUser1 > 0) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent) && !this->IsEventSelected (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ pMIDITrack->m_lUser1 = 0;
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditTimeDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditTimeDlgStatus.m_nUnit = theDlg.m_nUnit;
+ }
+ }
+
+ // SMPTEベース
+ else {
+ CEditTimeSmpDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditTimeSmpDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditTimeSmpDlgStatus.m_nUnit, 3);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_TIME));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+
+ // 選択されているイベントのうち、最初のイベントの時刻を求める
+ long lFirstTime = 0x7FFFFFFF;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime < lFirstTime) {
+ lFirstTime = lTime;
+ break;
+ }
+ }
+ }
+ }
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+ long lnn, ldd, lbb, lcc;
+ MIDIData_FindTimeSignature (m_pMIDIData, lFirstTime, &lnn, &ldd, &lbb, &lcc);
+ // 同じイベントを2回移動しないように、選択されているイベントを一時配列に登録する。
+ CPtrArray theTempSelectedEventArray;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUser1 = 0;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // 非結合イベントのみ、結合イベントの場合は前非結合のみ
+ if (MIDIEvent_IsCombined (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL ||
+ !MIDIEvent_IsCombined (pMIDIEvent)) {
+ theTempSelectedEventArray.Add (pMIDIEvent);
+ pMIDITrack->m_lUser1++;
+ }
+ }
+ }
+ }
+ // EOTの履歴保持(EOTが選択されていない場合のみ)(20081102修正)
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent && pMIDITrack->m_lUser1 > 0) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent) && !this->IsEventSelected (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+ // 一時配列のイベント1個につき1回の移動をかける。
+ long lTempSelectedEventArrayCount = theTempSelectedEventArray.GetSize ();
+ if (theDlg.m_nAmount < 0) {
+ // (EOTを最後に移動させるため、昇順に)(20081102修正)
+ for (long j = 0; j < lTempSelectedEventArrayCount; j++) {
+ pMIDIEvent = (MIDIEvent*)(theTempSelectedEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ if (theDlg.m_nUnit == 0) {
+ lTime += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lTime += theDlg.m_nAmount * lTimeResolution;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lTime = lFirstTime + (lTime - lFirstTime) * theDlg.m_nAmount / 100;
+ // ノートオフに結合したノートオンイベントの場合は、音長さも変更する
+ if (MIDIEvent_IsNoteOn (pCloneEvent) && MIDIEvent_IsCombined (pCloneEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pCloneEvent);
+ lDuration = lDuration * theDlg.m_nAmount / 100;
+ lDuration = CLIP (1, lDuration, 65535);
+ MIDIEvent_SetDuration (pCloneEvent, lDuration);
+ }
+ }
+ else if (theDlg.m_nUnit == 3) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lTime += (lDelta - abs (theDlg.m_nAmount));
+ }
+ else if (theDlg.m_nUnit == 4) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lTime += (lDelta - abs (theDlg.m_nAmount)) * lTimeResolution;
+ }
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ else {
+ // (EOTを最初に移動させるため、逆順に)(20081102修正)
+ for (long j = lTempSelectedEventArrayCount - 1; j >= 0; j--) {
+ pMIDIEvent = (MIDIEvent*)(theTempSelectedEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ if (theDlg.m_nUnit == 0) {
+ lTime += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lTime += theDlg.m_nAmount * lTimeResolution;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lTime = lFirstTime + (lTime - lFirstTime) * theDlg.m_nAmount / 100;
+ // ノートオフに結合したノートオンイベントの場合は、音長さも変更する
+ if (MIDIEvent_IsNoteOn (pCloneEvent) && MIDIEvent_IsCombined (pCloneEvent)) {
+ long lDuration = MIDIEvent_GetDuration (pCloneEvent);
+ lDuration = lDuration * theDlg.m_nAmount / 100;
+ lDuration = CLIP (1, lDuration, 65535);
+ MIDIEvent_SetDuration (pCloneEvent, lDuration);
+ }
+ }
+ else if (theDlg.m_nUnit == 3) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lTime += (lDelta - abs (theDlg.m_nAmount));
+ }
+ else if (theDlg.m_nUnit == 4) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lTime += (lDelta - abs (theDlg.m_nAmount)) * lTimeResolution;
+ }
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ theTempSelectedEventArray.RemoveAll ();
+ // EOTの履歴保持(EOTが選択されていない場合のみ)(20081102修正)
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent && pMIDITrack->m_lUser1 > 0) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent) && !this->IsEventSelected (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ pMIDITrack->m_lUser1 = 0;
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditTimeSmpDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditTimeSmpDlgStatus.m_nUnit = theDlg.m_nUnit;
+ }
+ }
+}
+
+// 『編集(E)』-『タイムの変更...』
+void CSekaijuDoc::OnUpdateEditTimeUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『チャンネルの変更...』
+void CSekaijuDoc::OnEditChannel () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CEditChannelDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditChannelDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditChannelDlgStatus.m_nUnit, 2);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ long lTrackOutputChannel = 0;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_CHANNEL));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ // チャンネルの変更
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // MIDIチャンネルイベント
+ // (ノートオフ・ノートオン・キーアフター・コントロールチェンジ・
+ // プログラムチェンジ・チャンネルアフター・ピッチベンド)のみ
+ if (MIDIEvent_IsMIDIEvent (pMIDIEvent) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lChannel = MIDIEvent_GetChannel (pCloneEvent);
+ if (theDlg.m_nUnit == 0) {
+ if (0 <= lTrackOutputChannel && lTrackOutputChannel < 16) {
+ lChannel = lTrackOutputChannel;
+ }
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lChannel = theDlg.m_nAmount - 1;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lChannel += theDlg.m_nAmount;
+ }
+ lChannel = CLIP (0, lChannel, 15);
+ VERIFY (MIDIEvent_SetChannel (pCloneEvent, lChannel));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditChannelDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditChannelDlgStatus.m_nUnit = theDlg.m_nUnit;
+ }
+}
+
+// 『編集(E)』-『チャンネルの変更...』
+void CSekaijuDoc::OnUpdateEditChannelUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『音程の変更...』
+void CSekaijuDoc::OnEditKey () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CEditKeyDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditKeyDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditKeyDlgStatus.m_nUnit, 2);
+ theDlg.m_nTargetNote = CLIP (0, pSekaijuApp->m_theEditKeyDlgStatus.m_nTargetNote, 1);
+ theDlg.m_nTargetKeyAfter = CLIP (0, pSekaijuApp->m_theEditKeyDlgStatus.m_nTargetKeyAfter, 1);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_KEY));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ // 音程の変更
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // ノートオン・ノートオフ(非結合)・キーアフタータッチのみ
+ if ((MIDIEvent_IsNoteOn (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL ||
+ MIDIEvent_IsNoteOff (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL) &&
+ theDlg.m_nTargetNote == 1 ||
+ MIDIEvent_IsKeyAftertouch (pMIDIEvent) &&
+ theDlg.m_nTargetKeyAfter == 1) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lKey = MIDIEvent_GetKey (pCloneEvent);
+ if (theDlg.m_nUnit == 0) {
+ lKey += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lKey += theDlg.m_nAmount * 12;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lKey += (lDelta - abs (theDlg.m_nAmount));
+ }
+ else if (theDlg.m_nUnit == 3) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lKey += (lDelta - abs (theDlg.m_nAmount)) * 12;
+ }
+ lKey = CLIP (0, lKey, 127);
+ VERIFY (MIDIEvent_SetKey (pCloneEvent, lKey));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditKeyDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditKeyDlgStatus.m_nUnit = theDlg.m_nUnit;
+ pSekaijuApp->m_theEditKeyDlgStatus.m_nTargetNote = theDlg.m_nTargetNote;
+ pSekaijuApp->m_theEditKeyDlgStatus.m_nTargetKeyAfter = theDlg.m_nTargetKeyAfter;
+ }
+}
+
+// 『編集(E)』-『音程の変更...』
+void CSekaijuDoc::OnUpdateEditKeyUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// 『編集(E)』-『ベロシティの変更...』
+void CSekaijuDoc::OnEditVelocity () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CEditVelocityDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditVelocityDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditVelocityDlgStatus.m_nUnit, 3);
+ theDlg.m_nTargetNoteOn = CLIP (0, pSekaijuApp->m_theEditVelocityDlgStatus.m_nTargetNoteOn, 1);
+ theDlg.m_nTargetNoteOff = CLIP (0, pSekaijuApp->m_theEditVelocityDlgStatus.m_nTargetNoteOff, 1);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_VELOCITY));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ // ベロシティの変更
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // ノートオン(前非結合)・ノートオフ(前非結合)の場合
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL && theDlg.m_nTargetNoteOn ||
+ MIDIEvent_IsNoteOff (pMIDIEvent) &&
+ pMIDIEvent->m_pPrevCombinedEvent == NULL && theDlg.m_nTargetNoteOff) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent* pTempEvent = pCloneEvent;
+ while (pTempEvent) {
+ if (MIDIEvent_IsNoteOn (pTempEvent) && theDlg.m_nTargetNoteOn ||
+ MIDIEvent_IsNoteOff (pTempEvent) && theDlg.m_nTargetNoteOff) {
+ long lVelocity = MIDIEvent_GetVelocity (pTempEvent);
+ if (theDlg.m_nUnit == 0) {
+ lVelocity = theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lVelocity += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lVelocity = lVelocity * theDlg.m_nAmount / 100;
+ }
+ else if (theDlg.m_nUnit == 3) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lVelocity += (lDelta - abs (theDlg.m_nAmount));
+ }
+ lVelocity = CLIP (0, lVelocity, 127);
+ MIDIEvent_SetVelocity (pTempEvent, lVelocity);
+ }
+ pTempEvent = pTempEvent->m_pNextCombinedEvent;
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditVelocityDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditVelocityDlgStatus.m_nUnit = theDlg.m_nUnit;
+ pSekaijuApp->m_theEditVelocityDlgStatus.m_nTargetNoteOn = theDlg.m_nTargetNoteOn;
+ pSekaijuApp->m_theEditVelocityDlgStatus.m_nTargetNoteOff = theDlg.m_nTargetNoteOff;
+ }
+}
+
+// 『編集(E)』-『ベロシティの変更...』
+void CSekaijuDoc::OnUpdateEditVelocityUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『音長さの変更...』
+void CSekaijuDoc::OnEditDuration () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CEditDurationDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditDurationDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditDurationDlgStatus.m_nUnit, 3);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_DURATION));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+ // 音の長さ変更
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // ノートオフに結合されたノートオンイベントのみ
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsCombined (pMIDIEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lDuration = MIDIEvent_GetDuration (pCloneEvent);
+ if (theDlg.m_nUnit == 0) {
+ lDuration = theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lDuration += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lDuration = lDuration * theDlg.m_nAmount / 100;
+ }
+ else if (theDlg.m_nUnit == 3) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lDuration += (lDelta - abs (theDlg.m_nAmount));
+ }
+ lDuration = CLIP (1, lDuration, 65535);
+ VERIFY (MIDIEvent_SetDuration (pCloneEvent, lDuration));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditDurationDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditDurationDlgStatus.m_nUnit = theDlg.m_nUnit;
+ }
+}
+
+// 『編集(E)』-『音長さの変更...』
+void CSekaijuDoc::OnUpdateEditDurationUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『値の変更...』
+void CSekaijuDoc::OnEditValue () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CEditValueDlg theDlg;
+ theDlg.m_nAmount = pSekaijuApp->m_theEditValueDlgStatus.m_nAmount;
+ theDlg.m_nUnit = CLIP (0, pSekaijuApp->m_theEditValueDlgStatus.m_nUnit, 3);
+ theDlg.m_nTargetKeyAfter = CLIP (0, pSekaijuApp->m_theEditValueDlgStatus.m_nTargetKeyAfter, 1);
+ theDlg.m_nTargetControlChange = CLIP (0, pSekaijuApp->m_theEditValueDlgStatus.m_nTargetControlChange, 1);
+ theDlg.m_nTargetChannelAfter = CLIP (0, pSekaijuApp->m_theEditValueDlgStatus.m_nTargetChannelAfter, 1);
+ theDlg.m_nTargetPitchBend = CLIP (0, pSekaijuApp->m_theEditValueDlgStatus.m_nTargetPitchBend, 1);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_MODIFY_VALUE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ // 値の変更
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // キーアフタータッチ・コントロールチェンジ・チャンネルアフタータッチ
+ if (MIDIEvent_IsKeyAftertouch (pMIDIEvent) && theDlg.m_nTargetKeyAfter ||
+ MIDIEvent_IsControlChange (pMIDIEvent) && theDlg.m_nTargetControlChange ||
+ MIDIEvent_IsChannelAftertouch (pMIDIEvent) && theDlg.m_nTargetChannelAfter) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ if (theDlg.m_nUnit == 0) {
+ lValue = theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lValue += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lValue = lValue * theDlg.m_nAmount / 100;
+ }
+ else if (theDlg.m_nUnit == 3) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lValue += (lDelta - abs (theDlg.m_nAmount));
+ }
+ lValue = CLIP (0, lValue, 127);
+ VERIFY (MIDIEvent_SetValue (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ // ピッチベンド
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent) && theDlg.m_nTargetPitchBend) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ if (theDlg.m_nUnit == 0) {
+ lValue = theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 1) {
+ lValue += theDlg.m_nAmount;
+ }
+ else if (theDlg.m_nUnit == 2) {
+ lValue = 8192 + (lValue - 8192) * theDlg.m_nAmount / 100;
+ }
+ else if (theDlg.m_nUnit == 3) {
+ long lDelta = rand () % (abs (theDlg.m_nAmount * 2) + 1);
+ lValue += (lDelta - abs (theDlg.m_nAmount));
+ }
+ lValue = CLIP (0, lValue, 16383);
+ VERIFY (MIDIEvent_SetValue (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditValueDlgStatus.m_nAmount = theDlg.m_nAmount;
+ pSekaijuApp->m_theEditValueDlgStatus.m_nUnit = theDlg.m_nUnit;
+ pSekaijuApp->m_theEditValueDlgStatus.m_nTargetKeyAfter = theDlg.m_nTargetKeyAfter;
+ pSekaijuApp->m_theEditValueDlgStatus.m_nTargetControlChange = theDlg.m_nTargetControlChange;
+ pSekaijuApp->m_theEditValueDlgStatus.m_nTargetChannelAfter = theDlg.m_nTargetChannelAfter;
+ pSekaijuApp->m_theEditValueDlgStatus.m_nTargetPitchBend = theDlg.m_nTargetPitchBend;
+ }
+}
+
+// 『編集(E)』-『値の変更...』
+void CSekaijuDoc::OnUpdateEditValueUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『編集(E)』-『クォンタイズ...』
+void CSekaijuDoc::OnEditQuantize () {
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ CEditQuantizeDlg theDlg;
+ theDlg.m_lTimeMode = MIDIData_GetTimeMode (m_pMIDIData);
+ theDlg.m_lTimeResolution = MIDIData_GetTimeResolution (m_pMIDIData);
+ theDlg.m_nSnapTimeIndex = CLIP (0, pSekaijuApp->m_theEditQuantizeDlgStatus.m_nSnapTimeIndex, 6);
+ theDlg.m_nStrength = CLIP (0, pSekaijuApp->m_theEditQuantizeDlgStatus.m_nStrength, 100);
+ theDlg.m_nTargetNoteOn = CLIP (0, pSekaijuApp->m_theEditQuantizeDlgStatus.m_nTargetNoteOn, 1);
+ theDlg.m_nTargetNoteOff = CLIP (0, pSekaijuApp->m_theEditQuantizeDlgStatus.m_nTargetNoteOff, 1);
+ if (theDlg.DoModal () == IDOK) {
+ BeginWaitCursor ();
+ long lDivision[7] = {1, 2, 3, 4, 6, 8, 12};
+ long lSnapTimeIndex = CLIP (0, theDlg.m_nSnapTimeIndex, 6);
+ long lSnapTime = __max (1, MIDIData_GetTimeResolution (m_pMIDIData) / lDivision[lSnapTimeIndex]);
+ m_theCriticalSection.Lock ();
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_QUANTIZE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+
+ // 同じイベントを2回移動しないように、選択されているイベントを一時配列に登録する。
+ CPtrArray theTempSelectedEventArray;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 選択されているイベントのみ
+ if (this->IsEventSelected (pMIDIEvent)) {
+ // ノートオフに結合されたノートオンイベントのみ
+ if (MIDIEvent_IsNoteOn (pMIDIEvent) && MIDIEvent_IsCombined (pMIDIEvent)) {
+ theTempSelectedEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ }
+
+ // 一時配列のイベント1個につき1回の移動をかける。
+ long lTempSelectedEventArrayCount = theTempSelectedEventArray.GetSize ();
+ for (long j = 0; j < lTempSelectedEventArrayCount; j++) {
+ pMIDIEvent = (MIDIEvent*)(theTempSelectedEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+
+ // 音符の開始位置移動(音長さは保持される)
+ if (theDlg.m_nTargetNoteOn) {
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ long lNewTime = (lTime + lSnapTime / 2) / lSnapTime * lSnapTime;
+ long lDeltaTime = lNewTime - lTime;
+ long lStDeltaTime = lDeltaTime * theDlg.m_nStrength / 100;
+ long lStNewTime = CLIP (0, lTime + lStDeltaTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lStNewTime));
+ }
+
+ // 音符の終了位置移動(音長さを変更することによる)
+ if (theDlg.m_nTargetNoteOff) {
+ long lBeginTime = MIDIEvent_GetTime (pCloneEvent);
+ long lDuration = MIDIEvent_GetDuration (pCloneEvent);
+ long lEndTime = lBeginTime + lDuration;
+ long lNewEndTime = (lEndTime + lSnapTime / 2) / lSnapTime * lSnapTime;
+ long lDeltaTime = lNewEndTime - lEndTime;
+ long lStDeltaTime = lDeltaTime * theDlg.m_nStrength / 100;
+ long lStNewEndTime = CLIP (0, lEndTime + lStDeltaTime, 0x7FFFFFFF);
+ long lStNewDuration = lStNewEndTime - lBeginTime;
+ while (lStNewDuration <= 1) {
+ lStNewDuration += lSnapTime;
+ }
+ VERIFY (MIDIEvent_SetDuration (pCloneEvent, lStNewDuration));
+ }
+
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ theTempSelectedEventArray.RemoveAll ();
+
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ pSekaijuApp->m_theEditQuantizeDlgStatus.m_nSnapTimeIndex = theDlg.m_nSnapTimeIndex;
+ pSekaijuApp->m_theEditQuantizeDlgStatus.m_nStrength = theDlg.m_nStrength;
+ pSekaijuApp->m_theEditQuantizeDlgStatus.m_nTargetNoteOn = theDlg.m_nTargetNoteOn;
+ pSekaijuApp->m_theEditQuantizeDlgStatus.m_nTargetNoteOff = theDlg.m_nTargetNoteOff;
+ }
+}
+
+
+
+// 『編集(E)』-『クォンタイズ...』
+void CSekaijuDoc::OnUpdateEditQuantizeUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+// 『編集(E)』-『音符の細分化とトリル化...』
+void CSekaijuDoc::OnEditBreakupAndTrill () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ CEditBreakupAndTrillDlg theDlg;
+ theDlg.m_lTimeMode = MIDIData_GetTimeMode (m_pMIDIData);
+ theDlg.m_lTimeResolution = MIDIData_GetTimeResolution (m_pMIDIData);
+ theDlg.m_nDurationIndex = pSekaijuApp->m_theEditBreakupAndTrillDlgStatus.m_nDurationIndex;
+ theDlg.m_nEnableTrill = pSekaijuApp->m_theEditBreakupAndTrillDlgStatus.m_nEnableTrill;
+ theDlg.m_nKeyShift = pSekaijuApp->m_theEditBreakupAndTrillDlgStatus.m_nKeyShift;
+
+
+ if (theDlg.DoModal () == IDOK) {
+ pSekaijuApp->m_theEditBreakupAndTrillDlgStatus.m_nDurationIndex = theDlg.m_nDurationIndex;
+ pSekaijuApp->m_theEditBreakupAndTrillDlgStatus.m_nEnableTrill = theDlg.m_nEnableTrill;
+ pSekaijuApp->m_theEditBreakupAndTrillDlgStatus.m_nKeyShift = theDlg.m_nKeyShift;
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+
+ // 処理後の1音の長さ[tick]を計算
+ long lDurationDiv[7] = {1, 2, 3, 4, 6, 8, 12};
+ long lDuration = theDlg.m_lTimeResolution / lDurationDiv[theDlg.m_nDurationIndex];
+ lDuration = CLIP (1, lDuration, 65535);
+ long lKeyShift = CLIP (-127, theDlg.m_nKeyShift, 127);
+
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_BREAKUP_AND_TRILL));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ long i = 0;
+ long j = 0;
+ long lDeletedNoteEventCount = 0;
+ long lInsertedNoteEventCount = 0;
+
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+
+ // 配列に登録されたイベントを削除
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ // 選択されているノートオンイベントを配列に登録
+ CPtrArray theEventArray;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ if (MIDIEvent_IsNote (pMIDIEvent) && MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ theEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ // それぞれの選択されているノートイベントについて
+ for (i = 0; i < theEventArray.GetSize (); i++) {
+ VERIFY (pMIDIEvent = (MIDIEvent*)theEventArray.GetAt (i));
+ ASSERT (MIDIEvent_IsNote (pMIDIEvent) && MIDIEvent_IsNoteOn (pMIDIEvent));
+ long lOldTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lOldChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ long lOldDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ long lOldKey = MIDIEvent_GetKey (pMIDIEvent);
+ long lOldVelocity = MIDIEvent_GetVelocity (pMIDIEvent);
+ // 既存のノートイベントを削除
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent));
+ lDeletedNoteEventCount++;
+ // 新しいノートイベントを挿入
+ for (j = 0; j < 65536; j++) {
+ long lNewTime = lOldTime + lDuration * j;
+ if (lNewTime >= lOldTime + lOldDuration) {
+ break;
+ }
+ long lNewDuration = lDuration;
+ if (lNewTime + lNewDuration >= lOldTime + lOldDuration) {
+ lNewDuration = lOldTime + lOldDuration - lNewTime;
+ ASSERT (lNewDuration > 0);
+ }
+ long lNewKey = lOldKey;
+ if (theDlg.m_nEnableTrill) {
+ lNewKey = (j % 2 == 0 ? lOldKey : lOldKey + lKeyShift);
+ }
+ lNewKey = CLIP (1, lNewKey, 127);
+ long lNewVelocity = lOldVelocity;
+ long lNewChannel = lOldChannel;
+ // 新しいノートイベントを作成
+ MIDIEvent* pNewEvent = MIDIEvent_CreateNote
+ (lNewTime, lNewChannel, lNewKey, lNewVelocity, lNewDuration);
+ ASSERT (pNewEvent);
+ // 結合イベントを先頭から順に選択状態にする。
+ MIDIEvent* pTempEvent = pNewEvent;
+ while (pTempEvent) {
+ pTempEvent->m_lUserFlag |= MIDIEVENT_SELECTED;
+ pTempEvent = pTempEvent->m_pNextCombinedEvent;
+ }
+ // トラックに挿入、履歴記録
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pNewEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ lInsertedNoteEventCount++;
+ }
+ }
+ theEventArray.RemoveAll ();
+ }
+
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+
+ }
+}
+
+// 『編集(E)』-『音符の細分化とトリル化...』
+void CSekaijuDoc::OnUpdateEditBreakupAndTrillUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+
+// 『編集(E)』-『ビート検出とテンポ自動挿入...』
+void CSekaijuDoc::OnEditBeatScan () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ CString strMsg;
+
+ // フォーマットチェック
+ long lFormat = MIDIData_GetFormat (m_pMIDIData);
+ if (lFormat == 0) {
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_BEATSCAN_WITH_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // タイムベースチェック
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (m_pMIDIData, &lTimeMode, &lTimeResolution);
+ long lTrackCount = MIDIData_CountTrack (m_pMIDIData);
+ if (lTimeMode != MIDIDATA_TPQNBASE) {
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_BEATSCAN_WITH_SMPTEBASE_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // 各トラックのトラック名をダイアログクラスの配列に代入
+ long i = 0;
+ long j = 0;
+ TCHAR szTrackName[256];
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CEditBeatScanDlg theDlg;
+ theDlg.m_lTimeMode = lTimeMode;
+ theDlg.m_lTimeResolution = lTimeResolution;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ memset (szTrackName, 0, sizeof (szTrackName));
+ MIDITrack_GetName (pMIDITrack, szTrackName, TSIZEOF (szTrackName));
+ theDlg.m_theTrackNameArray.Add (szTrackName);
+ i++;
+ }
+
+ theDlg.m_nBeatTrackIndex = pSekaijuApp->m_theEditBeatScanDlgStatus.m_nBeatTrackIndex;
+ theDlg.m_nBeatTrackIndex = CLIP (0, theDlg.m_nBeatTrackIndex, lTrackCount - 1);
+ theDlg.m_nBeatIntervalIndex = pSekaijuApp->m_theEditBeatScanDlgStatus.m_nBeatIntervalIndex;
+ theDlg.m_nInsertTempo = pSekaijuApp->m_theEditBeatScanDlgStatus.m_nInsertTempo;
+
+ // ダイアログ表示
+ if (theDlg.DoModal () == IDOK) {
+
+ pSekaijuApp->m_theEditBeatScanDlgStatus.m_nBeatTrackIndex = theDlg.m_nBeatTrackIndex;
+ pSekaijuApp->m_theEditBeatScanDlgStatus.m_nBeatIntervalIndex = theDlg.m_nBeatIntervalIndex;
+ pSekaijuApp->m_theEditBeatScanDlgStatus.m_nInsertTempo = theDlg.m_nInsertTempo;
+
+ m_theCriticalSection.Lock ();
+ CDWordArray theBeatTimeArray;
+ CDWordArray theBeatMillisecArray;
+ CDWordArray theTempoArray;
+
+ // 処理後のビート間隔[tick]を計算
+ long lBeatDiv[7] = {1, 2, 3, 4, 6, 8, 12};
+ long lBeatInterval = lTimeResolution / lBeatDiv[theDlg.m_nBeatIntervalIndex];
+
+ // 選択されている各ビートの時刻[tick]とミリ秒[msec]を抽出
+ MIDITrack* pBeatTrack = this->GetTrack (theDlg.m_nBeatTrackIndex);
+ ASSERT (pBeatTrack);
+ long lOldTime = 0;
+ long lNumBeatCount = 0;
+ theBeatTimeArray.Add (0);
+ theBeatMillisecArray.Add (0);
+ lNumBeatCount++;
+ forEachEvent (pBeatTrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ if (MIDIEvent_IsNoteOn (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime > lOldTime) {
+ theBeatTimeArray.Add (lTime);
+ long lMillisec = MIDIData_TimeToMillisec (m_pMIDIData, lTime);
+ theBeatMillisecArray.Add (lMillisec);
+ lNumBeatCount++;
+ lOldTime = lTime;
+ }
+ }
+ }
+ }
+ ASSERT (lNumBeatCount == theBeatTimeArray.GetSize ());
+ ASSERT (lNumBeatCount == theBeatMillisecArray.GetSize ());
+
+ // 指定トラック内で選択されているビートの数が少なすぎる場合は却下
+ if (lNumBeatCount <= 3) {
+ m_theCriticalSection.Unlock ();
+ VERIFY (strMsg.LoadString (IDS_SELECTED_NOTEEVENT_IS_TOO_FEW_IN_THE_SPECIFIED_TRACK));
+ AfxMessageBox (strMsg);
+ return;
+ }
+
+ // ビートスキャン開始時刻[tick]とビートスキャン終了時刻[tick]を抽出
+ long lBeginTime = theBeatTimeArray.GetAt (1);
+ long lEndTime = theBeatTimeArray.GetAt (lNumBeatCount - 1);
+ long lBeginMeasure, lBeginBeat, lBeginTick;
+ MIDIData_BreakTime (m_pMIDIData, lBeginTime, &lBeginMeasure, &lBeginBeat, &lBeginTick);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (m_pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ // ビートスキャン処理開始確認メッセージ
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_NOTEVENT_IS_DETECTED_IN_THE_SPECIFIED_TRACK_CONTINUE));
+ strMsg.Format (strFormat, lNumBeatCount - 1,
+ lBeginMeasure + 1, lBeginBeat + 1, lBeginTick,
+ lEndMeasure + 1, lEndBeat + 1, lEndTick);
+ m_theCriticalSection.Unlock ();
+ long lRet = AfxMessageBox (strMsg, MB_ICONINFORMATION | MB_YESNOCANCEL);
+ if (lRet == IDNO || lRet == IDCANCEL) {
+ return;
+ }
+ m_theCriticalSection.Lock ();
+
+ BeginWaitCursor ();
+
+ // 各ビート位置における補正後テンポ[μ秒/4分音符]を計算
+ long lTempo = 0;
+ MIDIData_FindTempo (m_pMIDIData, 0, &lTempo);
+ theTempoArray.Add (lTempo);
+ for (j = 1; j < lNumBeatCount - 1; j++) {
+ lTempo =
+ (theBeatMillisecArray.GetAt (j + 1) - theBeatMillisecArray.GetAt (j)) *
+ 1000 * lTimeResolution / lBeatInterval;
+ theTempoArray.Add (lTempo);
+ }
+ MIDIData_FindTempo (m_pMIDIData, lEndTime, &lTempo);
+ theTempoArray.Add (lTempo);
+ ASSERT (lNumBeatCount == theTempoArray.GetSize ());
+
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_BEATSCAN));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+ }
+
+ // 既存のテンポイベントの削除
+ long lDeletedTempoEventCount = 0;
+ if (theDlg.m_nInsertTempo) {
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ // lBeginTime〜lEndTimeにあるテンポイベントを配列に登録
+ CPtrArray theEventArray;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lBeginTime <= lTime && lTime < lEndTime) {
+ theEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ // 配列に登録されたイベントを削除
+ for (i = 0; i < theEventArray.GetSize (); i++) {
+ VERIFY (pMIDIEvent = (MIDIEvent*)theEventArray.GetAt (i));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (MIDITrack_RemoveEvent (pMIDITrack, pMIDIEvent));
+ lDeletedTempoEventCount++;
+ }
+ theEventArray.RemoveAll ();
+ }
+ }
+
+ // MIDIイベントの時刻移動
+ long lMovedEventCount = 0;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ j = 0;
+ // lBeginTime以降にあるイベントを配列に登録
+ // (結合イベントの場合は最初のイベントのみ)
+ // (エンドオブトラックイベントは自動移動するので除く)
+ CPtrArray theEventArray;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime >= lBeginTime) {
+ if (pMIDIEvent->m_pPrevCombinedEvent == NULL &&
+ !MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ theEventArray.Add (pMIDIEvent);
+ }
+ }
+ }
+ // 配列に登録されたイベントを位置移動
+ for (i = 0; i < theEventArray.GetSize (); i++) {
+ VERIFY (pMIDIEvent = (MIDIEvent*)theEventArray.GetAt (i));
+ ASSERT (pMIDIEvent->m_pPrevCombinedEvent == NULL);
+ ASSERT (MIDIEvent_GetParent (pMIDIEvent) == pMIDITrack);
+ // ノートイベント(ノートオン+ノートオフ)の場合
+ if (MIDIEvent_IsNote (pMIDIEvent)) {
+ long lTime1 = MIDIEvent_GetTime (pMIDIEvent);
+ long lDuration = MIDIEvent_GetDuration (pMIDIEvent);
+ long lTime2 = lTime1 + lDuration;
+ while (j < lNumBeatCount - 1) {
+ if ((long)theBeatTimeArray.GetAt (j) <= lTime1 &&
+ lTime1 < (long)theBeatTimeArray.GetAt (j + 1)) {
+ break;
+ }
+ j++;
+ }
+ long k = j;
+ while (k < lNumBeatCount - 1) {
+ if ((long)theBeatTimeArray.GetAt (k) <= lTime2 &&
+ lTime2 < (long)theBeatTimeArray.GetAt (k + 1)) {
+ break;
+ }
+ k++;
+ }
+ long lNewTime1 = 0;
+ long lNewTime2 = 0;
+ // ノートオン位置移動
+ // 開始時刻or最初のビート時刻より前にあるイベント
+ if (j == 0) {
+ ASSERT (0 <= lTime1 && lTime1 < lBeginTime);
+ ASSERT (FALSE);
+ }
+ // ビート時刻(j)とビート時刻(j+1)の間にあるイベント
+ else if (1 <= j && j < lNumBeatCount - 1) {
+ ASSERT (lBeginTime <= lTime1 && lTime1 < lEndTime);
+ lNewTime1 =
+ lBeginTime +
+ lBeatInterval * (j - 1) +
+ lBeatInterval *
+ (lTime1 - theBeatTimeArray.GetAt (j)) /
+ (theBeatTimeArray.GetAt (j + 1) - theBeatTimeArray.GetAt(j));
+ lNewTime1 = CLIP (0, lNewTime1, 0x7FFFFFFF);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent_SetTime (pCloneEvent, lNewTime1);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ lMovedEventCount++;
+ }
+ // 終了時刻or最後のビート時刻より後にあるイベント
+ else {
+ ASSERT (lTime1 >= lEndTime);
+ lNewTime1 =
+ lBeginTime +
+ lBeatInterval * (lNumBeatCount - 2) +
+ lTime1 - theBeatTimeArray.GetAt (lNumBeatCount - 1);
+ lNewTime1 = CLIP (0, lNewTime1, 0x7FFFFFFF);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent_SetTime (pCloneEvent, lNewTime1);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ lMovedEventCount++;
+ }
+ // ノートオフ位置移動(音長さの変更による)
+ // 開始時刻or最初のビート時刻より前にあるイベント
+ if (k == 0) {
+ ASSERT (0 <= lTime2 && lTime2 < lBeginTime);
+ ASSERT (FALSE);
+ }
+ // ビート時刻(k)とビート時刻(k+1)の間にあるイベント
+ else if (1 <= k && k < lNumBeatCount - 1) {
+ ASSERT (lBeginTime <= lTime2 && lTime2 < lEndTime);
+ long lNewTime2 =
+ lBeginTime +
+ lBeatInterval * (k - 1) +
+ lBeatInterval *
+ (lTime2 - theBeatTimeArray.GetAt (k)) /
+ (theBeatTimeArray.GetAt (k + 1) - theBeatTimeArray.GetAt(k));
+ lNewTime2 = CLIP (0, lNewTime2, 0x7FFFFFFF);
+ long lNewDuration = lNewTime2 - lNewTime1;
+ lNewDuration = CLIP (0, lNewDuration, 0xFFFF);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent_SetDuration (pCloneEvent, lNewDuration);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ lMovedEventCount++;
+ }
+ // 終了時刻or最後のビート時刻より後にあるイベント
+ else {
+ ASSERT (lTime2 >= lEndTime);
+ lNewTime2 =
+ lBeginTime +
+ lBeatInterval * (lNumBeatCount - 2) +
+ lTime2 - theBeatTimeArray.GetAt (lNumBeatCount - 1);
+ lNewTime2 = CLIP (0, lNewTime2, 0x7FFFFFFF);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ long lNewDuration = lNewTime2 - lNewTime1;
+ lNewDuration = CLIP (0, lNewDuration, 0xFFFF);
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent_SetDuration (pCloneEvent, lNewDuration);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ lMovedEventCount++;
+ }
+ }
+ // ノートイベント(ノートオン+ノートオフ)以外の場合
+ else {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ while (j < lNumBeatCount - 1) {
+ if ((long)theBeatTimeArray.GetAt (j) <= lTime &&
+ lTime < (long)theBeatTimeArray.GetAt (j + 1)) {
+ break;
+ }
+ j++;
+ }
+ // 開始時刻or最初のビート時刻より前にあるイベント
+ if (j == 0) {
+ ASSERT (0 <= lTime && lTime < lBeginTime);
+ ASSERT (FALSE);
+ }
+ // ビート時刻(j)とビート時刻(j+1)の間にあるイベント
+ else if (1 <= j && j < lNumBeatCount - 1) {
+ ASSERT (lBeginTime <= lTime && lTime < lEndTime);
+ long lNewTime =
+ lBeginTime +
+ lBeatInterval * (j - 1) +
+ lBeatInterval *
+ (lTime - theBeatTimeArray.GetAt (j)) /
+ (theBeatTimeArray.GetAt (j + 1) - theBeatTimeArray.GetAt(j));
+ lNewTime = CLIP (0, lNewTime, 0x7FFFFFFF);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent_SetTime (pCloneEvent, lNewTime);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ lMovedEventCount++;
+ }
+ // 終了時刻or最後のビート時刻より後にあるイベント
+ else {
+ ASSERT (lTime >= lEndTime);
+ long lNewTime =
+ lBeginTime +
+ lBeatInterval * (lNumBeatCount - 2) +
+ lTime - theBeatTimeArray.GetAt (lNumBeatCount - 1);
+ lNewTime = CLIP (0, lNewTime, 0x7FFFFFFF);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ MIDIEvent_SetTime (pCloneEvent, lNewTime);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ lMovedEventCount++;
+ }
+ }
+ } // for
+ theEventArray.RemoveAll ();
+ } // forEachTrack
+
+ // テンポイベントの挿入
+ long lInsertedTempoEventCount = 0;
+ if (theDlg.m_nInsertTempo) {
+ VERIFY (pMIDITrack = MIDIData_GetFirstTrack (m_pMIDIData));
+ for (i = 1; i < theTempoArray.GetSize (); i++) {
+ lTempo = theTempoArray.GetAt (i);
+ lTempo = CLIP (1, lTempo, 60000000);
+ long lTime = lBeginTime + lBeatInterval * (i - 1);
+ VERIFY (pMIDIEvent = MIDIEvent_CreateTempo (lTime, lTempo));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pMIDIEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pMIDIEvent));
+ lInsertedTempoEventCount++;
+ }
+ }
+
+ // EOTの履歴保持
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+ }
+
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ }
+}
+
+// 『編集(E)』-『ビート検出とテンポ自動挿入...』
+void CSekaijuDoc::OnUpdateEditBeatScanUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+
+ // すべてのイベントが非選択であればこの項目をディスエーブルする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable == 1) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+// 『編集(E)』-『小節を挿入...』(20100728追加)
+void CSekaijuDoc::OnEditInsertMeasure () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ long lTimeMode = MIDIData_GetTimeMode (m_pMIDIData);
+
+ CEditInsertMeasureDlg theDlg;
+ theDlg.m_nPosition = pSekaijuApp->m_theEditInsertMeasureDlgStatus.m_nPosition;
+ theDlg.m_nNumMeasure = pSekaijuApp->m_theEditInsertMeasureDlgStatus.m_nNumMeasure;
+ theDlg.m_bZeroOrigin = (lTimeMode == MIDIDATA_TPQNBASE ? 0 : 1);
+ if (theDlg.DoModal () == IDOK) {
+ pSekaijuApp->m_theEditInsertMeasureDlgStatus.m_nPosition = theDlg.m_nPosition;
+ pSekaijuApp->m_theEditInsertMeasureDlgStatus.m_nNumMeasure = theDlg.m_nNumMeasure;
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_INSERTMEASURE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+
+ long lTime1, lTime2, lMeasureTime, lSlideTime;
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition - 1, 0, 0, &lTime1);
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition , 0, 0, &lTime2);
+ }
+ else {
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition, 0, 0, &lTime1);
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition + 1, 0, 0, &lTime2);
+ }
+ lMeasureTime = MAX (0, lTime2 - lTime1);
+ lSlideTime = lMeasureTime * theDlg.m_nNumMeasure;
+ // 後続のMIDIイベントの時刻移動
+ // 同じイベントを2回移動しないように、後続のイベントを一時配列に登録する。
+ CPtrArray theTempFollowingEventArray;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUser1 = 0;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 小節挿入位置より後のイベントのみ
+ if (MIDIEvent_GetTime (pMIDIEvent) >= lTime1) {
+ // 非結合イベントのみ、結合イベントの場合は前非結合のみ
+ if (MIDIEvent_IsCombined (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL ||
+ !MIDIEvent_IsCombined (pMIDIEvent)) {
+ theTempFollowingEventArray.Add (pMIDIEvent);
+ pMIDITrack->m_lUser1++;
+ }
+ }
+ }
+ }
+ // 一時配列のイベント1個につき1回の移動をかける。
+ long lTempFollowingEventArrayCount = theTempFollowingEventArray.GetSize ();
+ if (lSlideTime < 0) {
+ // (EOTを最後に移動させるため、昇順に)(20081102修正)
+ for (long j = 0; j < lTempFollowingEventArrayCount; j++) {
+ pMIDIEvent = (MIDIEvent*)(theTempFollowingEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ lTime += lSlideTime;
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ else {
+ // (EOTを最初に移動させるため、逆順に)(20081102修正)
+ for (long j = lTempFollowingEventArrayCount - 1; j >= 0; j--) {
+ pMIDIEvent = (MIDIEvent*)(theTempFollowingEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ lTime += lSlideTime;
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ theTempFollowingEventArray.RemoveAll ();
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ }
+}
+
+// 『編集(E)』-『小節を挿入...』(20100728追加)
+void CSekaijuDoc::OnUpdateEditInsertMeasureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『編集(E)』-『小節を除去...』(20100728追加)
+void CSekaijuDoc::OnEditRemoveMeasure () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ long lTimeMode = MIDIData_GetTimeMode (m_pMIDIData);
+
+ CEditRemoveMeasureDlg theDlg;
+ theDlg.m_nPosition = pSekaijuApp->m_theEditRemoveMeasureDlgStatus.m_nPosition;
+ theDlg.m_nNumMeasure = pSekaijuApp->m_theEditRemoveMeasureDlgStatus.m_nNumMeasure;
+ theDlg.m_bZeroOrigin = (lTimeMode == MIDIDATA_TPQNBASE ? 0 : 1);
+ if (theDlg.DoModal () == IDOK) {
+ pSekaijuApp->m_theEditRemoveMeasureDlgStatus.m_nPosition = theDlg.m_nPosition;
+ pSekaijuApp->m_theEditRemoveMeasureDlgStatus.m_nNumMeasure = theDlg.m_nNumMeasure;
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_INSERTMEASURE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+
+ long lTime1, lTime2, lSlideTime;
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition - 1, 0, 0, &lTime1);
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition - 1 + theDlg.m_nNumMeasure, 0, 0, &lTime2);
+ }
+ else {
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition, 0, 0, &lTime1);
+ MIDIData_MakeTime (m_pMIDIData, theDlg.m_nPosition + theDlg.m_nNumMeasure, 0, 0, &lTime2);
+ }
+ lSlideTime = MIN (0, lTime1 - lTime2);
+ // lTime1〜lTime2のイベントの削除
+ // 同じイベントを2回移動しないように、lTime1〜lTime2のイベントを一時配列に登録する。
+ CPtrArray theTempDuringEventArray;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUser1 = 0;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // lTime1〜lTime2のイベントのみ
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (lTime1 <= lTime && lTime < lTime2) {
+ // 非結合イベントのみ、結合イベントの場合は前非結合のみ
+ if (MIDIEvent_IsCombined (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL ||
+ !MIDIEvent_IsCombined (pMIDIEvent)) {
+ theTempDuringEventArray.Add (pMIDIEvent);
+ pMIDITrack->m_lUser1++;
+ }
+ }
+ }
+ }
+ // 一時配列内のイベントを削除(EOTを除く)
+ long lTempDuringEventArrayCount = theTempDuringEventArray.GetSize ();
+ for (long j = 0; j < lTempDuringEventArrayCount; j++) {
+ pMIDIEvent = (MIDIEvent*)(theTempDuringEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ if (MIDIEvent_IsEndofTrack (pMIDIEvent)) {
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = CLIP (0, lTime1, 0x7FFFFFFF);
+ MIDIEvent_SetTime (pCloneEvent, lTime);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ else {
+ VERIFY (MIDITrack_RemoveEvent (MIDIEvent_GetParent (pMIDIEvent), pMIDIEvent));
+ }
+ }
+ theTempDuringEventArray.RemoveAll ();
+
+ // 後続のMIDIイベントの時刻移動
+ // 同じイベントを2回移動しないように、後続のイベントを一時配列に登録する。
+ CPtrArray theTempFollowingEventArray;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUser1 = 0;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // 小節挿入位置より後のイベントのみ
+ if (MIDIEvent_GetTime (pMIDIEvent) >= lTime1) {
+ // 非結合イベントのみ、結合イベントの場合は前非結合のみ
+ if (MIDIEvent_IsCombined (pMIDIEvent) && pMIDIEvent->m_pPrevCombinedEvent == NULL ||
+ !MIDIEvent_IsCombined (pMIDIEvent)) {
+ theTempFollowingEventArray.Add (pMIDIEvent);
+ pMIDITrack->m_lUser1++;
+ }
+ }
+ }
+ }
+ // 一時配列のイベント1個につき1回の移動をかける。
+ long lTempFollowingEventArrayCount = theTempFollowingEventArray.GetSize ();
+ if (lSlideTime < 0) {
+ // (EOTを最後に移動させるため、昇順に)(20081102修正)
+ for (long j = 0; j < lTempFollowingEventArrayCount; j++) {
+ pMIDIEvent = (MIDIEvent*)(theTempFollowingEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ lTime += lSlideTime;
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ else {
+ // (EOTを最初に移動させるため、逆順に)(20081102修正)
+ for (long j = lTempFollowingEventArrayCount - 1; j >= 0; j--) {
+ pMIDIEvent = (MIDIEvent*)(theTempFollowingEventArray.GetAt (j));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pMIDIEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pMIDIEvent));
+ long lTime = MIDIEvent_GetTime (pCloneEvent);
+ lTime += lSlideTime;
+ lTime = CLIP (0, lTime, 0x7FFFFFFF);
+ VERIFY (MIDIEvent_SetTime (pCloneEvent, lTime));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ pMIDIEvent = pCloneEvent;
+ }
+ }
+ theTempFollowingEventArray.RemoveAll ();
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+ }
+}
+
+// 『編集(E)』-『小節を除去...』(20100728追加)
+void CSekaijuDoc::OnUpdateEditRemoveMeasureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+
+// 『ビュー(&V)』-『再表示(&R)』
+void CSekaijuDoc::OnViewRedraw () {
+ //this->UpdateAllViews (NULL, 0xFFFFFFFF);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ // TODO:上の2つのどちらが良いか。
+}
+
+// 『ビュー(&V)』-『新規トラックリスト(&T)』
+void CSekaijuDoc::OnViewTrackList () {
+ m_theCriticalSection.Lock ();
+ m_lTempTime = m_lNewTime;
+ m_pTempTrack = NULL;
+ m_pTempEvent = NULL;
+ m_theCriticalSection.Unlock ();
+ ShowTrackListFrame ();
+}
+
+// 『ビュー(&V)』-『新規ピアノロール(&P)』
+void CSekaijuDoc::OnViewPianoRoll () {
+ m_theCriticalSection.Lock ();
+ m_lTempTime = m_lNewTime;
+ m_pTempTrack = NULL;
+ m_pTempEvent = NULL;
+ MIDITrack* pMIDITrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_VISIBLE;
+ }
+ m_theCriticalSection.Unlock ();
+ ShowPianoRollFrame ();
+}
+
+// 『ビュー(&V)』-『新規イベントリスト(&E)』
+void CSekaijuDoc::OnViewEventList () {
+ m_theCriticalSection.Lock ();
+ m_lTempTime = m_lNewTime;
+ m_pTempTrack = NULL;
+ m_pTempEvent = NULL;
+ MIDITrack* pMIDITrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_VISIBLE;
+ }
+ m_theCriticalSection.Unlock ();
+ ShowEventListFrame ();
+}
+
+// 『ビュー(&V)』-『新規譜面(&S)』
+void CSekaijuDoc::OnViewMusicalScore () {
+ m_theCriticalSection.Lock ();
+ m_lTempTime = m_lNewTime;
+ m_pTempTrack = NULL;
+ m_pTempEvent = NULL;
+ MIDITrack* pMIDITrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ pMIDITrack->m_lUserFlag |= MIDITRACK_VISIBLE;
+ }
+ m_theCriticalSection.Unlock ();
+ ShowMusicalScoreFrame ();
+}
+
+
+// 『ポップアップ』-『このトラックのみトラックリスト表示(&T)』
+void CSekaijuDoc::OnPopupShowTrackList () {
+ if (m_pTempTrack != NULL) { // 20100429追加
+ ShowTrackListFrame ();
+ }
+}
+
+// 『ポップアップ』-『このトラックのみトラックリスト表示(&T)』 // 20100429追加
+void CSekaijuDoc::OnUpdatePopupShowTrackListUI (CCmdUI* pCmdUI) {
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『このトラックのみピアノロール表示(&P)』
+void CSekaijuDoc::OnPopupShowPianoRoll () {
+ if (m_pTempTrack != NULL) { // 20100429追加
+ ShowPianoRollFrame ();
+ }
+}
+
+// 『ポップアップ』-『このトラックのみピアノロール表示(&P)』 // 20100429追加
+void CSekaijuDoc::OnUpdatePopupShowPianoRollUI (CCmdUI* pCmdUI) {
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『このトラックのみイベントリスト表示(&E)』
+void CSekaijuDoc::OnPopupShowEventList () {
+ if (m_pTempTrack != NULL) { // 20100429追加
+ ShowEventListFrame ();
+ }
+}
+
+// 『ポップアップ』-『このトラックのみイベントリスト表示(&E)』 // 20100429追加
+void CSekaijuDoc::OnUpdatePopupShowEventListUI (CCmdUI* pCmdUI) {
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+// 『ポップアップ』-『このトラックのみ譜面表示(&S)』
+void CSekaijuDoc::OnPopupShowMusicalScore () {
+ if (m_pTempTrack != NULL) { // 20100429追加
+ ShowMusicalScoreFrame ();
+ }
+}
+
+// 『ポップアップ』-『このトラックのみ譜面表示(&S)』 // 20100429追加
+void CSekaijuDoc::OnUpdatePopupShowMusicalScoreUI (CCmdUI* pCmdUI) {
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ }
+}
+
+
+// 『ポップアップ』-『このトラックのみ入力ON』
+void CSekaijuDoc::OnPopupTrackInputOn () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+
+ // 入力ON/OFF変更処理(履歴記録)
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ONLY_THIS_TRACK_INPUT_ON));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ MIDITrack* pMIDITrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ if (pMIDITrack == m_pTempTrack) {
+ MIDITrack_SetInputOn (pCloneTrack, 1);
+ }
+ else {
+ MIDITrack_SetInputOn (pCloneTrack, 0);
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ pMIDITrack = pCloneTrack;
+ }
+
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『このトラックのみ入力ON』
+void CSekaijuDoc::OnUpdatePopupTrackInputOnUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『このトラックのみ入力OFF』
+void CSekaijuDoc::OnPopupTrackInputOff () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+
+ // 入力ON/OFF変更処理(履歴記録)
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ONLY_THIS_TRACK_INPUT_OFF));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ MIDITrack* pMIDITrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ if (pMIDITrack == m_pTempTrack) {
+ MIDITrack_SetInputOn (pCloneTrack, 0);
+ }
+ else {
+ MIDITrack_SetInputOn (pCloneTrack, 1);
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ pMIDITrack = pCloneTrack;
+ }
+
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『このトラックのみ入力OFF』
+void CSekaijuDoc::OnUpdatePopupTrackInputOffUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『全トラック入力ON』
+void CSekaijuDoc::OnPopupTrackInputAll () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+ // 入力ON/OFF変更処理(履歴記録)
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ALL_TRACK_INPUT_ON));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ MIDITrack* pMIDITrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ MIDITrack_SetInputOn (pCloneTrack, 1);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ pMIDITrack = pCloneTrack;
+ }
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『全トラック入力ON』
+void CSekaijuDoc::OnUpdatePopupTrackInputAllUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『このトラックのみ出力ON』
+void CSekaijuDoc::OnPopupTrackOutputOn () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+ // 出力ON/OFF変更処理(履歴記録)
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ONLY_THIS_TRACK_OUTPUT_ON));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ MIDITrack* pMIDITrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ if (pMIDITrack == m_pTempTrack) {
+ MIDITrack_SetOutputOn (pCloneTrack, 1);
+ }
+ else {
+ MIDITrack_SetOutputOn (pCloneTrack, 0);
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ pMIDITrack = pCloneTrack;
+ }
+
+ // 演奏状態復元処理
+ long lCurTime = MIDIClock_GetTickCount (m_pMIDIClock);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pSekaijuApp->ResetTempMIDIStatusArray ();
+ this->TimeMIDIStatus (lCurTime, pSekaijuApp->m_pTempMIDIStatus);
+ long lFlags;
+ // 再生中ならば(a)すべて又は(b)ノートのみを復元する
+ if (pSekaijuApp->m_bPlaying) {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? SDS_ALL : SDS_NOTE;
+ pSekaijuApp->m_bIgnoreNoteEvent = 1;
+ }
+ // 停止中ならば(a)ノートを除くすべてを復元するか(b)何も復元しない
+ else {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? (SDS_ALL & ~SDS_NOTE) : 0;
+ pSekaijuApp->m_bIgnoreNoteEvent = 0;
+ }
+ pSekaijuApp->SendDifferentStatus (lFlags);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『このトラックのみ出力ON』
+void CSekaijuDoc::OnUpdatePopupTrackOutputOnUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『このトラックのみ出力OFF』
+void CSekaijuDoc::OnPopupTrackOutputOff () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+ // 出力ON/OFF変更処理(履歴記録)
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ONLY_THIS_TRACK_OUTPUT_OFF));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ MIDITrack* pMIDITrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ if (pMIDITrack == m_pTempTrack) {
+ MIDITrack_SetOutputOn (pCloneTrack, 0);
+ }
+ else {
+ MIDITrack_SetOutputOn (pCloneTrack, 1);
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ pMIDITrack = pCloneTrack;
+ }
+
+ // 演奏状態復元処理
+ long lCurTime = MIDIClock_GetTickCount (m_pMIDIClock);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pSekaijuApp->ResetTempMIDIStatusArray ();
+ this->TimeMIDIStatus (lCurTime, pSekaijuApp->m_pTempMIDIStatus);
+ long lFlags;
+ // 再生中ならば(a)すべて又は(b)ノートのみを復元する
+ if (pSekaijuApp->m_bPlaying) {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? SDS_ALL : SDS_NOTE;
+ pSekaijuApp->m_bIgnoreNoteEvent = 1;
+ }
+ // 停止中ならば(a)ノートを除くすべてを復元するか(b)何も復元しない
+ else {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? (SDS_ALL & ~SDS_NOTE) : 0;
+ pSekaijuApp->m_bIgnoreNoteEvent = 0;
+ }
+ pSekaijuApp->SendDifferentStatus (lFlags);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+
+
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『このトラックのみ出力OFF』
+void CSekaijuDoc::OnUpdatePopupTrackOutputOffUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) { // 20100429追加
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『全トラック出力ON』
+void CSekaijuDoc::OnPopupTrackOutputAll () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+ m_theCriticalSection.Lock ();
+
+ // 出力ON/OFF変更処理(履歴記録)
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_ALL_TRACK_OUTPUT_ON));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ MIDITrack* pMIDITrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ VERIFY (pCloneTrack = this->ReplaceMIDITrack (pMIDITrack));
+ MIDITrack_SetOutputOn (pCloneTrack, 1);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ pMIDITrack = pCloneTrack;
+ }
+
+ // 演奏状態復元処理
+ long lCurTime = MIDIClock_GetTickCount (m_pMIDIClock);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pSekaijuApp->ResetTempMIDIStatusArray ();
+ this->TimeMIDIStatus (lCurTime, pSekaijuApp->m_pTempMIDIStatus);
+ long lFlags;
+ // 再生中ならば(a)すべて又は(b)ノートのみを復元する
+ if (pSekaijuApp->m_bPlaying) {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? SDS_ALL : SDS_NOTE;
+ pSekaijuApp->m_bIgnoreNoteEvent = 1;
+ }
+ // 停止中ならば(a)ノートを除くすべてを復元するか(b)何も復元しない
+ else {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? (SDS_ALL & ~SDS_NOTE) : 0;
+ pSekaijuApp->m_bIgnoreNoteEvent = 0;
+ }
+ pSekaijuApp->SendDifferentStatus (lFlags);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+
+
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『全トラック出力ON』
+void CSekaijuDoc::OnUpdatePopupTrackOutputAllUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『切り取り(&T)』
+void CSekaijuDoc::OnPopupCut () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ long lRet = 0;
+ long lCopiedEventCount = 0;
+ BeginWaitCursor ();
+
+ // クリップボードに転送する文字列を作成
+ CString strText;
+ m_theCriticalSection.Lock ();
+ lCopiedEventCount = this->MakeCopyString (strText, 0x0001, NULL);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ if (lCopiedEventCount == 0) {
+ EndWaitCursor ();
+ return;
+ }
+
+ // クリップボードに独自テキストを転送
+ lRet = this->SetClipboardTextPrivate9 (strText);
+ if (lRet == FALSE) {
+ EndWaitCursor ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_WRITE_TO_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // 選択イベントを削除
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_CUT));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = GetCurHistoryUnit ());
+
+ this->DeleteSelectedEvent (pCurHistoryUnit);
+
+ SetModifiedFlag (TRUE);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『切り取り(&T)』
+void CSekaijuDoc::OnUpdatePopupCutUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // ひとつでもMIDIイベントが選択されていればEnable
+ // そうでなければDisableとする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// 『ポップアップ』-『コピー(&C)』
+void CSekaijuDoc::OnPopupCopy () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ long lRet = 0;
+ long lCopiedEventCount = 0;
+ BeginWaitCursor ();
+
+ // クリップボードに転送する文字列を作成
+ CString strText;
+ m_theCriticalSection.Lock ();
+ lCopiedEventCount = this->MakeCopyString (strText, 0x0001, NULL);
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ if (lCopiedEventCount == 0) {
+ EndWaitCursor ();
+ return;
+ }
+
+ // クリップボードに独自テキストを転送
+ lRet = this->SetClipboardTextPrivate9 (strText);
+ if (lRet == FALSE) {
+ EndWaitCursor ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_WRITE_TO_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ EndWaitCursor ();
+}
+
+// 『ポップアップ』-『コピー(&C)』
+void CSekaijuDoc::OnUpdatePopupCopyUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+
+ // ひとつでもMIDIイベントが選択されていればEnable
+ // そうでなければDisableとする
+ m_theCriticalSection.Lock ();
+ long lEnable = 0;
+ MIDITrack* pMIDITrack;
+ MIDIEvent* pMIDIEvent;
+ forEachTrack (m_pMIDIData, pMIDITrack) {
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (this->IsEventSelected (pMIDIEvent)) {
+ lEnable = 1;
+ break;
+ }
+ }
+ if (lEnable) {
+ break;
+ }
+ }
+ pCmdUI->Enable (lEnable);
+ m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『貼り付け(&T)』
+void CSekaijuDoc::OnPopupPaste () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+
+
+ BeginWaitCursor ();
+ CString strMsg;
+
+ // クリップボードのテキストを取得
+ CString strText;
+ long lRet = this->GetClipboardTextPrivate9 (strText);
+ if (lRet == FALSE) {
+ EndWaitCursor ();
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_READ_FROM_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // テキストフォーマット検査
+ if (strText.Left(5) != _T("MDa2 ")) {
+ EndWaitCursor ();
+ VERIFY (strMsg.LoadString (IDS_NO_AVAILABLE_MIDIDATA_IN_THE_CLIPBOARD));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // 貼り付け処理
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_EDIT_PASTE));
+ VERIFY (this->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = this->GetCurHistoryUnit ());
+ m_theCriticalSection.Lock ();
+ long lInsertedEventCount = this->ParsePasteString (strText, m_lTempTrackIndex, m_lTempTime, pCurHistoryUnit);
+ this->SetModifiedFlag (TRUE);
+ this->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ ::Sleep (0);
+
+ // 結果のメッセージボックス表示
+ if (lInsertedEventCount == -1) {
+ VERIFY (strMsg.LoadString (IDS_PASTE_FAILED));
+ }
+ else {
+ CString strFormat;
+ VERIFY (strFormat.LoadString (IDS_D_MIDIEVENTS_WERE_INSERTED));
+ strMsg.Format (strFormat, lInsertedEventCount);
+ }
+ AfxMessageBox (strMsg, MB_ICONINFORMATION);
+}
+
+// 『ポップアップ』-『貼り付け(&T)』
+void CSekaijuDoc::OnUpdatePopupPasteUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ // クリップボードの形式が独自テキストか調べる
+ pCmdUI->Enable (this->IsClipboardTextPrivate9 ());
+
+}
+
+
+
+// 『ポップアップ』-『テンポの挿入...』
+void CSekaijuDoc::OnPopupInsertTempo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ return;
+ }
+
+ CPropertyTempoDlg theDlg;
+ long lTime = m_lTempTime;
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ long lTempo = 60000000 / 120;
+ double dTempoBPM = (double)60000000 / (double)lTempo;
+ theDlg.m_strTempoBPM.Format (_T("%1.2lf"), dTempoBPM);
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+#ifdef UNICODE
+ dTempoBPM = _wtol (theDlg.m_strTempoBPM); // TODO:VC++4.0で_ttofが使えないので仮
+#else
+ dTempoBPM = atof (theDlg.m_strTempoBPM);
+#endif
+ lTempo = (long)(60000000 / CLIP (1, dTempoBPM, 60000));
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+ // イベントの追加
+ VERIFY (pNewEvent = MIDIEvent_CreateTempo (lTime, lTempo));
+ VERIFY (MIDITrack_InsertEvent (m_pTempTrack, pNewEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『テンポの挿入...』
+void CSekaijuDoc::OnUpdatePopupInsertTempoUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『拍子記号の挿入...』
+void CSekaijuDoc::OnPopupInsertTimeSignature () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ return;
+ }
+
+ CPropertyTimeSignatureDlg theDlg;
+ long lTime = m_lTempTime;
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ long lnn, ldd, lcc, lbb;
+ lnn = 4;
+ ldd = 2;
+ lcc = 24;
+ lbb = 8;
+ theDlg.m_lNN = lnn;
+ theDlg.m_nDDIndex = CLIP (0, ldd, 5);
+ theDlg.m_lCC = lcc;
+ theDlg.m_lBB = lbb;
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ lnn = theDlg.m_lNN;
+ ldd = theDlg.m_nDDIndex;
+ lcc = theDlg.m_lCC;
+ lbb = theDlg.m_lBB;
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+ // イベントの追加
+ VERIFY (pNewEvent = MIDIEvent_CreateTimeSignature (lTime, lnn, ldd, lcc, lbb));
+ VERIFY (MIDITrack_InsertEvent (m_pTempTrack, pNewEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『拍子記号の挿入...』
+void CSekaijuDoc::OnUpdatePopupInsertTimeSignatureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+// 『ポップアップ』-『調性記号の挿入...』
+void CSekaijuDoc::OnPopupInsertKeySignature () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ return;
+ }
+
+ CPropertyKeySignatureDlg theDlg;
+ long lTime = m_lTempTime;
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ long lsf, lmi;
+ lsf = 0;
+ lmi = 0;
+ theDlg.m_nSFIndex = lsf + 7;
+ theDlg.m_nMiIndex = CLIP (0, lmi, 1);
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ lsf = theDlg.m_nSFIndex - 7;
+ lmi = theDlg.m_nMiIndex;
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+ // イベントの追加
+ VERIFY (pNewEvent = MIDIEvent_CreateKeySignature (lTime, lsf, lmi));
+ VERIFY (MIDITrack_InsertEvent (m_pTempTrack, pNewEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『調性記号の挿入...』
+void CSekaijuDoc::OnUpdatePopupInsertKeySignatureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+// 『ポップアップ』-『マーカーの挿入...』
+void CSekaijuDoc::OnPopupInsertMarker () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ return;
+ }
+
+ CPropertyMarkerDlg theDlg;
+ long lTime = m_lTempTime;
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ TCHAR szText1[1024];
+ TCHAR szText2[1024];
+ memset (szText1, 0, TSIZEOF (szText1));
+ memset (szText2, 0, TSIZEOF (szText2));
+ theDlg.m_strText = szText2;
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ memset (szText1, 0, TSIZEOF (szText1));
+ memset (szText2, 0, TSIZEOF (szText2));
+ str2codestr ((TCHAR*)(LPCTSTR)(theDlg.m_strText), theDlg.m_strText.GetLength (), szText1, 1023);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+ // イベントの追加
+ VERIFY (pNewEvent = MIDIEvent_CreateMarker (lTime, szText1));
+ VERIFY (MIDITrack_InsertEvent (m_pTempTrack, pNewEvent));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『マーカーの挿入...』
+void CSekaijuDoc::OnUpdatePopupInsertMarkerUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// 『ポップアップ』-『テンポの変更...』
+void CSekaijuDoc::OnPopupModifyTempo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTempoEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsTempo (m_pTempTempoEvent)) {
+ return;
+ }
+
+ CPropertyTempoDlg theDlg;
+ long lTime = MIDIEvent_GetTime (m_pTempTempoEvent);
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ long lTempo = MIDIEvent_GetTempo (m_pTempTempoEvent);
+ double dTempoBPM = (double)60000000 / (double)lTempo;
+ theDlg.m_strTempoBPM.Format (_T("%1.2lf"), dTempoBPM);
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+#ifdef UNICODE
+ dTempoBPM = _wtol (theDlg.m_strTempoBPM); // TODO:VC++4.0で_ttofが使えないので仮
+#else
+ dTempoBPM = atof (theDlg.m_strTempoBPM);
+#endif
+ lTempo = (long)(60000000 / CLIP (1, dTempoBPM, 60000));
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempTempoEvent);
+ VERIFY (pNewEvent = ReplaceMIDIEvent (m_pTempTempoEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetTempo (pNewEvent, lTempo);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『テンポの変更...』
+void CSekaijuDoc::OnUpdatePopupModifyTempoUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTempoEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsTempo (m_pTempTempoEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『拍子記号の変更...』
+void CSekaijuDoc::OnPopupModifyTimeSignature () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTimeSignatureEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsTimeSignature (m_pTempTimeSignatureEvent)) {
+ return;
+ }
+
+ CPropertyTimeSignatureDlg theDlg;
+ long lTime = MIDIEvent_GetTime (m_pTempTimeSignatureEvent);
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (m_pTempTimeSignatureEvent, &lnn, &ldd, &lcc, &lbb);
+ theDlg.m_lNN = lnn;
+ theDlg.m_nDDIndex = CLIP (0, ldd, 5);
+ theDlg.m_lCC = lcc;
+ theDlg.m_lBB = lbb;
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ lnn = theDlg.m_lNN;
+ ldd = theDlg.m_nDDIndex;
+ lcc = theDlg.m_lCC;
+ lbb = theDlg.m_lBB;
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempTimeSignatureEvent);
+ VERIFY (pNewEvent = ReplaceMIDIEvent (m_pTempTimeSignatureEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetTimeSignature (pNewEvent, lnn, ldd, lbb, lcc);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『拍子記号の変更...』
+void CSekaijuDoc::OnUpdatePopupModifyTimeSignatureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTimeSignatureEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsTimeSignature (m_pTempTimeSignatureEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+// 『ポップアップ』-『調性記号の変更...』
+void CSekaijuDoc::OnPopupModifyKeySignature () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempKeySignatureEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsKeySignature (m_pTempKeySignatureEvent)) {
+ return;
+ }
+
+ CPropertyKeySignatureDlg theDlg;
+ long lTime = MIDIEvent_GetTime (m_pTempKeySignatureEvent);
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (m_pTempKeySignatureEvent, &lsf, &lmi);
+ theDlg.m_nSFIndex = lsf + 7;
+ theDlg.m_nMiIndex = CLIP (0, lmi, 1);
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ lsf = theDlg.m_nSFIndex - 7;
+ lmi = theDlg.m_nMiIndex;
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempKeySignatureEvent);
+ VERIFY (pNewEvent = ReplaceMIDIEvent (m_pTempKeySignatureEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetKeySignature (pNewEvent, lsf, lmi);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『調性記号の変更...』
+void CSekaijuDoc::OnUpdatePopupModifyKeySignatureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempKeySignatureEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsKeySignature (m_pTempKeySignatureEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+// 『ポップアップ』-『マーカーの変更...』
+void CSekaijuDoc::OnPopupModifyMarker () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempMarkerEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsMarker (m_pTempMarkerEvent)) {
+ return;
+ }
+
+ CPropertyMarkerDlg theDlg;
+ long lTime = MIDIEvent_GetTime (m_pTempMarkerEvent);
+ CString strTime;
+ LongTimeToStringTime (m_pMIDIData, lTime, &strTime);
+ theDlg.m_strTime = strTime;
+ TCHAR szText1[1024];
+ TCHAR szText2[1024];
+ memset (szText1, 0, TSIZEOF (szText1));
+ memset (szText2, 0, TSIZEOF (szText2));
+ MIDIEvent_GetText (m_pTempMarkerEvent, szText1, 1023);
+ codestr2str (szText1, _tcslen (szText1), szText2, 1023);
+ theDlg.m_strText = szText2;
+ if (theDlg.DoModal () == IDOK) {
+ // タイム文字列をlong型に変換
+ long lErrorID = StringTimeToLongTime (m_pMIDIData, theDlg.m_strTime, &lTime);
+ if (lErrorID != 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (lErrorID));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ memset (szText1, 0, TSIZEOF (szText1));
+ memset (szText2, 0, TSIZEOF (szText2));
+ str2codestr ((TCHAR*)(LPCTSTR)(theDlg.m_strText), theDlg.m_strText.GetLength (), szText1, 1023);
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ MIDIEvent* pNewEvent = NULL;
+ MIDIEvent* pLastEvent = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent));
+ VERIFY (pCloneEvent = ReplaceMIDIEvent (pLastEvent));
+ }
+ }
+
+
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempMarkerEvent);
+ VERIFY (pNewEvent = ReplaceMIDIEvent (m_pTempMarkerEvent));
+ MIDIEvent_SetTime (pNewEvent, lTime);
+ MIDIEvent_SetText (pNewEvent, szText1);
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+
+ // EOTの履歴保持
+ pLastEvent = MIDITrack_GetLastEvent (m_pTempTrack);
+ if (pLastEvent != NULL) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pLastEvent));
+ }
+ }
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+ }
+}
+
+// 『ポップアップ』-『マーカーの変更...』
+void CSekaijuDoc::OnUpdatePopupModifyMarkerUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempMarkerEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsMarker (m_pTempMarkerEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// 『ポップアップ』-『テンポの削除...』
+void CSekaijuDoc::OnPopupDeleteTempo () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTempoEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsTempo (m_pTempTempoEvent)) {
+ return;
+ }
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // イベントの削除
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempTempoEvent);
+ VERIFY (MIDITrack_RemoveEvent (m_pTempTrack, m_pTempTempoEvent));
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『テンポの削除』
+void CSekaijuDoc::OnUpdatePopupDeleteTempoUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTempoEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsTempo (m_pTempTempoEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+// 『ポップアップ』-『拍子記号の削除』
+void CSekaijuDoc::OnPopupDeleteTimeSignature () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempTimeSignatureEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsTimeSignature (m_pTempTimeSignatureEvent)) {
+ return;
+ }
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempTimeSignatureEvent);
+ VERIFY (MIDITrack_RemoveEvent (m_pTempTrack, m_pTempTimeSignatureEvent));
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『拍子記号の削除...』
+void CSekaijuDoc::OnUpdatePopupDeleteTimeSignatureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempTimeSignatureEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsTimeSignature (m_pTempTimeSignatureEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+// 『ポップアップ』-『調性記号の削除...』
+void CSekaijuDoc::OnPopupDeleteKeySignature () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempKeySignatureEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsKeySignature (m_pTempKeySignatureEvent)) {
+ return;
+ }
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // イベントの置換と変更
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempKeySignatureEvent);
+ VERIFY (MIDITrack_RemoveEvent (m_pTempTrack, m_pTempKeySignatureEvent));
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+
+}
+
+// 『ポップアップ』-『調性記号の削除...』
+void CSekaijuDoc::OnUpdatePopupDeleteKeySignatureUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempKeySignatureEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsKeySignature (m_pTempKeySignatureEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
+
+
+// 『ポップアップ』-『マーカーの削除...』
+void CSekaijuDoc::OnPopupDeleteMarker () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ return;
+ }
+ if (m_bEditLocked) {
+ return;
+ }
+ if (m_pTempMarkerEvent == NULL || m_pTempTrack == NULL) {
+ return;
+ }
+ if (!MIDIEvent_IsMarker (m_pTempMarkerEvent)) {
+ return;
+ }
+
+ BeginWaitCursor ();
+ m_theCriticalSection.Lock ();
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_EVENT));
+ AddHistoryUnit (strHistoryName);
+ CHistoryUnit* pCurHistoryUnit = GetCurHistoryUnit ();
+
+ // イベントの削除
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, m_pTempMarkerEvent);
+ VERIFY (MIDITrack_RemoveEvent (m_pTempTrack, m_pTempMarkerEvent));
+
+ m_theCriticalSection.Unlock ();
+ EndWaitCursor ();
+ UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ ::Sleep (0);
+}
+
+// 『ポップアップ』-『マーカーの削除...』
+void CSekaijuDoc::OnUpdatePopupDeleteMarkerUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (pSekaijuApp->m_bRecording ||
+ pSekaijuApp->m_bInplaceEditing ||
+ pSekaijuApp->m_bInplaceListing ||
+ pSekaijuApp->m_bValueUpDowning) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (m_pTempMarkerEvent == NULL || m_pTempTrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ if (!MIDIEvent_IsMarker (m_pTempMarkerEvent)) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+}
diff --git a/src/SekaijuDoc.h b/src/SekaijuDoc.h
new file mode 100644
index 0000000..ff41a89
--- /dev/null
+++ b/src/SekaijuDoc.h
@@ -0,0 +1,320 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ドキュメントクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _SEKAIJUDOC_H_
+#define _SEKAIJUDOC_H_
+
+#define SEKAIJUDOC_ARGB(A,R,G,B) ((A)<<24|(R)<<16|(G)<<8|B)
+
+// UpdateAllViewsに設定するlHintフラグ
+#define SEKAIJUDOC_PLAYSTARTED 0x00000001
+#define SEKAIJUDOC_PLAYSTOPED 0x00000002
+#define SEKAIJUDOC_RECORDSTARTED 0x00000004
+#define SEKAIJUDOC_RECORDSTOPED 0x00000008
+#define SEKAIJUDOC_POSITIONCHANGED 0x00000010
+
+#define SEKAIJUDOC_MIDIDATACHANGED 0x00000100
+#define SEKAIJUDOC_MIDITRACKCHANGED 0x00000200
+#define SEKAIJUDOC_MIDIEVENTCHANGED 0x00000400
+
+// MIDIDataオブジェクトのフラグの意味(pMIDITrack->m_lUserFlag);
+#define MIDIDATA_VISIBLE 0x00000001
+#define MIDIDATA_ENABLE 0x00000002
+#define MIDIDATA_SELECTED 0x00000004
+#define MIDIDATA_ALIVE 0x00000100
+#define MIDIDATA_DEAD 0x00000200
+#define MIDIDATA_RESISTEREDASINSERTED 0x00000400
+#define MIDIDATA_RESISTEREDASREMOVED 0x00000800
+
+// MIDITrackオブジェクトのフラグの意味(pMIDITrack->m_lUserFlag);
+#define MIDITRACK_VISIBLE 0x00000001
+#define MIDITRACK_ENABLE 0x00000002
+#define MIDITRACK_SELECTED 0x00000004
+#define MIDITRACK_ALIVE 0x00000100
+#define MIDITRACK_DEAD 0x00000200
+#define MIDITRACK_RESISTEREDASINSERTED 0x00000400
+#define MIDITRACK_RESISTEREDASREMOVED 0x00000800
+
+// MIDIEventオブジェクトのフラグの意味(pMIDIEvent->m_lUserFlag);
+#define MIDIEVENT_VISIBLE 0x00000001
+#define MIDIEVENT_ENABLE 0x00000002
+#define MIDIEVENT_SELECTED 0x00000004
+#define MIDIEVENT_VIEWMODEDRUM 0x00000008
+#define MIDIEVENT_ALIVE 0x00000100
+#define MIDIEVENT_DEAD 0x00000200
+#define MIDIEVENT_RESISTEREDASINSERTED 0x00000400
+#define MIDIEVENT_RESISTEREDASREMOVED 0x00000800
+
+
+#define SEKAIJUDOC_MODENATIVE 0x00000000 // Native
+#define SEKAIJUDOC_MODEGM1 0x7E000001 // GM1
+#define SEKAIJUDOC_MODEGMOFF 0x7E000002 // GMOff(=Native)
+#define SEKAIJUDOC_MODEGM2 0x7E000003 // GM2
+#define SEKAIJUDOC_MODEGS 0x41000002 // GS
+#define SEKAIJUDOC_MODE88 0x41000003 // 88
+#define SEKAIJUDOC_MODEXG 0x43000002 // XG
+
+class CSekaijuDoc : public CDocument {
+
+ DECLARE_DYNCREATE (CSekaijuDoc)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ MIDIData* m_pMIDIData; // ドキュメントとなるMIDIデータへのポインタ
+ MIDIClock* m_pMIDIClock; // MIDIクロックへのポインタ
+ long m_lOldTime; // 前回の演奏位置時刻(0〜)[tick]
+ long m_lNewTime; // 現在の演奏位置時刻(0〜)[tick]
+ CCriticalSection m_theCriticalSection; // クリティカルセクション(※1)
+public:
+ BOOL m_bEditLocked; // このMIDIデータは編集を禁止されているか?(20100128追加)
+ BOOL m_bSaveLocked; // このMIDIデータは保存を禁止されているか?(20100128追加)
+public:
+ time_t m_tmFileOpenTime; // ファイルを最後に開いた時刻
+ time_t m_tmLastAutoSaveTime; // ファイルを最後に保存した時刻
+public:
+ long m_lTempTime; // 一時的なタイム(0〜)[tick]
+ long m_lTempTrackIndex; // 一時的なトラック番号(0〜65535)
+ MIDIEvent* m_pTempEvent; // 一時的なイベントへのポインタ
+ MIDIEvent* m_pTempTempoEvent; // 一時的なテンポイベントへのポインタ
+ MIDIEvent* m_pTempTimeSignatureEvent; // 一時的な拍子記号イベントへのポインタ
+ MIDIEvent* m_pTempKeySignatureEvent; // 一時的な調性記号イベントへのポインタ
+ MIDIEvent* m_pTempMarkerEvent; // 一時的なマーカーイベントへのポインタ
+ MIDITrack* m_pTempTrack; // 一時的なトラックへのポインタ
+protected:
+ long m_lCurHistoryPosition; // 現在の履歴ユニット番号(0〜)
+ CPtrArray m_theHistoryUnitArray; // 履歴ユニット配列
+ // ※1:メインスレッドと演奏録音用スレッドが同時にこのドキュメントにアクセス(R/W)するのを防ぐ。
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuDoc(); // コンストラクタ
+ virtual ~CSekaijuDoc(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual BOOL OnNewDocument ();
+ virtual BOOL OnOpenDocument (LPCTSTR lpszPathName);
+ virtual BOOL OnSaveDocument (LPCTSTR lpszPathName);
+ virtual void OnCloseDocument ();
+
+ //--------------------------------------------------------------------------
+ // 診断
+ //--------------------------------------------------------------------------
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual BOOL ApplyAppCurSpeedIndex ();
+ virtual void TimeMIDIStatus (long lTargetTime, MIDIStatus* pTempMIDIStatus[]);
+ virtual BOOL SetClipboardTextPrivate9 (CString& strData);
+ virtual BOOL GetClipboardTextPrivate9 (CString& strText);
+ virtual BOOL IsClipboardTextPrivate9 ();
+ virtual long MakeCopyString (CString& strText, long lCopyMode, CHistoryUnit* pHistoryUnit);
+ virtual long ParsePasteString (CString& strData, long lBeginTrackIndex, long lBeginTime, CHistoryUnit* pHistoryUnit);
+ virtual BOOL DeleteSelectedEvent (CHistoryUnit* pHistoryUnit);
+ virtual long SetEventSelected (MIDIEvent* pMIDIEvent, BOOL bSelected);
+ virtual long IsEventSelected (MIDIEvent* pMIDIEvent);
+ virtual long SelectNoObject (CHistoryUnit* pHistoryUnit);
+ virtual long SelectAllObject (CHistoryUnit* pHistoryUnit);
+ virtual MIDIEvent* SelectEvent (MIDIEvent* pMIDIEvent, long bSelected, CHistoryUnit* pHistoryUnit);
+ virtual MIDITrack* SelectTrack (MIDITrack* pMIDITrack, long bSelected, CHistoryUnit* pHistoryUnit);
+ virtual long IsTrackSelected (MIDITrack* pMIDITrack);
+ virtual long SelectTrackMeasure (MIDITrack* pMIDITrack, long lMeasure, long bSelected, CHistoryUnit* pHistoryUnit);
+ virtual long IsTrackMeasureSelected (MIDITrack* pMIDITrack, long lMeasure);
+ virtual long AddDefaultEventToTrack (MIDITrack* pMIDITrack, long lMode, CHistoryUnit* pHistoryUnit);
+ virtual long AddTrack (long lNeedTrackCount, long lMode, CHistoryUnit* pHistoryUnit);
+ virtual MIDITrack* GetTrack (long lIndex);
+ virtual long GetTrackIndex (MIDITrack* pMIDITrack);
+ virtual CString GetTrackName (MIDITrack* pMIDITrack);
+ virtual BOOL SetTrackName (MIDITrack* pMIDITrack, CString strTrackName);
+ virtual long GetTrackVisible (MIDITrack* pMIDITrack);
+ virtual BOOL SetTrackVisible (MIDITrack* pMIDITrack, long lVisible);
+ virtual long GetTrackEnable (MIDITrack* pMIDITrack);
+ virtual BOOL SetTrackEnable (MIDITrack* pMIDITrack, long lEnable);
+ virtual long GetTrackSelected (MIDITrack* pMIDITrack);
+ virtual BOOL SetTrackSelected (MIDITrack* pMIDITrack, long lSelected);
+ virtual MIDIEvent* GetTrackFirstControlChange (MIDITrack* pMIDITrack, long lNumber);
+ virtual MIDIEvent* GetTrackFirstProgramChange (MIDITrack* pMIDITrack);
+ virtual MIDIEvent* FindBankMSB (MIDIEvent* pMIDIEvent);
+ virtual MIDIEvent* FindBankLSB (MIDIEvent* pMIDIEvent);
+ virtual MIDIEvent* FindProgramChange (MIDIEvent* pMIDIEvent);
+ virtual CString GetKeyName (MIDITrack* pMIDITrack, long lTime, long lKey); // 20090501追加
+ virtual BOOL LongTimeToStringMillisec (MIDIData* pMIDIData, long lTime, CString* pstrText); // 20090502追加
+ virtual BOOL LongTimeToStringTime (MIDIData* pMIDIData, long lTime, CString* pstrText); // 20090502追加
+ virtual long StringTimeToLongTime (MIDIData* pMIDIData, CString strText, long* pTime); // 20090502追加
+
+ virtual void ShowTrackListFrame ();
+ virtual void ShowPianoRollFrame ();
+ virtual void ShowEventListFrame ();
+ virtual void ShowMusicalScoreFrame ();
+
+ virtual MIDIEvent* ReplaceMIDIEvent (MIDIEvent* pMIDIEvent);
+ virtual MIDIEvent* DuplicateMIDIEvent (MIDIEvent* pMIDIEvent);
+ virtual MIDITrack* ReplaceMIDITrack (MIDITrack* pMIDITrack);
+ virtual MIDIData* ReplaceMIDIData (MIDIData* pMIDIData);
+
+ virtual BOOL AddHistoryUnit (CString m_strName);
+ virtual CHistoryUnit* GetCurHistoryUnit ();
+ virtual BOOL DeleteAllHistoryUnit ();
+
+
+
+
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnUpdateFileSaveUI (CCmdUI* pCmdUI);
+ afx_msg void OnUpdateFileSaveAsUI (CCmdUI* pCmdUI);
+ afx_msg void OnFileProperty ();
+ afx_msg void OnUpdateFilePropertyUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditUndo ();
+ afx_msg void OnUpdateEditUndoUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditRedo ();
+ afx_msg void OnUpdateEditRedoUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditInitHistory ();
+ afx_msg void OnUpdateEditInitHistoryUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditCut ();
+ afx_msg void OnUpdateEditCutUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditCopy ();
+ afx_msg void OnUpdateEditCopyUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditPaste ();
+ afx_msg void OnUpdateEditPasteUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditDelete ();
+ afx_msg void OnUpdateEditDeleteUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditSelectAll ();
+ afx_msg void OnUpdateEditSelectAllUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditSelectNone ();
+ afx_msg void OnUpdateEditSelectNoneUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditSelectBefore ();
+ afx_msg void OnUpdateEditSelectBeforeUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditDeselectBefore ();
+ afx_msg void OnUpdateEditDeselectBeforeUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditSelectAfter ();
+ afx_msg void OnUpdateEditSelectAfterUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditDeselectAfter ();
+ afx_msg void OnUpdateEditDeselectAfterUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnEditTrack ();
+ afx_msg void OnUpdateEditTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditTime ();
+ afx_msg void OnUpdateEditTimeUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditChannel ();
+ afx_msg void OnUpdateEditChannelUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditKey ();
+ afx_msg void OnUpdateEditKeyUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditVelocity ();
+ afx_msg void OnUpdateEditVelocityUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditDuration ();
+ afx_msg void OnUpdateEditDurationUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditValue ();
+ afx_msg void OnUpdateEditValueUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditQuantize ();
+ afx_msg void OnUpdateEditQuantizeUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditBreakupAndTrill ();
+ afx_msg void OnUpdateEditBreakupAndTrillUI (CCmdUI* pCmdUI);
+ afx_msg void OnEditBeatScan ();
+ afx_msg void OnUpdateEditBeatScanUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnEditInsertMeasure (); // 20100728追加
+ afx_msg void OnUpdateEditInsertMeasureUI (CCmdUI* pCmdUI); // 20100728追加
+ afx_msg void OnEditRemoveMeasure (); // 20100728追加
+ afx_msg void OnUpdateEditRemoveMeasureUI (CCmdUI* pCmdUI); // 20100728追加
+
+ afx_msg void OnViewRedraw ();
+ afx_msg void OnViewTrackList ();
+ afx_msg void OnViewPianoRoll ();
+ afx_msg void OnViewEventList ();
+ afx_msg void OnViewMusicalScore ();
+
+ afx_msg void OnPopupShowTrackList ();
+ afx_msg void OnUpdatePopupShowTrackListUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupShowPianoRoll ();
+ afx_msg void OnUpdatePopupShowPianoRollUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupShowEventList ();
+ afx_msg void OnUpdatePopupShowEventListUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupShowMusicalScore ();
+ afx_msg void OnUpdatePopupShowMusicalScoreUI (CCmdUI* pCmdUI); // 20100429追加
+
+
+ afx_msg void OnPopupTrackInputOn ();
+ afx_msg void OnUpdatePopupTrackInputOnUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackInputOff ();
+ afx_msg void OnUpdatePopupTrackInputOffUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackInputAll ();
+ afx_msg void OnUpdatePopupTrackInputAllUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackOutputOn ();
+ afx_msg void OnUpdatePopupTrackOutputOnUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackOutputOff ();
+ afx_msg void OnUpdatePopupTrackOutputOffUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupTrackOutputAll ();
+ afx_msg void OnUpdatePopupTrackOutputAllUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnPopupCut ();
+ afx_msg void OnUpdatePopupCutUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupCopy ();
+ afx_msg void OnUpdatePopupCopyUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupPaste ();
+ afx_msg void OnUpdatePopupPasteUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnPopupInsertTempo ();
+ afx_msg void OnUpdatePopupInsertTempoUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupInsertTimeSignature ();
+ afx_msg void OnUpdatePopupInsertTimeSignatureUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupInsertKeySignature ();
+ afx_msg void OnUpdatePopupInsertKeySignatureUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupInsertMarker ();
+ afx_msg void OnUpdatePopupInsertMarkerUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnPopupModifyTempo ();
+ afx_msg void OnUpdatePopupModifyTempoUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupModifyTimeSignature ();
+ afx_msg void OnUpdatePopupModifyTimeSignatureUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupModifyKeySignature ();
+ afx_msg void OnUpdatePopupModifyKeySignatureUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupModifyMarker ();
+ afx_msg void OnUpdatePopupModifyMarkerUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnPopupDeleteTempo ();
+ afx_msg void OnUpdatePopupDeleteTempoUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupDeleteTimeSignature ();
+ afx_msg void OnUpdatePopupDeleteTimeSignatureUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupDeleteKeySignature ();
+ afx_msg void OnUpdatePopupDeleteKeySignatureUI (CCmdUI* pCmdUI);
+ afx_msg void OnPopupDeleteMarker ();
+ afx_msg void OnUpdatePopupDeleteMarkerUI (CCmdUI* pCmdUI);
+
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/SekaijuDocManager.cpp b/src/SekaijuDocManager.cpp
new file mode 100644
index 0000000..a537995
--- /dev/null
+++ b/src/SekaijuDocManager.cpp
@@ -0,0 +1,194 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ドキュメントマネージャークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include "resource.h"
+#include "SekaijuDocManager.h"
+#include "SekaijuFileDlg.h"
+
+IMPLEMENT_DYNAMIC (CSekaijuDocManager, CDocManager)
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// CDocManager::DoPromptFileNameのオーバーライド
+BOOL CSekaijuDocManager::DoPromptFileName
+(CString& strFileName, UINT nIDSTitle, DWORD lFlags,
+ BOOL bOpenFileDialog, CDocTemplate* pTemplate) {
+
+ CSekaijuFileDlg theFileDlg (bOpenFileDialog);
+
+ CString strTitle;
+ VERIFY (strTitle.LoadString (nIDSTitle));
+
+ // 注意事項:MSDN2002/4のOPENFILENAME構造体の説明
+ // For compatibility reasons, the Places Bar is hidden if Flags is set to
+ // OFN_ENABLEHOOK and lStructSize is OPENFILENAME_SIZE_VERSION_400.
+ // CFileDialogクラスでは強制的にOFN_ENABLEHOOKでAfxCommDlgProcにフックする。
+
+ // 20081028 : m_ofnの値の設定(76or88)は次による
+ //#ifndef OPENFILENAME_SIZE_VERSION_400
+ // theFileDlg.m_ofn.lStructSize = sizeof(OPENFILENAME); //=76(Windows95/98/ME style)
+ //#else
+ // theFileDlg.m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; //=76(Windows95/98/ME style)
+ //#endif
+
+ #if (_WIN32_WINNT >= 0x0500)
+ theFileDlg.m_ofn.lStructSize = 88; //=88(With placebar)
+ theFileDlg.m_ofn.pvReserved = NULL;
+ theFileDlg.m_ofn.dwReserved = 0;
+ theFileDlg.m_ofn.FlagsEx = 0;
+ #else
+ theFileDlg.m_ofn.lStructSize = 76; //=76(Without placebar if OFN_ENABLEHOOK used)
+ #endif
+
+ theFileDlg.m_ofn.nMaxFileTitle = _MAX_PATH;
+
+ theFileDlg.m_ofn.Flags |= lFlags;
+
+ // 拡張子フィルター
+ CString strFilter;
+ CString strDefault;
+ CString strFilterAllMIDI[3];
+ CString strFilterSKJ[3];
+ CString strFilterCHY[3];
+ CString strFilterMID[3];
+ CString strFilterCSV[3];
+ CString strFilterVSQ[3];
+ CString strFilterAll[3];
+ VERIFY (strFilterAllMIDI[0].LoadString (IDS_ALL_MIDI_SEQUENCE_AD_SKJ_AD_CHY_AD_MID_AD_VSQ));
+ VERIFY (strFilterAllMIDI[1].LoadString (IDS_AD_SKJ_AD_CHY_AD_MID_AD_VSQ));
+ VERIFY (strFilterSKJ[0].LoadString (IDS_SEKAIJU_SEQUENCE_FILES_AD_SKJ));
+ VERIFY (strFilterSKJ[1].LoadString (IDS_AD_SKJ));
+ VERIFY (strFilterSKJ[2].LoadString (IDS_D_SKJ));
+ VERIFY (strFilterCHY[0].LoadString (IDS_CHERRY_SEQUENCE_FILES_AD_CHY));
+ VERIFY (strFilterCHY[1].LoadString (IDS_AD_CHY));
+ VERIFY (strFilterCHY[2].LoadString (IDS_D_CHY));
+ VERIFY (strFilterMID[0].LoadString (IDS_STANDARD_MIDI_FILES_AD_MID));
+ VERIFY (strFilterMID[1].LoadString (IDS_AD_MID));
+ VERIFY (strFilterMID[2].LoadString (IDS_D_MID));
+ VERIFY (strFilterCSV[0].LoadString (IDS_MIDI_CSV_FILES_AD_CSV));
+ VERIFY (strFilterCSV[1].LoadString (IDS_AD_CSV));
+ VERIFY (strFilterCSV[2].LoadString (IDS_D_CSV));
+ VERIFY (strFilterVSQ[0].LoadString (IDS_VOCALOID2_FILES_AD_VSQ));
+ VERIFY (strFilterVSQ[1].LoadString (IDS_AD_VSQ));
+ VERIFY (strFilterVSQ[2].LoadString (IDS_D_VSQ));
+ VERIFY (strFilterAll[0].LoadString (IDS_ALL_FILES_AD_A));
+ VERIFY (strFilterAll[1].LoadString (IDS_AD_A));
+
+ // 拡張子フィルター追加設定
+ if (bOpenFileDialog == TRUE) {
+ strFilter += strFilterAllMIDI[0]; // すべてのMIDIシーケンス(*.skj;*.chy;*.mid;*.csv;*.vsq)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterAllMIDI[1]; // *.skj;*.chy;*.mid;*.csv;*.vsq
+ strFilter += (TCHAR)_T('\0');
+ }
+ strFilter += strFilterSKJ[0]; // すべてのMIDIシーケンス(*.skj)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterSKJ[1]; // *.skj
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterCHY[0]; // Cherryシーケンスファイル(*.chy)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterCHY[1]; // *.chy
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterMID[0]; // スタンダードMIDIファイル(*.mid)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterMID[1]; // *.mid
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterCSV[0]; // MIDICSVファイル(*.csv)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterCSV[1]; // *.csv
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterVSQ[0]; // vocaloid2ファイル(*.vsq)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterVSQ[1]; // *.vsq
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterAll[0]; // すべてのファイル(*.*)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterAll[1]; // *.*
+ strFilter += (TCHAR)_T('\0');
+ strFilter += (TCHAR)_T('\0');
+ theFileDlg.m_ofn.nMaxCustFilter = 1024;
+
+ theFileDlg.m_ofn.lpstrFilter = strFilter;
+#ifndef _MAC
+ theFileDlg.m_ofn.lpstrTitle = strTitle;
+#else
+ theFileDlg.m_ofn.lpstrPrompt = strTitle;
+#endif
+
+ // デフォルトの拡張子を設定
+ theFileDlg.m_strDefExt = strFilterSKJ[1]; // *.skj
+ theFileDlg.m_ofn.lpstrDefExt = theFileDlg.m_strDefExt;
+
+ // フィルターコンボボックスのデフォルト選択(20100613修正)
+ CString strExt = strFileName.Right (4);
+ if (strExt.CompareNoCase (strFilterSKJ[1].Right(4)) == 0) { // *.skj
+ theFileDlg.m_ofn.nFilterIndex = 1;
+ }
+ else if (strExt.CompareNoCase (strFilterCHY[1].Right(4)) == 0) { // *.chy
+ theFileDlg.m_ofn.nFilterIndex = 2;
+ }
+ else if (strExt.CompareNoCase (strFilterMID[1].Right(4)) == 0) { // *.mid
+ theFileDlg.m_ofn.nFilterIndex = 3;
+ }
+ else if (strExt.CompareNoCase (strFilterCSV[1].Right(4)) == 0) { // *.csv
+ theFileDlg.m_ofn.nFilterIndex = 4;
+ }
+ else if (strExt.CompareNoCase (strFilterVSQ[1].Right(4)) == 0) { // *.vsq
+ theFileDlg.m_ofn.nFilterIndex = 5;
+ }
+
+ theFileDlg.m_ofn.lpstrFile = strFileName.GetBuffer(_MAX_PATH);
+
+ // ファイルダイアログ.DoModal
+ BOOL bResult = theFileDlg.DoModal() == IDOK ? TRUE : FALSE;
+
+ strFileName.ReleaseBuffer();
+
+ // 拡張子が付いていない場合は、選択したファイルタイプの拡張子を自動的に付ける
+ if (bOpenFileDialog == FALSE) {
+ if (theFileDlg.m_ofn.nFilterIndex == 1 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterSKJ[2]) != 0) { // .skj
+ strFileName += strFilterSKJ[2];
+ }
+ else if (theFileDlg.m_ofn.nFilterIndex == 2 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterCHY[2]) != 0) { // .chy
+ strFileName += strFilterCHY[2];
+ }
+ else if (theFileDlg.m_ofn.nFilterIndex == 3 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterMID[2]) != 0) { // .mid
+ strFileName += strFilterMID[2];
+ }
+ else if (theFileDlg.m_ofn.nFilterIndex == 4 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterCSV[2]) != 0) { // .csv
+ strFileName += strFilterCSV[2];
+ }
+ else if (theFileDlg.m_ofn.nFilterIndex == 5 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterVSQ[2]) != 0) { // .vsq
+ strFileName += strFilterVSQ[2];
+ }
+ }
+
+ return bResult;
+}
diff --git a/src/SekaijuDocManager.h b/src/SekaijuDocManager.h
new file mode 100644
index 0000000..dab1ab7
--- /dev/null
+++ b/src/SekaijuDocManager.h
@@ -0,0 +1,37 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ドキュメントマネージャークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _SEKAIJUDOCMANAGER_H_
+#define _SEKAIJUDOCMANAGER_H_
+
+class CSekaijuDocManager : public CDocManager {
+
+ DECLARE_DYNAMIC (CSekaijuDocManager)
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual BOOL DoPromptFileName(CString& fileName, UINT nIDSTitle,
+ DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
+
+};
+
+#endif
diff --git a/src/SekaijuDocTemplate.cpp b/src/SekaijuDocTemplate.cpp
new file mode 100644
index 0000000..9bca05d
--- /dev/null
+++ b/src/SekaijuDocTemplate.cpp
@@ -0,0 +1,282 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ドキュメントテンプレートクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuDocTemplate.h"
+#include "SekaijuToolBar.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "PianoRollFrame.h"
+#include "EventListFrame.h"
+#include "MusicalScoreFrame.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CSekaijuDocTemplate::CSekaijuDocTemplate (UINT nIDResource,
+ CRuntimeClass* pDocClass, CRuntimeClass* pFrameClass,
+ CRuntimeClass* pViewClass)
+ : CMultiDocTemplate (nIDResource, pDocClass, pFrameClass, pViewClass) {
+ ASSERT (m_docList.IsEmpty());
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// トラックリストフレームウィンドウの生成
+CFrameWnd* CSekaijuDocTemplate::CreateTrackListFrame (CDocument* pDoc) {
+ if (pDoc != NULL) {
+ ASSERT_VALID(pDoc);
+ }
+ ASSERT (m_nIDResource != 0);
+ CCreateContext context;
+ context.m_pCurrentFrame = NULL;
+ context.m_pCurrentDoc = pDoc;
+ context.m_pNewViewClass = m_pViewClass;
+ context.m_pNewDocTemplate = this;
+
+ CRuntimeClass* m_pOldFrameClass = m_pFrameClass;
+ m_pFrameClass = RUNTIME_CLASS (CTrackListFrame);
+ if (m_pFrameClass == NULL) {
+ TRACE0 ("Error: you must override CDocTemplate::CreateTrackListFrame.\n");
+ ASSERT (FALSE);
+ return NULL;
+ }
+ CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
+ if (pFrame == NULL) {
+ TRACE1 ("Warning: Dynamic create of frame %hs failed.\n",
+ m_pFrameClass->m_lpszClassName);
+ return NULL;
+ }
+ ASSERT_KINDOF(CFrameWnd, pFrame);
+
+ if (context.m_pNewViewClass == NULL) {
+ TRACE0 ("Warning: creating frame with no default view.\n");
+ }
+ // create new from resource
+ if (!pFrame->LoadFrame(m_nIDResource,
+ WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles
+ NULL, &context))
+ {
+ TRACE0 ("Warning: CDocTemplate couldn't create a frame.\n");
+ // frame will be deleted in PostNcDestroy cleanup
+ return NULL;
+ }
+
+ m_pFrameClass = m_pOldFrameClass;
+ return pFrame;
+
+}
+
+
+// ピアノロールフレームウィンドウの生成
+CFrameWnd* CSekaijuDocTemplate::CreatePianoRollFrame (CDocument* pDoc) {
+ if (pDoc != NULL) {
+ ASSERT_VALID(pDoc);
+ }
+ ASSERT (m_nIDResource != 0);
+ CCreateContext context;
+ context.m_pCurrentFrame = NULL;
+ context.m_pCurrentDoc = pDoc;
+ context.m_pNewViewClass = m_pViewClass;
+ context.m_pNewDocTemplate = this;
+
+ CRuntimeClass* m_pOldFrameClass = m_pFrameClass;
+ m_pFrameClass = RUNTIME_CLASS (CPianoRollFrame);
+ if (m_pFrameClass == NULL) {
+ TRACE0 ("Error: you must override CDocTemplate::CreatePianoRollFrame.\n");
+ ASSERT (FALSE);
+ return NULL;
+ }
+ CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
+ if (pFrame == NULL) {
+ TRACE1 ("Warning: Dynamic create of frame %hs failed.\n",
+ m_pFrameClass->m_lpszClassName);
+ return NULL;
+ }
+ ASSERT_KINDOF(CFrameWnd, pFrame);
+
+ if (context.m_pNewViewClass == NULL) {
+ TRACE0 ("Warning: creating frame with no default view.\n");
+ }
+ // create new from resource
+ if (!pFrame->LoadFrame(m_nIDResource,
+ WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles
+ NULL, &context))
+ {
+ TRACE0 ("Warning: CDocTemplate couldn't create a frame.\n");
+ // frame will be deleted in PostNcDestroy cleanup
+ return NULL;
+ }
+
+ m_pFrameClass = m_pOldFrameClass;
+ return pFrame;
+
+}
+
+// イベントリストフレームウィンドウの生成
+CFrameWnd* CSekaijuDocTemplate::CreateEventListFrame (CDocument* pDoc) {
+ if (pDoc != NULL) {
+ ASSERT_VALID(pDoc);
+ }
+ ASSERT (m_nIDResource != 0);
+ CCreateContext context;
+ context.m_pCurrentFrame = NULL;
+ context.m_pCurrentDoc = pDoc;
+ context.m_pNewViewClass = m_pViewClass;
+ context.m_pNewDocTemplate = this;
+
+ CRuntimeClass* m_pOldFrameClass = m_pFrameClass;
+ m_pFrameClass = RUNTIME_CLASS (CEventListFrame);
+ if (m_pFrameClass == NULL) {
+ TRACE0 ("Error: you must override CDocTemplate::CreateEventListFrame.\n");
+ ASSERT(FALSE);
+ return NULL;
+ }
+ CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
+ if (pFrame == NULL) {
+ TRACE1 ("Warning: Dynamic create of frame %hs failed.\n",
+ m_pFrameClass->m_lpszClassName);
+ return NULL;
+ }
+ ASSERT_KINDOF(CFrameWnd, pFrame);
+
+ if (context.m_pNewViewClass == NULL) {
+ TRACE0 ("Warning: creating frame with no default view.\n");
+ }
+ // create new from resource
+ if (!pFrame->LoadFrame(m_nIDResource,
+ WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles
+ NULL, &context))
+ {
+ TRACE0("Warning: CDocTemplate couldn't create a frame.\n");
+ // frame will be deleted in PostNcDestroy cleanup
+ return NULL;
+ }
+
+ m_pFrameClass = m_pOldFrameClass;
+ return pFrame;
+
+}
+
+// 譜面フレームウィンドウの生成
+CFrameWnd* CSekaijuDocTemplate::CreateMusicalScoreFrame (CDocument* pDoc) {
+ if (pDoc != NULL) {
+ ASSERT_VALID(pDoc);
+ }
+ ASSERT (m_nIDResource != 0);
+ CCreateContext context;
+ context.m_pCurrentFrame = NULL;
+ context.m_pCurrentDoc = pDoc;
+ context.m_pNewViewClass = m_pViewClass;
+ context.m_pNewDocTemplate = this;
+
+ CRuntimeClass* m_pOldFrameClass = m_pFrameClass;
+ m_pFrameClass = RUNTIME_CLASS (CMusicalScoreFrame);
+ if (m_pFrameClass == NULL) {
+ TRACE0 ("Error: you must override CDocTemplate::CreateMusicalScoreFrame.\n");
+ ASSERT(FALSE);
+ return NULL;
+ }
+ CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
+ if (pFrame == NULL) {
+ TRACE1 ("Warning: Dynamic create of frame %hs failed.\n",
+ m_pFrameClass->m_lpszClassName);
+ return NULL;
+ }
+ ASSERT_KINDOF(CFrameWnd, pFrame);
+
+ if (context.m_pNewViewClass == NULL) {
+ TRACE0 ("Warning: creating frame with no default view.\n");
+ }
+ // create new from resource
+ if (!pFrame->LoadFrame(m_nIDResource,
+ WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles
+ NULL, &context))
+ {
+ TRACE0("Warning: CDocTemplate couldn't create a frame.\n");
+ // frame will be deleted in PostNcDestroy cleanup
+ return NULL;
+ }
+
+ m_pFrameClass = m_pOldFrameClass;
+ return pFrame;
+
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// このドキュメントテンプレートのすべてのドキュメントのビューを更新
+void CSekaijuDocTemplate::UpdateAllViews (CView* pSender, LPARAM lHint, CObject* pHint) {
+ POSITION pos2 = this->GetFirstDocPosition ();
+ while (pos2) {
+ CDocument* pDocument = this->GetNextDoc (pos2);
+ pDocument->UpdateAllViews (pSender, lHint, pHint);
+ }
+}
+
+// MIDIデータの新規作成、又はMIDIデータを開く時
+CDocument* CSekaijuDocTemplate::OpenDocumentFile (LPCTSTR lpszPathName, BOOL bMakeVisible) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 複数のMIDIデータを開くことを許可していない場合
+ if (!pSekaijuApp->m_theGeneralOption.m_bEnableMultiOpen) {
+ // 既存の開いているMIDIデータをすべて閉じる。
+ POSITION pos = GetFirstDocPosition ();
+ while (pos != NULL) {
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(GetNextDoc (pos));
+ if (!pSekaijuDoc->SaveModified ()) {
+ return pSekaijuDoc;
+ }
+ pSekaijuDoc->OnCloseDocument ();
+ }
+ }
+ // 通常の処理
+ return CMultiDocTemplate::OpenDocumentFile (lpszPathName, bMakeVisible);
+}
+
+
+IMPLEMENT_DYNAMIC (CSekaijuDocTemplate, CMultiDocTemplate)
+
diff --git a/src/SekaijuDocTemplate.h b/src/SekaijuDocTemplate.h
new file mode 100644
index 0000000..8c152f9
--- /dev/null
+++ b/src/SekaijuDocTemplate.h
@@ -0,0 +1,51 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ドキュメントテンプレートクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _SEKAIJUDOCTEMPLETE_H_
+#define _SEKAIJUDOCTEMPLETE_H_
+
+class CSekaijuDocTemplate : public CMultiDocTemplate {
+ DECLARE_DYNAMIC (CSekaijuDocTemplate)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+ // コンストラクタ
+public:
+ CSekaijuDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
+ CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+ CFrameWnd* CreateTrackListFrame (CDocument* pDoc);
+ CFrameWnd* CreatePianoRollFrame (CDocument* pDoc);
+ CFrameWnd* CreateEventListFrame (CDocument* pDoc);
+ CFrameWnd* CreateMusicalScoreFrame (CDocument* pDoc);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+ virtual void UpdateAllViews (CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL);
+ virtual CDocument* OpenDocumentFile (LPCTSTR lpszPathName, BOOL bMakeVisible = TRUE);
+
+};
+
+#endif
diff --git a/src/SekaijuFileDlg.cpp b/src/SekaijuFileDlg.cpp
new file mode 100644
index 0000000..6f6db3f
--- /dev/null
+++ b/src/SekaijuFileDlg.cpp
@@ -0,0 +1,117 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ファイルダイアログクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+#include <afxdlgs.h>
+#include <dlgs.h> // for standard control IDs for commdlg
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+#include "SekaijuFileDlg.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+#define new DEBUG_NEW
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ1
+CSekaijuFileDlg::CSekaijuFileDlg (BOOL bOpenFileDialog) :
+ //20091018修正:MFC8.0以前においては、次のデフォルトコンストラクタを使用する。
+ CFileDialog (bOpenFileDialog) {
+ //20091018修正:MFC9.0において、CFileDialogのm_bVistaStyleに強制的にFALSEを指定する。
+ //CFileDialog (bOpenFileDialog, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
+ // NULL, NULL, 0, FALSE) {;
+}
+
+// コンストラクタ2
+CSekaijuFileDlg::CSekaijuFileDlg (BOOL bOpenFileDialog,
+ LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags,
+ LPCTSTR lpszFilter, CWnd* pParentWnd) :
+ //20091018修正:MFC8.0以前においては、次のデフォルトコンストラクタを使用する。
+ CFileDialog (bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd) {
+ //20091018修正:MFC9.0において、CFileDialogのm_bVistaStyleに強制的にFALSEを指定する。
+ //CFileDialog (bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd,
+ // 0, FALSE) {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 注意事項:MSDN2002/4のOPENFILENAME構造体の説明
+// For compatibility reasons, the Places Bar is hidden if Flags is set to
+// OFN_ENABLEHOOK and lStructSize is OPENFILENAME_SIZE_VERSION_400.
+
+//int CSekaijuFileDlg::DoModal () {
+ //m_ofn.Flags |= OFN_EXPLORER | OFN_ENABLEHOOK;
+ //m_ofn.lpfnHook = (LPOFNHOOKPROC) SaveAsHookProc;
+ //if (m_bOpenFileDialog) {
+ // return ::GetOpenFileName (&m_ofn);
+ //}
+ //else {
+ // return ::GetSaveFileName (&m_ofn);
+ //}
+//}
+
+
+// ファイルタイプコンボボックスが変更されたとき
+void CSekaijuFileDlg::OnTypeChange () {
+ // 注意:m_ofn.lFlagsにOFN_EXPLOLER(0x00080000)を追加しておくこと。
+ // 保存用ファイルダイアログのみ
+ if (!m_bOpenFileDialog) {
+ // ファイル名の拡張子をファイルタイプコンボボックス(0x047c)で選択した拡張子に書き換える。
+ CString strFileTitle = GetFileTitle ();
+ if (!strFileTitle.IsEmpty ()) {
+ CString strExt;
+ if (AfxExtractSubString (strExt, m_ofn.lpstrFilter, 2 * m_ofn.nFilterIndex - 1, (TCHAR)'\0')) {
+ LPTSTR pszExtension = _tcschr ((LPTSTR)(LPCTSTR)strExt, _T('.'));//PathFindExtension (strExt);
+ if (_tcscmp (pszExtension, _T(".*")) != 0 && TCSLEN (pszExtension) >= 2) {
+ // 拡張子を入力しなかった場合に自動的に付加される拡張子を変更
+ m_strDefExt = CString (pszExtension + 1);
+ m_ofn.lpstrDefExt = m_strDefExt;
+ // ファイル名コンボボックスの拡張子を自動変更
+ CString strText = strFileTitle + pszExtension;
+ //if (!m_bVistaSytle) {
+ SetControlText (0x047c, (LPSTR)(LPCTSTR)strText);
+ // 注意:0x047cはWindows2000/XPスタイルのファイルダイアログにおけるファイル名ID
+ SetControlText (0x0480, (LPSTR)(LPCTSTR)strText);
+ // 注意:0x0480はWindows95/98/MEスタイルのファイルダイアログにおけるファイル名ID
+ // TODO:ここにWindowsVistaスタイルのファイルダイアログにおけるファイル名IDを記述。
+ // (名前をつけて保存ダイアログの中身のコントロールIDをspy++で調べる)
+ //}
+ }
+ }
+ }
+ }
+ CFileDialog::OnTypeChange ();
+}
+
diff --git a/src/SekaijuFileDlg.h b/src/SekaijuFileDlg.h
new file mode 100644
index 0000000..0ce157c
--- /dev/null
+++ b/src/SekaijuFileDlg.h
@@ -0,0 +1,52 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ファイルダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _SEKAIJUFILEDLG_H_
+#define _SEKAIJUFILEDLG_H_
+
+class CSekaijuFileDlg : public CFileDialog {
+
+ //DECLARE_DYNAMIC (CSekaijuFileDlg)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+ // コンストラクタ
+public:
+ CSekaijuFileDlg (BOOL bOpenFileDialog);
+ CSekaijuFileDlg (BOOL bOpenFileDialog,
+ LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags,
+ LPCTSTR lpszFilter, CWnd* pParentWnd);
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ CString m_strDefExt; // デフォルトの拡張子(ファイルタイプを切り替えるたびに更新)
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ //virtual int DoModal ();
+ virtual void OnTypeChange (); // ファイルタイプが変更された
+};
+
+#endif
diff --git a/src/SekaijuStatusBar.cpp b/src/SekaijuStatusBar.cpp
new file mode 100644
index 0000000..091b413
--- /dev/null
+++ b/src/SekaijuStatusBar.cpp
@@ -0,0 +1,108 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ステータスバークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "Resource.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "SekaijuDoc.h"
+
+
+
+
+// デバッグ用
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNAMIC (CSekaijuStatusBar, CStatusBar)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CSekaijuStatusBar, CStatusBar)
+ ON_WM_LBUTTONDBLCLK ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CSekaijuStatusBar::CSekaijuStatusBar () {
+}
+
+// デストラクタ
+CSekaijuStatusBar::~CSekaijuStatusBar () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+void CSekaijuStatusBar::OnLButtonDblClk (UINT nFlags, CPoint point) {
+ CDC* pDC = GetDC ();
+ CRect rcItem;
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ long i = 0;
+ for (i = 0; i < 6; i++) {
+ GetItemRect (i, &rcItem);
+ if (rcItem.PtInRect (point)) {
+ break;
+ }
+ }
+ switch (i) {
+ case 0:
+ break;
+ case 1: // フォーマット
+ case 2: // トラック数
+ case 3: // タイムベース
+ pMainFrame->PostMessage (WM_COMMAND, ID_FILE_PROPERTY);
+ break;
+ case 4: // 入力ベロシティゲージ
+ pSekaijuApp->m_theCurrentPage.m_lMIDIDevice = 0;
+ pMainFrame->PostMessage (WM_COMMAND, ID_SETUP_MIDIDEVICE);
+ break;
+ case 5: // 出力ベロシティゲージ
+ pSekaijuApp->m_theCurrentPage.m_lMIDIDevice = 1;
+ pMainFrame->PostMessage (WM_COMMAND, ID_SETUP_MIDIDEVICE);
+ break;
+ }
+}
+
+
+
diff --git a/src/SekaijuToolBar.cpp b/src/SekaijuToolBar.cpp
new file mode 100644
index 0000000..eba9e8a
--- /dev/null
+++ b/src/SekaijuToolBar.cpp
@@ -0,0 +1,174 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ツールバークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "Resource.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "SekaijuDoc.h"
+
+
+
+
+// デバッグ用
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNAMIC (CSekaijuToolBar, CToolBar)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CSekaijuToolBar, CToolBar)
+ ON_WM_NCPAINT()
+ ON_WM_HSCROLL ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CSekaijuToolBar::CSekaijuToolBar () {
+}
+
+// デストラクタ
+CSekaijuToolBar::~CSekaijuToolBar () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// http://support.microsoft.com/kb/843490/jaの問題に対応
+void CSekaijuToolBar::EraseNonClient () {
+ // Get window DC that is clipped to the non-client area.
+ CWindowDC dc(this);
+ CRect rectClient;
+ GetClientRect(rectClient);
+ CRect rectWindow;
+ GetWindowRect(rectWindow);
+ ScreenToClient(rectWindow);
+ rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
+ dc.ExcludeClipRect(rectClient);
+
+ // Draw the borders in the non-client area.
+ rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
+ DrawBorders(&dc, rectWindow);
+
+ // Erase the parts that are not drawn.
+ dc.IntersectClipRect(rectWindow);
+ SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC);
+
+ // Draw the gripper in the non-client area.
+ DrawGripper(&dc, rectWindow);
+}
+
+// http://support.microsoft.com/kb/843490/jaの問題に対応
+void CSekaijuToolBar::DoPaint (CDC* pDC) {
+ ASSERT_VALID(this);
+ ASSERT_VALID(pDC);
+
+ // Paint inside the client area.
+ CRect rect;
+ GetClientRect(rect);
+ DrawBorders(pDC, rect);
+ DrawGripper(pDC, rect);
+}
+
+// http://support.microsoft.com/kb/843490/jaの問題に対応
+void CSekaijuToolBar::DrawGripper (CDC* pDC, const CRect& rect) {
+ pDC->FillSolidRect( &rect, ::GetSysColor(COLOR_BTNFACE)); // Fill in the background.
+ //CToolBar::DrawGripper(pDC,rect); //VC++4.0std(MFC4.0)では未対応
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// http://support.microsoft.com/kb/843490/jaの問題に対応
+void CSekaijuToolBar::OnNcPaint() {
+ Invalidate (TRUE); // VC++4.0std(MFC4.0)でツールバーが再描画されないのを防止
+ EraseNonClient();
+}
+
+// 位置スクロールバーを動かしたときの挙動
+void CSekaijuToolBar::OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ if (pMainFrame == NULL) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)(pMainFrame->GetActiveFrame ()->GetActiveDocument());
+ if (pSekaijuDoc == NULL) {
+ return;
+ }
+ if (pScrollBar == &(pMainFrame->m_wndPositionScroll)) {
+ switch (nSBCode) {
+ case SB_LINELEFT:
+ pMainFrame->SendMessage (WM_COMMAND, ID_CONTROL_PREVBEAT, 0);
+ break;
+ case SB_LINERIGHT:
+ pMainFrame->SendMessage (WM_COMMAND, ID_CONTROL_NEXTBEAT, 0);
+ break;
+ case SB_PAGELEFT:
+ pMainFrame->SendMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE, 0);
+ break;
+ case SB_PAGERIGHT:
+ pMainFrame->SendMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE, 0);
+ break;
+ case SB_LEFT: // 20090220追加
+ pMainFrame->SendMessage (WM_COMMAND, ID_CONTROL_TOBEGIN, 0);
+ break;
+ case SB_RIGHT: // 20090220追加
+ pMainFrame->SendMessage (WM_COMMAND, ID_CONTROL_TOEND, 0);
+ break;
+ case SB_THUMBTRACK:
+ if (!pSekaijuApp->m_bRecording) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllHold1Off ();
+ pSekaijuApp->SendAllSostenutoOff ();
+ pSekaijuApp->SendAllHold2Off ();
+ pSekaijuApp->SendAllSoundOff ();
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, nPos);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_POSITIONCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+ break;
+ }
+
+ }
+}
+
diff --git a/src/SekaijuView.cpp b/src/SekaijuView.cpp
new file mode 100644
index 0000000..e67988f
--- /dev/null
+++ b/src/SekaijuView.cpp
@@ -0,0 +1,87 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+// このクラスの役割はCSekaijuDoc* GetDocument()を提供することのみであり、
+// 実用的なビューはCSekaijuViewから派生させて作ること。
+// なお、このクラスはVisible=FALSEのダミービューとしても使える。
+
+#include "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE (CSekaijuView, CView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CSekaijuView, CView)
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CSekaijuView::CSekaijuView() {
+}
+
+// デストラクタ
+CSekaijuView::~CSekaijuView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウスタイルの変更
+BOOL CSekaijuView::PreCreateWindow (CREATESTRUCT& cs) {
+ return CView::PreCreateWindow (cs);
+}
+
+// 描画(ダミー)
+void CSekaijuView::OnDraw (CDC* pDC) {
+ ASSERT_VALID (GetDocument());
+}
+
+// GetDocument(非デバッグ バージョンはインラインです。)
+#ifdef _DEBUG
+CSekaijuDoc* CSekaijuView::GetDocument () {
+ ASSERT (m_pDocument->IsKindOf(RUNTIME_CLASS(CSekaijuDoc)));
+ return (CSekaijuDoc*)m_pDocument;
+}
+
+#endif
diff --git a/src/SekaijuView.h b/src/SekaijuView.h
new file mode 100644
index 0000000..3c23e47
--- /dev/null
+++ b/src/SekaijuView.h
@@ -0,0 +1,66 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// ビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+// このクラスの役割はCSekaijuDoc* GetDocument()を提供することのみであり、
+// 実用的なビューはCSekaijuViewから派生させて作ること。
+// なお、このクラスはVisible=FALSEのダミービューとしても使える。
+
+#ifndef _SEKAIJUVIEW_H_
+#define _SEKAIJUVIEW_H_
+
+class CSekaijuView : public CView {
+ DECLARE_DYNCREATE(CSekaijuView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuView (); // コンストラクタ
+ virtual ~CSekaijuView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuDoc* GetDocument (); // ドキュメントの取得
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnDraw (CDC* pDC);
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+#ifndef _DEBUG
+inline CSekaijuDoc* CSekaijuView::GetDocument () {
+ return (CSekaijuDoc*)m_pDocument;
+}
+#endif
+
+
+
+#endif
diff --git a/src/TrackListBox.cpp b/src/TrackListBox.cpp
new file mode 100644
index 0000000..3814b2f
--- /dev/null
+++ b/src/TrackListBox.cpp
@@ -0,0 +1,131 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストボックスクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "resource.h"
+#include "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxcmn.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuDoc.h"
+#include "ColorfulCheckListBox.h"
+#include "TrackListBox.h"
+
+// TSIZEOFマクロ //20120211追加
+#ifndef TSIZEOF
+#define TSIZEOF(STR) (sizeof(STR)/sizeof(TCHAR))
+#endif
+#ifndef TCSLEN
+#ifdef UNICODE
+#define TCSLEN(STRING) wcslen(STRING)
+#else
+#define TCSLEN(STRING) strlen(STRING)
+#endif
+#endif
+#ifndef TCSNCPY
+#ifdef UNICODE
+#define TCSNCPY(STRING1,STRING2,N) wcsncpy(STRING1,STRING2,N)
+#else
+#define TCSNCPY(STRING1,STRING2,N) strncpy(STRING1,STRING2,N)
+#endif
+#endif
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE (CTrackListBox, CColorfulCheckListBox)
+
+BEGIN_MESSAGE_MAP (CTrackListBox, CColorfulCheckListBox)
+ ON_WM_RBUTTONDOWN ()
+END_MESSAGE_MAP ()
+
+
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListBox::CTrackListBox () {
+ m_pDocument = NULL;
+ m_lMenuID = 0;
+ CColorfulCheckListBox::CColorfulCheckListBox ();
+}
+
+// コンストラクタ
+CTrackListBox::CTrackListBox (CDocument* pDocument, long lMenuID) {
+ m_pDocument = pDocument;
+ m_lMenuID = lMenuID;
+ CColorfulCheckListBox::CColorfulCheckListBox ();
+}
+
+// デストラクタ
+CTrackListBox::~CTrackListBox () {
+ CColorfulCheckListBox::~CColorfulCheckListBox ();
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+CSekaijuDoc* CTrackListBox::GetDocument () {
+ return (CSekaijuDoc*)m_pDocument;
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// マウス右ボタン押された時
+void CTrackListBox::OnRButtonDown (UINT nFlags, CPoint point) {
+ this->SetFocus ();
+ if (m_lMenuID == 0) {
+ return;
+ }
+ BOOL bOutside;
+ long lIndex = this->ItemFromPoint (point, bOutside);
+ if (bOutside) {
+ return;
+ }
+ if (lIndex < 0 || lIndex >= GetCount ()) {
+ return;
+ }
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_pTempTrack = pSekaijuDoc->GetTrack (lIndex);
+ // ポップアップメニュー表示
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (m_lMenuID));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, GetParentFrame ());
+}
+
+
diff --git a/src/TrackListBox.h b/src/TrackListBox.h
new file mode 100644
index 0000000..772a31e
--- /dev/null
+++ b/src/TrackListBox.h
@@ -0,0 +1,61 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストボックスクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTBOX_H_
+#define _TRACKLISTBOX_H_
+
+class CTrackListBox : public CColorfulCheckListBox {
+ DECLARE_DYNCREATE (CTrackListBox)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CDocument* m_pDocument; // ドキュメントへのポインタ
+ long m_lMenuID; // 右クリックしたときに現れるメニューのID
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListBox (); // コンストラクタ
+ CTrackListBox (CDocument* pDocument, long lMenuID); // コンストラクタ
+ virtual ~CTrackListBox (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuDoc* GetDocument ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/TrackListFrame.cpp b/src/TrackListFrame.cpp
new file mode 100644
index 0000000..1a7b740
--- /dev/null
+++ b/src/TrackListFrame.cpp
@@ -0,0 +1,2228 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストフレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "resource.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "SekaijuFileDlg.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "TrackListPrintView.h"
+#include "TrackListScaleView.h"
+#include "TrackListModeScaleView.h"
+#include "TrackListTimeScaleView.h"
+#include "TrackListTrackScaleView.h"
+#include "TrackListTrackModeView.h"
+#include "TrackListTrackTimeView.h"
+
+#include "../../MIDIData/MIDIData.h"
+
+
+
+// アロケーションの監視
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// 子ウィンドウのサイズ
+#define TRACKLISTFRAME_SCALEHEIGHT 32
+#define TRACKLISTFRAME_SCALEWIDTH 32
+#define TRACKLISTFRAME_MODEWIDTH 256
+#define TRACKLISTFRAME_TIMEWIDTH 600
+#define TRACKLISTFRAME_TRACKHEIGHT 480
+#define TRACKLISTFRAME_SCROLLBARHEIGHT 16
+#define TRACKLISTFRAME_SCROLLBARWIDTH 16
+#define TRACKLISTFRAME_BORDERWIDTH 2
+#define TRACKLISTFRAME_BORDERHEIGHT 2
+#define TRACKLISTFRAME_SPLITTERWIDTH 4
+#define TRACKLISTFRAME_SPLITTERHEIGHT 4
+
+// 子ウィンドウIDを定義
+#define TRACKLISTFRAME_DUMMYVIEW (AFX_IDW_PANE_FIRST + 0)
+#define TRACKLISTFRAME_PRINTVIEW (AFX_IDW_PANE_FIRST + 1)
+#define TRACKLISTFRAME_SCALEVIEW (AFX_IDW_PANE_FIRST + 32)
+#define TRACKLISTFRAME_MODESCALEVIEW (AFX_IDW_PANE_FIRST + 33)
+#define TRACKLISTFRAME_TIMESCALEVIEW (AFX_IDW_PANE_FIRST + 34)
+#define TRACKLISTFRAME_TRACKSCALEVIEW (AFX_IDW_PANE_FIRST + 35)
+#define TRACKLISTFRAME_TRACKMODEVIEW (AFX_IDW_PANE_FIRST + 36)
+#define TRACKLISTFRAME_TRACKTIMEVIEW (AFX_IDW_PANE_FIRST + 37)
+#define TRACKLISTFRAME_COLUMNSCROLL (AFX_IDW_PANE_FIRST + 48)
+#define TRACKLISTFRAME_TIMESCROLL (AFX_IDW_PANE_FIRST + 49)
+#define TRACKLISTFRAME_ROWSCROLL (AFX_IDW_PANE_FIRST + 50)
+#define TRACKLISTFRAME_SIZEBOX (AFX_IDW_PANE_FIRST + 51)
+#define TRACKLISTFRAME_COLUMNZOOMDOWN (AFX_IDW_PANE_FIRST + 52)
+#define TRACKLISTFRAME_COLUMNZOOMUP (AFX_IDW_PANE_FIRST + 53)
+#define TRACKLISTFRAME_TIMEZOOMDOWN (AFX_IDW_PANE_FIRST + 54)
+#define TRACKLISTFRAME_TIMEZOOMUP (AFX_IDW_PANE_FIRST + 55)
+#define TRACKLISTFRAME_ROWZOOMDOWN (AFX_IDW_PANE_FIRST + 56)
+#define TRACKLISTFRAME_ROWZOOMUP (AFX_IDW_PANE_FIRST + 57)
+
+//
+// トラックリストフレームのクライアント領域に配置されたオブジェクト
+//                          
+//          ┃ m_lVSc
+// ┃←m_lScale→│← m_lMode →★← m_lTime →│←rollBa→┃ TIMEWIDTH     →│←LBAR→┃
+// Width Width ┃ Width rWidth
+// ━
+// ↑ ┏━━━━━━┯━━━━━━━━┳━━━━━━━━━━━━━┯━┓
+// m_lScaleHeight ┃CView* │CView*     ┃CView* │↑┃
+// ↓ ┃m_pScaleView│m_pModeScaleView┃m_pTimeScaleView  ├─┨
+// ─ ┠──────┼────────╂─────────────┤ ┃
+// ↑ ┃CView* │CView*   ┃CView*     │□┃CScrollBar
+// ┃m_pTrack │m_pTrackModeView┃m_pTrackTimeView   │ ┃m_wndRowScroll
+// ┃ScaleView │       ┃          ├─┨
+// m_lTrackHeight ┃    │        ★          │↓┃
+// ┃    │        ┃         ├─┨CButton
+// ┃    │        ┃         │−┃m_wndRowZoomDown
+// ↓ ┃    │        ┃         ├─┨CButton
+// ─ ┃    │        ┃         │+┃m_wndRowZoomUp
+// ↑ ┠─┬────┴──┬─┬─┬─╂─┬─────┬─┬─┬─┼─┨CScrollBar
+//m_lHScrollBarHeight┃←│  □  │→│−│+┃←│  □  │→│−│+│⊿┃m_wndSizeScroll
+// ↓ ┗━┷━━━━━━━┷━┷━┷━┻━┷━━━━━┷━┷━┷━┷━┛
+// ━ CScrollBar CButton CButton CScrollBar CButton CButton
+// m_wndColumn m_wndColmun m_wndColumn m_wndTime m_wndTime m_wndTime
+// Scroll ZoomDown ZoomUpUP Scroll ZoomDown ZoomUp
+//
+// (あ)———:単純な境界(0px)。
+// (い)━━━:太く立体的な境界線。BORDERWIDTH(2px)又はBORDERHEIGHT(2px)で示す幅を占領
+// (う)━★━:スプリッター境界線。(い)*2+SPRITTERWIDTH(4px)又はSPRITTERHEIGHT(4px)で示す幅を占領。
+//
+
+
+// メッセージマップ
+IMPLEMENT_DYNCREATE(CTrackListFrame, CChildFrame)
+
+BEGIN_MESSAGE_MAP(CTrackListFrame, CChildFrame)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_SIZE ()
+ ON_WM_TIMER ()
+ ON_WM_ERASEBKGND ()
+ ON_WM_MDIACTIVATE ()
+ ON_WM_CLOSE ()
+ ON_WM_PAINT ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_HSCROLL ()
+ ON_WM_VSCROLL ()
+
+ ON_BN_CLICKED (TRACKLISTFRAME_COLUMNZOOMDOWN, OnColumnZoomDown)
+ ON_BN_CLICKED (TRACKLISTFRAME_COLUMNZOOMUP, OnColumnZoomUp)
+ ON_BN_CLICKED (TRACKLISTFRAME_TIMEZOOMDOWN, OnTimeZoomDown)
+ ON_BN_CLICKED (TRACKLISTFRAME_TIMEZOOMUP, OnTimeZoomUp)
+ ON_BN_CLICKED (TRACKLISTFRAME_ROWZOOMDOWN, OnRowZoomDown)
+ ON_BN_CLICKED (TRACKLISTFRAME_ROWZOOMUP, OnRowZoomUp)
+
+ ON_COMMAND (ID_TRACKLIST_INSERTTRACK, OnTrackListInsertTrack)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_INSERTTRACK, OnUpdateTrackListInsertTrackUI)
+ ON_COMMAND (ID_TRACKLIST_DUPLICATETRACK, OnTrackListDuplicateTrack)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_DUPLICATETRACK, OnUpdateTrackListDuplicateTrackUI)
+ ON_COMMAND (ID_TRACKLIST_DELETETRACK, OnTrackListDeleteTrack)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_DELETETRACK, OnUpdateTrackListDeleteTrackUI)
+ ON_COMMAND (ID_TRACKLIST_MOVEUPTRACK, OnTrackListMoveUpTrack)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_MOVEUPTRACK, OnUpdateTrackListMoveUpTrackUI)
+ ON_COMMAND (ID_TRACKLIST_MOVEDOWNTRACK, OnTrackListMoveDownTrack)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_MOVEDOWNTRACK, OnUpdateTrackListMoveDownTrackUI)
+ ON_COMMAND (ID_TRACKLIST_SELECT, OnTrackListSelect)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_SELECT, OnUpdateTrackListSelectUI)
+ ON_COMMAND (ID_TRACKLIST_SPEAKER, OnTrackListSpeaker)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_SPEAKER, OnUpdateTrackListSpeakerUI)
+ ON_COMMAND (ID_TRACKLIST_AUTOPAGEUPDATE, OnTrackListAutoPageUpdate)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_AUTOPAGEUPDATE, OnUpdateTrackListAutoPageUpdateUI)
+ ON_COMMAND (ID_TRACKLIST_SAVEAS, OnTrackListSaveAs)
+ ON_UPDATE_COMMAND_UI (ID_TRACKLIST_SAVEAS, OnUpdateTrackListSaveAsUI)
+
+
+END_MESSAGE_MAP()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListFrame::CTrackListFrame () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_lScaleWidth = TRACKLISTFRAME_SCALEWIDTH;
+ m_lScaleHeight = TRACKLISTFRAME_SCALEHEIGHT;
+ m_lTrackHeight = TRACKLISTFRAME_TRACKHEIGHT;
+ m_lModeWidth = TRACKLISTFRAME_MODEWIDTH;
+ m_lTimeWidth = TRACKLISTFRAME_TIMEWIDTH;
+ m_lHScrollBarHeight = ::GetSystemMetrics (SM_CYHSCROLL);
+ m_lVScrollBarWidth = ::GetSystemMetrics (SM_CXVSCROLL);
+ m_lRowZoom = pSekaijuApp->m_theTrackListOption1.m_lDefRowZoom;
+ m_lColumnZoom = pSekaijuApp->m_theTrackListOption1.m_lDefColumnZoom;
+ m_lTimeZoom = pSekaijuApp->m_theTrackListOption1.m_lDefTimeZoom;
+ // カラムの定義
+ m_lColumnBaseWidth[0] = pSekaijuApp->m_theTrackListOption1.m_lDefNameWidth;
+ m_lColumnBaseWidth[1] = pSekaijuApp->m_theTrackListOption1.m_lDefColorWidth;
+ m_lColumnBaseWidth[2] = pSekaijuApp->m_theTrackListOption1.m_lDefInputOnWidth;
+ m_lColumnBaseWidth[3] = pSekaijuApp->m_theTrackListOption1.m_lDefInputPortWidth;
+ m_lColumnBaseWidth[4] = pSekaijuApp->m_theTrackListOption1.m_lDefInputChWidth;
+ m_lColumnBaseWidth[5] = pSekaijuApp->m_theTrackListOption1.m_lDefOutputOnWidth;
+ m_lColumnBaseWidth[6] = pSekaijuApp->m_theTrackListOption1.m_lDefOutputPortWidth;
+ m_lColumnBaseWidth[7] = pSekaijuApp->m_theTrackListOption1.m_lDefOutputChWidth;
+ m_lColumnBaseWidth[8] = pSekaijuApp->m_theTrackListOption1.m_lDefViewModeWidth;
+ m_lColumnBaseWidth[9] = pSekaijuApp->m_theTrackListOption2.m_lDefCC000Width;
+ m_lColumnBaseWidth[10] = pSekaijuApp->m_theTrackListOption2.m_lDefCC032Width;
+ m_lColumnBaseWidth[11] = pSekaijuApp->m_theTrackListOption2.m_lDefPCWidth;
+ m_lColumnBaseWidth[12] = pSekaijuApp->m_theTrackListOption2.m_lDefCC007Width;
+ m_lColumnBaseWidth[13] = pSekaijuApp->m_theTrackListOption2.m_lDefCC010Width;
+ m_lColumnBaseWidth[14] = pSekaijuApp->m_theTrackListOption2.m_lDefCC091Width;
+ m_lColumnBaseWidth[15] = pSekaijuApp->m_theTrackListOption2.m_lDefCC093Width;
+ m_lColumnBaseWidth[16] = pSekaijuApp->m_theTrackListOption2.m_lDefCC094Width;
+ m_lColumnBaseWidth[17] = pSekaijuApp->m_theTrackListOption2.m_lDefKeyShiftWidth;
+ m_lColumnBaseWidth[18] = pSekaijuApp->m_theTrackListOption2.m_lDefVelShiftWidth;
+ m_lColumnBaseWidth[19] = pSekaijuApp->m_theTrackListOption2.m_lDefTimeShiftWidth;
+ m_lColumnBaseWidth[20] = pSekaijuApp->m_theTrackListOption2.m_lDefNumEventWidth;
+
+ VERIFY (m_strColumnTitle[0].LoadString (IDS_NAME));
+ VERIFY (m_strColumnTitle[1].LoadString (IDS_COLOR));
+ VERIFY (m_strColumnTitle[2].LoadString (IDS_INPUTON));
+ VERIFY (m_strColumnTitle[3].LoadString (IDS_INPUTPORT));
+ VERIFY (m_strColumnTitle[4].LoadString (IDS_INPUTCHANNEL));
+ VERIFY (m_strColumnTitle[5].LoadString (IDS_OUTPUTON));
+ VERIFY (m_strColumnTitle[6].LoadString (IDS_OUTPUTPORT));
+ VERIFY (m_strColumnTitle[7].LoadString (IDS_OUTPUTCHANNEL));
+ VERIFY (m_strColumnTitle[8].LoadString (IDS_VIEWMODE));
+ VERIFY (m_strColumnTitle[9].LoadString (IDS_CC_0));
+ VERIFY (m_strColumnTitle[10].LoadString (IDS_CC_32));
+ VERIFY (m_strColumnTitle[11].LoadString (IDS_PROGRAM_NUMBER));
+ VERIFY (m_strColumnTitle[12].LoadString (IDS_VOLUME));
+ VERIFY (m_strColumnTitle[13].LoadString (IDS_PAN));
+ VERIFY (m_strColumnTitle[14].LoadString (IDS_REVERB));
+ VERIFY (m_strColumnTitle[15].LoadString (IDS_CHORUS));
+ VERIFY (m_strColumnTitle[16].LoadString (IDS_DELAY));
+ VERIFY (m_strColumnTitle[17].LoadString (IDS_TIMEPLUS));
+ VERIFY (m_strColumnTitle[18].LoadString (IDS_KEYPLUS));
+ VERIFY (m_strColumnTitle[19].LoadString (IDS_VELPLUS));
+ VERIFY (m_strColumnTitle[20].LoadString (IDS_NUMEVENT));
+
+ m_lColumnContent[0] = TRACKLISTFRAME_TRACKNAME;
+ m_lColumnContent[1] = TRACKLISTFRAME_FORECOLOR;
+ m_lColumnContent[2] = TRACKLISTFRAME_INPUTON;
+ m_lColumnContent[3] = TRACKLISTFRAME_INPUTPORT;
+ m_lColumnContent[4] = TRACKLISTFRAME_INPUTCHANNEL;
+ m_lColumnContent[5] = TRACKLISTFRAME_OUTPUTON;
+ m_lColumnContent[6] = TRACKLISTFRAME_OUTPUTPORT;
+ m_lColumnContent[7] = TRACKLISTFRAME_OUTPUTCHANNEL;
+ m_lColumnContent[8] = TRACKLISTFRAME_VIEWMODE;
+ m_lColumnContent[9] = TRACKLISTFRAME_CONTROLCHANGE | (0 << 16);
+ m_lColumnContent[10] = TRACKLISTFRAME_CONTROLCHANGE | (32 << 16);
+ m_lColumnContent[11] = TRACKLISTFRAME_PROGRAMCHANGE;
+ m_lColumnContent[12] = TRACKLISTFRAME_CONTROLCHANGE | (7 << 16);
+ m_lColumnContent[13] = TRACKLISTFRAME_CONTROLCHANGE | (10 << 16);
+ m_lColumnContent[14] = TRACKLISTFRAME_CONTROLCHANGE | (91 << 16);
+ m_lColumnContent[15] = TRACKLISTFRAME_CONTROLCHANGE | (93 << 16);
+ m_lColumnContent[16] = TRACKLISTFRAME_CONTROLCHANGE | (94 << 16);
+ m_lColumnContent[17] = TRACKLISTFRAME_TIMEPLUS;
+ m_lColumnContent[18] = TRACKLISTFRAME_KEYPLUS;
+ m_lColumnContent[19] = TRACKLISTFRAME_VELOCITYPLUS;
+ m_lColumnContent[20] = TRACKLISTFRAME_NUMEVENT;
+
+ // デフォルトフォントの作成
+ CString strFontName;
+ VERIFY (strFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (12, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strFontName);
+ m_lCurTool = ID_TRACKLIST_SELECT;
+
+ m_bAutoPageUpdate = FALSE;
+
+}
+
+// デストラクタ
+CTrackListFrame::~CTrackListFrame () {
+ m_theFont.DeleteObject ();
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// ドキュメントへのポインタ取得
+CSekaijuDoc* CTrackListFrame::GetDocument () {
+ ASSERT (m_pDummyView);
+ return (CSekaijuDoc*)m_pDummyView->GetDocument ();
+}
+
+// 指定した列の基本幅を取得
+long CTrackListFrame::GetColumnBaseWidth (long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ return m_lColumnBaseWidth[lColumn];
+}
+
+// 指定した列の基本幅を設定
+long CTrackListFrame::SetColumnBaseWidth (long lColumn, long lColumnBaseWidth) {
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ m_lColumnBaseWidth[lColumn] = lColumnBaseWidth;
+ return 1;
+}
+
+// 指定した列のタイトルを取得
+CString CTrackListFrame::GetColumnTitle (long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ return m_strColumnTitle[lColumn];
+}
+
+// 指定した列のコンテンツ種類を取得
+long CTrackListFrame::GetColumnContent (long lColumn) {
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ return m_lColumnContent[lColumn];
+}
+
+
+// 行方向のズーム倍率を取得
+long CTrackListFrame::GetRowZoom () {
+ return m_lRowZoom;
+}
+
+// 列方向のズーム倍率を取得
+long CTrackListFrame::GetColumnZoom () {
+ return m_lColumnZoom;
+}
+
+// 時間方向のズーム倍率を取得
+long CTrackListFrame::GetTimeZoom () {
+ return m_lTimeZoom;
+}
+
+// 指定の列の左座標を取得
+long CTrackListFrame::GetColumnLeft (long lColumn) {
+ long lSum = 0;
+ for (long j = 0; j < lColumn; j++) {
+ lSum += m_lColumnBaseWidth[j];
+ }
+ return lSum * m_lColumnZoom;
+}
+
+// 指定の列の幅を取得
+long CTrackListFrame::GetColumnWidth (long lColumn) {
+ return m_lColumnBaseWidth[lColumn] * m_lColumnZoom;
+}
+
+// y座標をトラックに変換
+long CTrackListFrame::YtoRow (long y) {
+ return y / m_lRowZoom;
+}
+
+// トラックをy座標に変換
+long CTrackListFrame::RowtoY (long lTrack) {
+ return m_lRowZoom * lTrack;
+}
+
+// x座標からモードを取得
+long CTrackListFrame::XtoColumn (long x) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ long lSum = 0;
+ long lNextSum = 0;
+ for (long j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ lNextSum += m_lColumnBaseWidth[j] * m_lColumnZoom;
+ if (lSum <= x && x < lNextSum) {
+ return j;
+ }
+ lSum = lNextSum;
+ }
+ return -1;
+}
+
+// モードをx座標に変換
+long CTrackListFrame::ColumntoX (long lMode) {
+ return GetColumnLeft (lMode);
+}
+
+// x座標からタイムを取得
+long CTrackListFrame::XtoTime (long x) {
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return x * lTimeResolution / m_lTimeZoom;
+}
+
+// タイムをx座標に変換
+long CTrackListFrame::TimetoX (long lTime) {
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return lTime * m_lTimeZoom / lTimeResolution;
+}
+
+
+
+
+
+// 最も上に表示されている行を取得
+long CTrackListFrame::GetVisibleTopRow () {
+ return m_lRowScrollPos / m_lRowZoom;
+}
+
+// 最も下に表示されている行を取得
+long CTrackListFrame::GetVisibleBottomRow () {
+ CRect rcClient;
+ m_pTrackScaleView->GetClientRect (&rcClient);
+ return (m_lRowScrollPos + rcClient.Height ()) / m_lRowZoom;
+}
+
+// 表示されているタイムの左端を計算
+long CTrackListFrame::GetVisibleLeftTime () {
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return m_lTimeScrollPos * lTimeResolution / m_lTimeZoom;
+}
+
+// 表示されているタイムの右端を計算
+long CTrackListFrame::GetVisibleRightTime () {
+ CRect rcClient;
+ m_pTimeScaleView->GetClientRect (&rcClient);
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return (m_lTimeScrollPos + rcClient.Width ()) * lTimeResolution / m_lTimeZoom;
+}
+
+
+// 時間方向のスクロールポジションを取得
+long CTrackListFrame::GetTimeScrollPos () {
+ return m_lTimeScrollPos;
+}
+
+// 行方向のスクロールポジションを取得
+long CTrackListFrame::GetRowScrollPos () {
+ return m_lRowScrollPos;
+}
+
+// 列方向のスクロールポジションを取得
+long CTrackListFrame::GetColumnScrollPos () {
+ return m_lColumnScrollPos;
+}
+
+// 時間方向のスクロールポジション設定
+long CTrackListFrame::SetTimeScrollPos (long lTimeScrollPos) {
+ long lOldTimeScrollPos = m_lTimeScrollPos;
+ m_wndTimeScroll.SetScrollPos (lTimeScrollPos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ long lDeltaTimeScrollPos = m_lTimeScrollPos - lOldTimeScrollPos;
+ //((CTrackListTrackTimeView*)m_pTrackTimeView)->m_bTimeScrolled = TRUE;
+ m_pTimeScaleView->ScrollWindow (-lDeltaTimeScrollPos, 0);
+ m_pTrackTimeView->ScrollWindow (-lDeltaTimeScrollPos, 0);
+ m_pTimeScaleView->UpdateWindow ();
+ m_pTrackTimeView->UpdateWindow ();
+ return m_lTimeScrollPos;
+}
+
+// 列方向のスクロールポジション設定
+long CTrackListFrame::SetColumnScrollPos (long lColumnScrollPos) {
+ long lOldColumnScrollPos = m_lColumnScrollPos;
+ m_wndColumnScroll.SetScrollPos (lColumnScrollPos);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+ long lDeltaColumnScrollPos = m_lColumnScrollPos - lOldColumnScrollPos; //20080823修正
+ m_pModeScaleView->ScrollWindow (-lDeltaColumnScrollPos, 0);
+ m_pTrackModeView->ScrollWindow (-lDeltaColumnScrollPos, 0);
+ return m_lColumnScrollPos;
+}
+
+// 行方向のスクロールポジション設定
+long CTrackListFrame::SetRowScrollPos (long lRowScrollPos) {
+ long lOldRowScrollPos = m_lRowScrollPos;
+ m_wndRowScroll.SetScrollPos (lRowScrollPos);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+ long lDeltaRowScrollPos = m_lRowScrollPos - lOldRowScrollPos;
+ m_pTrackScaleView->ScrollWindow (0, -lDeltaRowScrollPos);
+ m_pTrackModeView->ScrollWindow (0, -lDeltaRowScrollPos);
+ m_pTrackTimeView->ScrollWindow (0, -lDeltaRowScrollPos);
+ return m_lRowScrollPos;
+}
+
+// スプリッターキャプターの描画
+void CTrackListFrame::DrawSplitterCaptor (CDC* pDC, CPoint pt) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CPen pen;
+ CPen* pOldPen;
+ pen.CreatePen (PS_SOLID, 4, ::GetSysColor(COLOR_BTNSHADOW));
+ pDC->SetROP2 (R2_XORPEN);
+ pOldPen = pDC->SelectObject (&pen);
+ pDC->MoveTo (pt.x, 0);
+ pDC->LineTo (pt.x, rcClient.Height());
+ pDC->SelectObject (pOldPen);
+}
+
+// 行スクロールバー(縦)のデザイン設定
+void CTrackListFrame::RecalcRowScrollInfo () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lTrackCount = 17;
+ if (pSekaijuDoc) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ if (pMIDIData) {
+ lTrackCount = MIDIData_CountTrack (pMIDIData);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = CLIP (17, lTrackCount + 16, MAXMIDITRACKNUM - 1) * m_lRowZoom;
+ si.nPage = m_lTrackHeight;
+ m_wndRowScroll.SetScrollInfo (&si, TRUE);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+}
+
+// 列スクロールバー(縦)のデザイン設定
+void CTrackListFrame::RecalcColumnScrollInfo () {
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = 0;
+ for (int i = 0; i < TRACKLISTFRAME_NUMCOLUMN; i++) {
+ si.nMax += m_lColumnBaseWidth[i];
+ }
+ si.nMax *= m_lColumnZoom;
+ si.nPage = m_lModeWidth;
+ m_wndColumnScroll.SetScrollInfo (&si, TRUE);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+}
+
+// タイムスクロールバー(横)のデザイン設定
+void CTrackListFrame::RecalcTimeScrollInfo () {
+ long lTimeResolution = 120;
+ long lEndTime = 0;
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (pSekaijuDoc) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pMIDIData) {
+ lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ lEndTime = MIDIData_GetEndTime (pMIDIData);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+ long lFeedTime = lTimeResolution * 4 * 120;
+ SCROLLINFO si;
+ si.fMask = SIF_RANGE | SIF_PAGE;
+ si.nMin = 0;
+ si.nMax = (lEndTime + lFeedTime) * m_lTimeZoom / lTimeResolution;
+ si.nMax = MIN (si.nMax, 0x7FFFFFFF);
+ si.nPage = m_lTimeWidth;
+ m_wndTimeScroll.SetScrollInfo (&si, TRUE);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ // 注:ズーム倍率1倍のとき4分音符の長さを1ピクセルと定義している。
+}
+
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成直前の構造体設定
+BOOL CTrackListFrame::PreCreateWindow (CREATESTRUCT& cs) {
+ return (CWnd::PreCreateWindow(cs));
+}
+
+// 背景消去(CFrameWnd::OnEraseBkgndのオーバーライド)
+BOOL CTrackListFrame::OnEraseBkgnd (CDC* pDC) {
+ return 0;
+}
+
+// ウィンドウタイトルの自動設定(CMDIChildWnd::OnUpdateFrameTitleのオーバーライド)
+void CTrackListFrame::OnUpdateFrameTitle (BOOL bAddToTitle) {
+ // update our parent window first
+ GetMDIFrame()->OnUpdateFrameTitle (bAddToTitle);
+ if ((GetStyle() & FWS_ADDTOTITLE) == 0) {
+ return; // leave child window alone!
+ }
+ CDocument* pDocument = GetActiveDocument();
+ if (bAddToTitle && pDocument != NULL) {
+ CString strTrackList;
+ strTrackList.LoadString (IDS_TRACKLIST);
+ CString strTitle;
+ if (m_nWindow > 0) {
+ strTitle.Format (_T("%s:%d(%s)"), pDocument->GetTitle (), m_nWindow, strTrackList);
+ }
+ else {
+ strTitle.Format (_T("%s(%s)"), pDocument->GetTitle (), strTrackList);
+ }
+ this->SetWindowText (strTitle);
+ }
+}
+
+// 再配置用関数(CFrameWnd::RecalcLayoutのオーバーライド)
+void CTrackListFrame::RecalcLayout (BOOL bNotify) {
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+
+ // 基本クラスの関数を処理
+ CFrameWnd::RecalcLayout (bNotify);
+
+ // アイコン化時には各コントロールのサイズを再計算しない。
+ if (rcClient.Width () == 0 || rcClient.Height () == 0) {
+ return;
+ }
+
+ // ツールバー1の高さ取得
+ CRect rcToolBar1;
+ m_wndToolBar1.GetWindowRect (&rcToolBar1);
+ m_lToolBar1Height = rcToolBar1.Height ();
+
+ // 高さ方向の位置計算
+ if (rcClient.Height () <
+ m_lToolBar1Height +
+ TRACKLISTFRAME_SCALEHEIGHT + m_lHScrollBarHeight +
+ TRACKLISTFRAME_BORDERHEIGHT * 2) {
+ m_lScaleHeight = rcClient.Height () - m_lToolBar1Height - m_lHScrollBarHeight -
+ TRACKLISTFRAME_BORDERHEIGHT * 2;
+ m_lTrackHeight = 0;
+ }
+ else {
+ m_lScaleHeight = TRACKLISTFRAME_SCALEHEIGHT;
+ m_lTrackHeight = rcClient.Height () - m_lToolBar1Height - m_lScaleHeight -
+ m_lHScrollBarHeight - TRACKLISTFRAME_BORDERHEIGHT * 2;
+ }
+
+ // 幅方向の位置計算
+ if (rcClient.Width () <
+ TRACKLISTFRAME_SCALEWIDTH + m_lVScrollBarWidth +
+ TRACKLISTFRAME_BORDERWIDTH * 4 + TRACKLISTFRAME_SPLITTERWIDTH) {
+ m_lScaleWidth = rcClient.Width () - TRACKLISTFRAME_SPLITTERWIDTH -
+ m_lVScrollBarWidth - TRACKLISTFRAME_BORDERWIDTH * 4;
+ m_lModeWidth = 0;
+ m_lTimeWidth = 0;
+ }
+ else if (rcClient.Width () <
+ TRACKLISTFRAME_SCALEWIDTH + m_lVScrollBarWidth + m_lModeWidth +
+ TRACKLISTFRAME_BORDERWIDTH * 4 + TRACKLISTFRAME_SPLITTERWIDTH +
+ m_lVScrollBarWidth) {
+ m_lScaleWidth = TRACKLISTFRAME_SCALEWIDTH;
+ m_lModeWidth = rcClient.Width () - TRACKLISTFRAME_SPLITTERWIDTH -
+ m_lScaleWidth - m_lVScrollBarWidth - TRACKLISTFRAME_BORDERWIDTH * 4;
+ m_lTimeWidth = 0;
+
+ }
+ else {
+ //m_lScaleWidth = TRACKLISTFRAME_SCALEWIDTH;
+ //m_lModeWidth = TRACKLISTFRAME_MODEWIDTH;
+ m_lTimeWidth = rcClient.Width () - m_lScaleWidth - m_lModeWidth -
+ TRACKLISTFRAME_SPLITTERWIDTH -
+ m_lVScrollBarWidth - TRACKLISTFRAME_BORDERWIDTH * 4;
+ }
+
+ // ビューの整列
+ if (m_pScaleView) {
+ m_pScaleView->MoveWindow (TRACKLISTFRAME_BORDERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT,
+ m_lScaleWidth, m_lScaleHeight);
+ }
+
+ if (m_pModeScaleView) {
+ m_pModeScaleView->MoveWindow (TRACKLISTFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT,
+ m_lModeWidth, m_lScaleHeight);
+ }
+
+ if (m_pTimeScaleView) {
+ m_pTimeScaleView->MoveWindow (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lModeWidth + TRACKLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT,
+ m_lTimeWidth, m_lScaleHeight);
+ }
+
+ if (m_pTrackScaleView) {
+ m_pTrackScaleView->MoveWindow (TRACKLISTFRAME_BORDERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lScaleWidth, m_lTrackHeight);
+ }
+
+ if (m_pTrackModeView) {
+ m_pTrackModeView->MoveWindow (TRACKLISTFRAME_BORDERWIDTH + m_lScaleWidth,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lModeWidth, m_lTrackHeight);
+ }
+
+ if (m_pTrackTimeView) {
+ m_pTrackTimeView->MoveWindow (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lModeWidth + TRACKLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight,
+ m_lTimeWidth, m_lTrackHeight);
+ }
+ // スクロールバーの整列
+ m_wndColumnScroll.MoveWindow (TRACKLISTFRAME_BORDERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight,
+ m_lScaleWidth + m_lModeWidth - m_lVScrollBarWidth * 2,
+ m_lHScrollBarHeight);
+
+ m_wndTimeScroll.MoveWindow (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lModeWidth + TRACKLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight,
+ m_lTimeWidth - m_lVScrollBarWidth * 2,
+ m_lHScrollBarHeight);
+
+ m_wndRowScroll.MoveWindow (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lModeWidth + m_lTimeWidth + TRACKLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT,
+ m_lVScrollBarWidth,
+ m_lScaleHeight + m_lTrackHeight - m_lHScrollBarHeight * 2);
+
+ m_wndSizeScroll.MoveWindow (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lModeWidth + m_lTimeWidth + TRACKLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ // ズームボタンの整列
+ m_wndColumnZoomDown.MoveWindow (TRACKLISTFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lModeWidth - m_lVScrollBarWidth * 2,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndColumnZoomUp.MoveWindow (TRACKLISTFRAME_BORDERWIDTH + m_lScaleWidth +
+ m_lModeWidth - m_lVScrollBarWidth,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndTimeZoomDown.MoveWindow (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lModeWidth + TRACKLISTFRAME_SPLITTERWIDTH + m_lTimeWidth -
+ m_lVScrollBarWidth * 2,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndTimeZoomUp.MoveWindow (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth +
+ m_lModeWidth + TRACKLISTFRAME_SPLITTERWIDTH + m_lTimeWidth -
+ m_lVScrollBarWidth,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndRowZoomDown.MoveWindow
+ (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth + m_lModeWidth +
+ m_lTimeWidth + TRACKLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight -
+ m_lHScrollBarHeight * 2,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ m_wndRowZoomUp.MoveWindow
+ (TRACKLISTFRAME_BORDERWIDTH * 3 + m_lScaleWidth + m_lModeWidth +
+ m_lTimeWidth + TRACKLISTFRAME_SPLITTERWIDTH,
+ m_lToolBar1Height + TRACKLISTFRAME_BORDERHEIGHT + m_lScaleHeight + m_lTrackHeight -
+ m_lHScrollBarHeight,
+ m_lVScrollBarWidth, m_lHScrollBarHeight);
+
+ // スクロールバーのサイズが変化したので、バーのデザインを再調整する。
+ RecalcRowScrollInfo ();
+ RecalcColumnScrollInfo ();
+ RecalcTimeScrollInfo ();
+
+}
+
+// クライアント領域の生成(CFrameWnd::OnCreateClientのオーバーライド)
+BOOL CTrackListFrame::OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext) {
+
+ // サイズ調整用のダミービュー生成(Visible = FALSE)
+ CWnd* pWnd = NULL;
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CSekaijuView);
+ m_pDummyView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_DUMMYVIEW);
+ if (m_pDummyView == NULL) {
+ return FALSE;
+ }
+ m_pDummyView->ShowWindow (SW_HIDE);
+
+ // 印刷ビューの生成(Visible = FALSE)
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CTrackListPrintView);
+ m_pPrintView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_PRINTVIEW);
+ if (m_pPrintView == NULL) {
+ return FALSE;
+ }
+ m_pDummyView->ShowWindow (SW_HIDE);
+
+ // スケールビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CTrackListScaleView);
+ m_pScaleView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_SCALEVIEW);
+ if (m_pScaleView == NULL) {
+ return FALSE;
+ }
+ m_pScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // モードスケールビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CTrackListModeScaleView);
+ m_pModeScaleView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_MODESCALEVIEW);
+ if (m_pModeScaleView == NULL) {
+ return FALSE;
+ }
+ m_pModeScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // タイムスケールビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CTrackListTimeScaleView);
+ m_pTimeScaleView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_TIMESCALEVIEW);
+ if (m_pTimeScaleView == NULL) {
+ return FALSE;
+ }
+ m_pTimeScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // トラックスケールビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CTrackListTrackScaleView);
+ m_pTrackScaleView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_TRACKSCALEVIEW);
+ if (m_pTrackScaleView == NULL) {
+ return FALSE;
+ }
+ m_pTrackScaleView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // トラックモードビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CTrackListTrackModeView);
+ m_pTrackModeView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_TRACKMODEVIEW);
+ if (m_pTrackModeView == NULL) {
+ return FALSE;
+ }
+ m_pTrackModeView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // トラックタイムビューの生成
+ pContext->m_pNewViewClass = RUNTIME_CLASS (CTrackListTrackTimeView);
+ m_pTrackTimeView = (CView*)CFrameWnd::CreateView (pContext, TRACKLISTFRAME_TRACKTIMEVIEW);
+ if (m_pTrackTimeView == NULL) {
+ return FALSE;
+ }
+ m_pTrackTimeView->ModifyStyleEx (WS_EX_CLIENTEDGE, 0);
+
+ // スクロールバーの生成
+ m_wndColumnScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_HORZ, CRect(0,0,0,0), this, TRACKLISTFRAME_COLUMNSCROLL);
+ m_wndTimeScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_HORZ, CRect(0,0,0,0), this, TRACKLISTFRAME_TIMESCROLL);
+ m_wndRowScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_VERT, CRect(0,0,0,0), this, TRACKLISTFRAME_ROWSCROLL);
+ m_wndSizeScroll.Create
+ (WS_CHILD|WS_VISIBLE|SBS_SIZEBOX, CRect(0,0,0,0), this, TRACKLISTFRAME_SIZEBOX);
+
+ // ズームボタン類の生成
+ m_wndColumnZoomDown.Create (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, TRACKLISTFRAME_COLUMNZOOMDOWN);
+ m_wndColumnZoomUp.Create (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, TRACKLISTFRAME_COLUMNZOOMUP);
+ m_wndTimeZoomDown.Create (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, TRACKLISTFRAME_TIMEZOOMDOWN);
+ m_wndTimeZoomUp.Create (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, TRACKLISTFRAME_TIMEZOOMUP);
+ m_wndRowZoomDown.Create (_T("-"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, TRACKLISTFRAME_ROWZOOMDOWN);
+ m_wndRowZoomUp.Create (_T("+"), WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, TRACKLISTFRAME_ROWZOOMUP);
+
+ // コントロールの位置合わせはWM_SIZEなどによるRecalcLaoyoutに任せる。
+
+ // フォーカスの設定
+ SetActiveView (m_pTrackModeView);
+
+ return TRUE;
+}
+
+// 印刷用のコマンドをトラップ(CFrameWnd::OnCmdMsgのオーバーライド)
+BOOL CTrackListFrame::OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // 印刷用のコマンドの場合、強制的にCTrackListPrintViewに渡す。
+ if ((nID == ID_FILE_PRINT || nID == ID_FILE_PRINT_DIRECT || nID == ID_FILE_PRINT_PREVIEW) &&
+ pSekaijuApp->m_bRecording == FALSE) {
+ if (m_pPrintView) {
+ return ((CTrackListPrintView*)m_pPrintView)->OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+ }
+ return FALSE;
+ }
+ // その他のコマンドはデフォルトの処理とする。
+ return CFrameWnd::OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+}
+
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CTrackListFrame::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+ CRect rcTemp;
+
+ // ツールバー1の作成
+ if (!m_wndToolBar1.Create (this) ||
+ !m_wndToolBar1.LoadToolBar (IDR_TRACKLIST1)) {
+ TRACE0 ("Failed to create toolbar\n");
+ return -1;
+ }
+ m_wndToolBar1.SetBarStyle (m_wndToolBar1.GetBarStyle() |
+ CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
+ //m_wndToolBar1.EnableDocking (CBRS_ALIGN_ANY);
+ //EnableDocking (CBRS_ALIGN_ANY);
+ //DockControlBar (&m_wndToolBar1);
+
+ LoadAccelTable (MAKEINTRESOURCE (IDR_TRACKLIST));
+
+ // 親クラスの関数呼び出し
+ int nRet = CChildFrame::OnCreate (lpCreateStruct);
+
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 自動ページ更新の設定
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) {
+ m_bAutoPageUpdate = TRUE;
+ }
+
+ SetActiveView (m_pTrackModeView, FALSE);
+ m_pTrackModeView->SetFocus ();
+ return nRet;
+
+}
+
+// ウィンドウ破棄時
+void CTrackListFrame::OnDestroy () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CChildFrame::OnDestroy ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// ウィンドウサイズ変更時
+void CTrackListFrame::OnSize (UINT nType, int cx, int cy) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CChildFrame::OnSize (nType, cx, cy);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// タイマー呼び出し時
+void CTrackListFrame::OnTimer (UINT nIDEvent) {
+ ;
+}
+
+// 描画するとき
+void CTrackListFrame::OnPaint () {
+ CPaintDC dc (this);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ // 上側領域のくぼみ描画
+ CRect rcClient1 (rcClient);
+ rcClient1.top = m_lToolBar1Height;
+ rcClient1.right = TRACKLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lModeWidth;
+ dc.Draw3dRect (&rcClient1, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient1.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient1, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 下側領域のくぼみ描画
+ CRect rcClient2 (rcClient);
+ rcClient2.top = m_lToolBar1Height;
+ rcClient2.left = TRACKLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lModeWidth + TRACKLISTFRAME_SPLITTERWIDTH;
+ dc.Draw3dRect (&rcClient2, RGB (128, 128, 128), RGB (255, 255, 255));
+ rcClient2.InflateRect (-1, -1);
+ dc.Draw3dRect (&rcClient2, RGB (0, 0, 0), RGB (192, 192, 192));
+ // 境界部分の描画
+ CRect rcClient3 (rcClient);
+ rcClient3.top = m_lToolBar1Height;
+ rcClient3.left = rcClient1.right + 1;
+ rcClient3.right = rcClient2.left - 1;
+ CBrush brush;
+ brush.CreateSolidBrush (::GetSysColor (COLOR_3DFACE));
+ dc.FillRect (&rcClient3, &brush);
+}
+
+// ウィンドウがアクティブになったとき
+void CTrackListFrame::OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd) {
+ CChildFrame::OnMDIActivate (bActivate, pActivateWnd, pDeactivateWnd);
+}
+
+// 閉じるボタンが押されたとき
+void CTrackListFrame::OnClose () {
+ _RPTF0 (_CRT_WARN, ("CTrackListFrame::OnClose ()\n"));
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // インプレースエディット及びインプレースリストボックスの終了
+ if (m_pTrackModeView) {
+ CTrackListTrackModeView* pTrackModeView = (CTrackListTrackModeView*)m_pTrackModeView;
+ if (pTrackModeView->IsTextEditing ()) {
+ pTrackModeView->EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ //if (pTrackModeView->IsListSelecting ()) {
+ // pTrackModeView->EndListSelectingOK ();
+ // pSekaijuDoc->SetModifiedFlag (TRUE);
+ // pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ //}
+ }
+ CChildFrame::OnClose ();
+}
+
+// キーが押された時
+void CTrackListFrame::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CWnd* pOldFocus = GetFocus ();
+ switch (nChar) {
+ // ↑
+ case VK_UP:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // ↓
+ case VK_DOWN:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // PageUp
+ case VK_PRIOR:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // PageDown
+ case VK_NEXT:
+ if (GetCapture () == NULL) {
+ this->PostMessage (WM_VSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndRowScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ break;
+ // ←
+ case VK_LEFT:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pModeScaleView || GetFocus () == m_pTrackModeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ else if (GetFocus () == m_pTimeScaleView || GetFocus () == m_pTrackTimeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ }
+ break;
+ // →
+ case VK_RIGHT:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pModeScaleView || GetFocus () == m_pTrackModeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ else if (GetFocus () == m_pTimeScaleView || GetFocus () == m_pTrackTimeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ }
+ break;
+ // Home
+ case VK_HOME:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pModeScaleView || GetFocus () == m_pTrackModeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEUP,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ else if (GetFocus () == m_pTimeScaleView || GetFocus () == m_pTrackTimeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ }
+ break;
+ // End
+ case VK_END:
+ if (GetCapture () == NULL) {
+ if (GetFocus () == m_pModeScaleView || GetFocus () == m_pTrackModeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_PAGEDOWN,
+ (LPARAM)(m_wndColumnScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ else if (GetFocus () == m_pTimeScaleView || GetFocus () == m_pTrackTimeView) {
+ this->PostMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(m_wndTimeScroll.GetSafeHwnd ()));
+ this->PostMessage (WM_SETFOCUS, (WPARAM)(pOldFocus->GetSafeHwnd ()), 0);
+ }
+ }
+ break;
+ // '-'(ズームダウン)
+ case 189:
+ case VK_SUBTRACT:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_theTrackListOption2.m_bEnableRowZoomKey) {
+ this->PostMessage (WM_COMMAND, TRACKLISTFRAME_ROWZOOMDOWN, 0);
+ }
+ if (pSekaijuApp->m_theTrackListOption2.m_bEnableColumnZoomKey) {
+ this->PostMessage (WM_COMMAND, TRACKLISTFRAME_COLUMNZOOMDOWN, 0);
+ }
+ if (pSekaijuApp->m_theTrackListOption2.m_bEnableTimeZoomKey) {
+ this->PostMessage (WM_COMMAND, TRACKLISTFRAME_TIMEZOOMDOWN, 0);
+ }
+ }
+ break;
+ // '+'(ズームアップ)
+ case 187:
+ case VK_ADD:
+ if (GetCapture () == NULL && ::GetKeyState (VK_CONTROL) < 0) {
+ if (pSekaijuApp->m_theTrackListOption2.m_bEnableRowZoomKey) {
+ this->PostMessage (WM_COMMAND, TRACKLISTFRAME_ROWZOOMUP, 0);
+ }
+ if (pSekaijuApp->m_theTrackListOption2.m_bEnableColumnZoomKey) {
+ this->PostMessage (WM_COMMAND, TRACKLISTFRAME_COLUMNZOOMUP, 0);
+ }
+ if (pSekaijuApp->m_theTrackListOption2.m_bEnableTimeZoomKey) {
+ this->PostMessage (WM_COMMAND, TRACKLISTFRAME_TIMEZOOMUP, 0);
+ }
+ }
+ break;
+ }
+}
+
+// マウス左ボタン押された時
+void CTrackListFrame::OnLButtonDown (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (TRACKLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lModeWidth <= point.x &&
+ point.x < TRACKLISTFRAME_BORDERHEIGHT * 2 + m_lScaleWidth + m_lModeWidth +
+ TRACKLISTFRAME_SPLITTERWIDTH) {
+ SetCapture ();
+ m_ptMouseDown = m_ptMouseMoveOld = point;
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+}
+
+// マウス右ボタン押された時
+void CTrackListFrame::OnRButtonDown (UINT nFlags, CPoint point) {
+
+
+}
+
+// マウス左ボタン離されたとき
+void CTrackListFrame::OnLButtonUp (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (GetCapture () == this) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ ReleaseDC (pDC);
+ ReleaseCapture ();
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ CPoint ptDelta = point - m_ptMouseDown;
+ m_lScaleWidth = CLIP (0, point.x, TRACKLISTFRAME_SCALEWIDTH);
+ m_lModeWidth = point.x - m_lScaleWidth;
+ RecalcLayout ();
+ Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+}
+
+// マウス右ボタン離されたとき
+void CTrackListFrame::OnRButtonUp (UINT nFlags, CPoint point) {
+
+
+}
+
+// マウスが動かされたとき
+void CTrackListFrame::OnMouseMove (UINT nFlags, CPoint point) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ // キャプター中
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CDC* pDC = GetDC ();
+ DrawSplitterCaptor (pDC, m_ptMouseMoveOld);
+ DrawSplitterCaptor (pDC, point);
+ ReleaseDC (pDC);
+ m_ptMouseMoveOld = point;
+ }
+ // 非キャプター中
+ else {
+ // カーソルがスプリッターの上にある
+ if (TRACKLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lModeWidth <= point.x &&
+ point.x < TRACKLISTFRAME_BORDERWIDTH * 2 + m_lScaleWidth + m_lModeWidth +
+ TRACKLISTFRAME_SPLITTERWIDTH) {
+ ::SetCursor (pSekaijuApp->m_hCursorResizeWE);
+ }
+ // カーソルがスプリッターの上にない
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+// 列方向ズームダウン(20091220:左端位置保持機能追加)
+void CTrackListFrame::OnColumnZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldColumnZoom = m_lColumnZoom;
+ long lOldColumnPos = m_wndColumnScroll.GetScrollPos ();
+ long lNewColumnZoom = CLIP (2, m_lColumnZoom - 1, 16);
+ long lNewColumnPos = lOldColumnPos * lNewColumnZoom / lOldColumnZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lColumnZoom = lNewColumnZoom;
+ RecalcColumnScrollInfo ();
+ m_wndColumnScroll.SetScrollPos (lNewColumnPos);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+ m_pModeScaleView->Invalidate ();
+ m_pTrackModeView->Invalidate ();
+ //m_pTrackModeView->SetFocus ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 列方向ズームアップ(20091220:左端位置保持機能追加)
+void CTrackListFrame::OnColumnZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldColumnZoom = m_lColumnZoom;
+ long lOldColumnPos = m_wndColumnScroll.GetScrollPos ();
+ long lNewColumnZoom = CLIP (2, m_lColumnZoom + 1, 16);
+ long lNewColumnPos = lOldColumnPos * lNewColumnZoom / lOldColumnZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lColumnZoom = lNewColumnZoom;
+ RecalcColumnScrollInfo ();
+ m_wndColumnScroll.SetScrollPos (lNewColumnPos);
+ m_lColumnScrollPos = m_wndColumnScroll.GetScrollPos ();
+ m_pModeScaleView->Invalidate ();
+ m_pTrackModeView->Invalidate ();
+ //m_pTrackModeView->SetFocus ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 時間方向ズームダウン(20091220:左端位置保持機能追加、自動ページ更新自動オフ追加)
+void CTrackListFrame::OnTimeZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTimeZoom = m_lTimeZoom;
+ long lOldTimePos = m_wndTimeScroll.GetScrollPos ();
+ long lNewTimeZoom = CLIP (2, m_lTimeZoom - 2, 16);
+ long lNewTimePos = lOldTimePos * lNewTimeZoom / lOldTimeZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lTimeZoom = lNewTimeZoom;
+ RecalcTimeScrollInfo ();
+ m_wndTimeScroll.SetScrollPos (lNewTimePos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ m_pTimeScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ //m_bAutoPageUpdate = TRUE;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+
+// 時間方向ズームアップ(20091220:左端位置保持機能追加、自動ページ更新自動オフ追加)
+void CTrackListFrame::OnTimeZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldTimeZoom = m_lTimeZoom;
+ long lOldTimePos = m_wndTimeScroll.GetScrollPos ();
+ long lNewTimeZoom = CLIP (2, m_lTimeZoom + 2, 16);
+ long lNewTimePos = lOldTimePos * lNewTimeZoom / lOldTimeZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bAutoPageUpdate = FALSE;
+ m_lTimeZoom = lNewTimeZoom;
+ RecalcTimeScrollInfo ();
+ m_wndTimeScroll.SetScrollPos (lNewTimePos);
+ m_lTimeScrollPos = m_wndTimeScroll.GetScrollPos ();
+ m_pTimeScaleView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ //m_bAutoPageUpdate = TRUE;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 行方向ズームダウン(20091220:上端位置保持機能追加)
+void CTrackListFrame::OnRowZoomDown () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldRowZoom = m_lRowZoom;
+ long lOldRowPos = m_wndRowScroll.GetScrollPos ();
+ long lNewRowZoom = CLIP (16, m_lRowZoom - 8, 64);
+ long lNewRowPos = lOldRowPos * lNewRowZoom / lOldRowZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lRowZoom = lNewRowZoom;
+ RecalcRowScrollInfo ();
+ m_wndRowScroll.SetScrollPos (lNewRowPos);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackModeView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 行方向ズームアップ(20091220:上端位置保持機能追加)
+void CTrackListFrame::OnRowZoomUp () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lOldRowZoom = m_lRowZoom;
+ long lOldRowPos = m_wndRowScroll.GetScrollPos ();
+ long lNewRowZoom = CLIP (16, m_lRowZoom + 8, 64);
+ long lNewRowPos = lOldRowPos * lNewRowZoom / lOldRowZoom;
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_lRowZoom = lNewRowZoom;
+ RecalcRowScrollInfo ();
+ m_wndRowScroll.SetScrollPos (lNewRowPos);
+ m_lRowScrollPos = m_wndRowScroll.GetScrollPos ();
+ m_pTrackScaleView->Invalidate ();
+ m_pTrackModeView->Invalidate ();
+ m_pTrackTimeView->Invalidate ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 水平スクロール
+void CTrackListFrame::OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndColumnScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lColumnScrollPos;
+ switch (nSBCode) {
+ case SB_LINELEFT:
+ lNewPos = m_lColumnScrollPos - m_lColumnZoom;
+ break;
+ case SB_LINERIGHT:
+ lNewPos = m_lColumnScrollPos + m_lColumnZoom;
+ break;
+ case SB_PAGELEFT:
+ lNewPos = m_lColumnScrollPos - m_lColumnZoom * 4;
+ break;
+ case SB_PAGERIGHT:
+ lNewPos = m_lColumnScrollPos + m_lColumnZoom * 4;
+ break;
+ case SB_LEFT: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_RIGHT: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetColumnScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_pTrackModeView->SetFocus ();
+ }
+ else if (pScrollBar == &m_wndTimeScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lTimeScrollPos;
+ switch (nSBCode) {
+ case SB_LINELEFT:
+ lNewPos = m_lTimeScrollPos - m_lTimeZoom * 2;
+ break;
+ case SB_LINERIGHT:
+ lNewPos = m_lTimeScrollPos + m_lTimeZoom * 2;
+ break;
+ case SB_PAGELEFT:
+ lNewPos = m_lTimeScrollPos - m_lTimeZoom * 16;
+ break;
+ case SB_PAGERIGHT:
+ lNewPos = m_lTimeScrollPos + m_lTimeZoom * 16;
+ break;
+ case SB_LEFT: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_RIGHT: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetTimeScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_bAutoPageUpdate = FALSE;
+ m_pTrackTimeView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 垂直スクロール
+void CTrackListFrame::OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (pScrollBar == &m_wndRowScroll) {
+ int nMin = 0;
+ int nMax = 0;
+ pScrollBar->GetScrollRange (&nMin, &nMax);
+ long lNewPos = m_lRowScrollPos;
+ switch (nSBCode) {
+ case SB_LINEDOWN:
+ lNewPos = m_lRowScrollPos + m_lRowZoom;
+ break;
+ case SB_LINEUP:
+ lNewPos = m_lRowScrollPos - m_lRowZoom;
+ break;
+ case SB_PAGEDOWN:
+ lNewPos = m_lRowScrollPos + m_lRowZoom * 12;
+ break;
+ case SB_PAGEUP:
+ lNewPos = m_lRowScrollPos - m_lRowZoom * 12;
+ break;
+ case SB_TOP: // 20100206追加
+ lNewPos = nMin;
+ break;
+ case SB_BOTTOM: // 20100206追加
+ lNewPos = nMax;
+ break;
+ case SB_THUMBTRACK:
+ lNewPos = nPos;
+ break;
+ }
+ SetRowScrollPos (CLIP (0, lNewPos, 0x7FFFFFFF));
+ m_pTrackModeView->SetFocus ();
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+
+
+// 『トラックを1行挿入』
+void CTrackListFrame::OnTrackListInsertTrack () {
+ _RPTF0 (_CRT_WARN, "OnTrackListInsertTrack\n");
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ MIDITrack* pLastTrack = MIDIData_GetLastTrack (pMIDIData);
+ // SMFフォーマット0の場合
+ if (lFormat == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_ADD_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // SMFフォーマット1でトラック0の場合
+ if (lFormat == 1 && lTrackIndex == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_ADD_TRACK_BEFORE_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // MIDIデータのトラック数が65536以上の場合
+ if (lTrackCount >= MAXMIDITRACKNUM) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_ADD_TRACK_ANY_MORE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // 新規MIDIトラックの作成
+ long i = 0;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pNewTrack = MIDITrack_Create ();
+ if (pNewTrack == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_OR_INSUFFICIENT_RESOURCE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // カレントMIDIトラックが存在する場合、そのトラックのプロパティをコピー
+ if (pMIDITrack) {
+ i = lTrackIndex;
+ pNewTrack->m_lInputOn = pMIDITrack->m_lInputOn;
+ pNewTrack->m_lInputPort = pMIDITrack->m_lInputPort;
+ pNewTrack->m_lInputChannel = pMIDITrack->m_lInputChannel;
+ pNewTrack->m_lOutputOn = pMIDITrack->m_lOutputOn;
+ pNewTrack->m_lOutputPort = pMIDITrack->m_lOutputPort;
+ pNewTrack->m_lOutputChannel = pMIDITrack->m_lOutputChannel;
+ pNewTrack->m_lViewMode = pMIDITrack->m_lViewMode;
+ pNewTrack->m_lForeColor = pMIDITrack->m_lForeColor;
+ pNewTrack->m_lBackColor = pMIDITrack->m_lBackColor;
+ pNewTrack->m_lKeyPlus = pMIDITrack->m_lKeyPlus;
+ pNewTrack->m_lVelocityPlus = pMIDITrack->m_lVelocityPlus;
+ pNewTrack->m_lTimePlus = pMIDITrack->m_lTimePlus;
+ pNewTrack->m_lReserved1 = pMIDITrack->m_lReserved1;
+ pNewTrack->m_lReserved2 = pMIDITrack->m_lReserved2;
+ pNewTrack->m_lReserved3 = pMIDITrack->m_lReserved3;
+ pNewTrack->m_lReserved4 = pMIDITrack->m_lReserved4;
+ pNewTrack->m_lUser1 = pMIDITrack->m_lUser1;
+ pNewTrack->m_lUser2 = pMIDITrack->m_lUser2;
+ pNewTrack->m_lUser3 = pMIDITrack->m_lUser3;
+ pNewTrack->m_lUserFlag = pMIDITrack->m_lUserFlag;
+ }
+ // カレントMIDIトラックが存在しない場合、新規MIDIトラックのプロパティを適宜設定
+ else {
+ i = lTrackCount;
+ MIDITrack_SetInputOn (pNewTrack, 1);
+ MIDITrack_SetInputPort (pNewTrack, 0);
+ MIDITrack_SetInputChannel (pNewTrack, (i + 15) % 16);
+ MIDITrack_SetOutputOn (pNewTrack, 1);
+ MIDITrack_SetOutputPort (pNewTrack, 0);
+ MIDITrack_SetOutputChannel (pNewTrack, (i + 15) % 16);
+ MIDITrack_SetViewMode (pNewTrack, 0);
+ MIDITrack_SetForeColor (pNewTrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]);
+ MIDITrack_SetBackColor (pNewTrack, 0x00FFFFFF);
+ MIDITrack_SetKeyPlus (pNewTrack, 0);
+ MIDITrack_SetVelocityPlus (pNewTrack, 0);
+ MIDITrack_SetTimePlus (pNewTrack, 0);
+ pNewTrack->m_lReserved1 = 0;
+ pNewTrack->m_lReserved2 = 0;
+ pNewTrack->m_lReserved3 = 0;
+ pNewTrack->m_lReserved4 = 0;
+ pNewTrack->m_lUser1 = 0;
+ pNewTrack->m_lUser2 = 0;
+ pNewTrack->m_lUser3 = 0;
+ pNewTrack->m_lUserFlag = 0;
+ }
+ // 新規MIDIトラックの挿入
+ if (pMIDITrack) {
+ MIDIData_InsertTrackBefore (pMIDIData, pNewTrack, pMIDITrack);
+ }
+ else {
+ MIDIData_InsertTrackAfter (pMIDIData, pNewTrack, pLastTrack);
+ }
+ // 履歴に記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_INSERT_TRACK));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pNewTrack));
+ // 新規MIDIトラックにデフォルトのMIDIイベントを追加
+ VERIFY (pSekaijuDoc->AddDefaultEventToTrack (pNewTrack, i == 0 ? 0x000B : 0x0007, pCurHistoryUnit));
+
+ //((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow++;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『トラックを1行挿入』
+void CTrackListFrame::OnUpdateTrackListInsertTrackUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ if (lFormat == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ else if (lFormat == 1 && lTrackIndex == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ else if (lTrackCount >= MAXMIDITRACKNUM) {
+ pCmdUI->Enable (FALSE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 『トラックを1行複写』
+void CTrackListFrame::OnTrackListDuplicateTrack () {
+ _RPTF0 (_CRT_WARN, "OnTrackListInsertCopyTrack\n");
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ // SMFフォーマット0の場合
+ if (lFormat == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_DUPLICATE_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // SMFフォーマット1でトラック0の場合
+ if (lFormat == 1 && lTrackIndex == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_DUPLICATE_THE_FIRST_TRACK_IN_FORMAT1_MIDIATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // カレントトラックが存在しない場合
+ if (pMIDITrack == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_THE_SOURCE_TRACK_IS_EMPTY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // このMIDIデータのトラック数が65536以上の場合
+ if (lTrackCount >= MAXMIDITRACKNUM) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_ADD_TRACK_ANY_MORE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // 新規MIDIトラックの作成
+ long i = lTrackIndex;
+ MIDITrack* pNewTrack = MIDITrack_CreateClone (pMIDITrack);
+ if (pNewTrack == NULL) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INSUFFICIENT_MEMORY_OR_INSUFFICIENT_RESOURCE));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // 履歴記録
+ CHistoryUnit* pHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DUPLICATE_TRACK));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 新規MIDIトラックの挿入
+ MIDIData_InsertTrackBefore (pMIDIData, pNewTrack, pMIDITrack);
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pNewTrack));
+ // 新しいMIDIトラックにデフォルトで含まれているイベントの履歴記録
+ MIDIEvent* pNewEvent = NULL;
+ forEachEvent (pNewTrack, pNewEvent) {
+ if (pNewEvent->m_pPrevCombinedEvent == NULL) {
+ VERIFY (pHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent));
+ }
+ }
+ //((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow++;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『トラックを1行複写』
+void CTrackListFrame::OnUpdateTrackListDuplicateTrackUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ // SMFフォーマット0の場合
+ if (lFormat == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ // SMFフォーマット1でトラック0の場合
+ else if (lFormat == 1 && lTrackIndex == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ // カレントトラックが存在しない場合
+ else if (pMIDITrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+ // このMIDIデータのトラック数が65536以上の場合
+ else if (lTrackCount >= MAXMIDITRACKNUM) {
+ pCmdUI->Enable (FALSE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 『トラックを1行削除』
+void CTrackListFrame::OnTrackListDeleteTrack () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ // SMFフォーマット2以外でトラック0の場合
+ if (lTrackIndex == 0 && lFormat != 2) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_DELETE_THE_FIRST_TRACK));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // カレントトラックが存在しない場合
+ if (pMIDITrack == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_THE_SPECIFIED_TRACK_IS_EMPTY));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // ヒストリ記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_DELETE_TRACK));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ // トラックをMIDIデータから除去
+ MIDIData_RemoveTrack (pMIDIData, pMIDITrack);
+ //((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow--;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『トラックを1行削除』
+void CTrackListFrame::OnUpdateTrackListDeleteTrackUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ // SMFフォーマット2以外でトラック0の場合
+ if (lTrackIndex == 0 && lFormat != 2) {
+ pCmdUI->Enable (FALSE);
+ }
+ // カレントトラックが存在しない場合
+ else if (pMIDITrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+ else {
+ pCmdUI->Enable (TRUE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 『トラックを1行上へ』
+void CTrackListFrame::OnTrackListMoveUpTrack () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ // カレントトラックが存在しない場合
+ if (pMIDITrack == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_NO_TRACK_IS_SELECTED_TO_BE_MOVED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // SMFフォーマット0の場合
+ if (lFormat == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MOVE_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // SMFフォーマット1でカレントトラックが0又は1の場合
+ if (lFormat == 1 && lTrackIndex <= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MOVE_UP_THE_FIRST_AND_THE_SECOND_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // SMFフォーマット2でカレントトラックが0の場合
+ if (lFormat == 2 && lTrackIndex == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MOVE_UP_THE_FIRST_TRACK_IN_FORMAT2_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // 履歴記録
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ MIDITrack* pTempTrack = pMIDITrack->m_pPrevTrack;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MOVE_TRACK));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ // 該当トラックをいったんMIDIデータから除去する
+ long lRet = MIDIData_RemoveTrack (pMIDIData, pMIDITrack);
+ if (lRet == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_TRACK_MOVE_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // 除去したトラックをMIDIデータに挿入する
+ lRet = MIDIData_InsertTrackBefore (pMIDIData, pMIDITrack, pTempTrack);
+ if (lRet == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_TRACK_MOVE_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pMIDITrack));
+ ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow--;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+// トラックを1行上へ
+void CTrackListFrame::OnUpdateTrackListMoveUpTrackUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ // カレントトラックが存在しない場合
+ if (pMIDITrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+ // SMFフォーマット0の場合
+ if (lFormat == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ // SMFフォーマット1でカレントトラックが0又は1の場合
+ if (lFormat == 1 && lTrackIndex <= 1) {
+ pCmdUI->Enable (FALSE);
+ }
+ // SMFフォーマット2でカレントトラックが0の場合
+ if (lFormat == 2 && lTrackIndex == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 『トラックを1行下へ』
+void CTrackListFrame::OnTrackListMoveDownTrack () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ // カレントトラックが存在しない場合
+ if (pMIDITrack == NULL) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_NO_TRACK_IS_SELECTED_TO_BE_MOVED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // SMFフォーマット0の場合
+ if (lFormat == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MOVE_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // SMFフォーマット1でカレントトラックが0の場合
+ if (lFormat == 1 && lTrackIndex == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MOVE_DOWN_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // カレントトラックが最後のトラックの場合
+ if (lTrackIndex >= lTrackCount - 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_MOVE_DOWN_THIS_TRACK_ANY_MORE));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ MIDITrack* pTempTrack = pMIDITrack->m_pNextTrack;
+ // 履歴記録
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MOVE_TRACK));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack));
+ long lRet = MIDIData_RemoveTrack (pMIDIData, pMIDITrack);
+ // 該当トラックをいったんMIDIデータから除去する
+ if (lRet == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_TRACK_MOVE_FAILED));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ // 除去したトラックをMIDIデータに挿入する
+ lRet = MIDIData_InsertTrackAfter (pMIDIData, pMIDITrack, pTempTrack);
+ if (lRet == 0) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_TRACK_MOVE_FAILED));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pMIDITrack));
+ ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow++;
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 『トラックを1行下へ』
+void CTrackListFrame::OnUpdateTrackListMoveDownTrackUI (CCmdUI* pCmdUI) {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // リアルタイム入力中は何もしない。
+ if (pSekaijuApp->m_bRecording) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ // MIDIデータが編集ロックされている場合は何もしない。
+ if (pSekaijuDoc->m_bEditLocked) {
+ pCmdUI->Enable (FALSE);
+ return;
+ }
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackIndex = ((CTrackListTrackModeView*)m_pTrackModeView)->m_lCurRow;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ // カレントトラックが存在しない場合
+ if (pMIDITrack == NULL) {
+ pCmdUI->Enable (FALSE);
+ }
+ // SMFフォーマット0の場合
+ if (lFormat == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ // SMFフォーマット1でカレントトラックが0の場合
+ if (lFormat == 1 && lTrackIndex == 0) {
+ pCmdUI->Enable (FALSE);
+ }
+ // カレントトラックが最後のトラックの場合
+ if (lTrackIndex >= lTrackCount - 1) {
+ pCmdUI->Enable (FALSE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 『選択(S)』
+void CTrackListFrame::OnTrackListSelect () {
+ m_lCurTool = ID_TRACKLIST_SELECT;
+}
+
+// 『選択(S)』
+void CTrackListFrame::OnUpdateTrackListSelectUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_TRACKLIST_SELECT ? 1 : 0);
+}
+
+// 『試聴(B)』
+void CTrackListFrame::OnTrackListSpeaker () {
+ m_lCurTool = ID_TRACKLIST_SPEAKER;
+}
+
+// 『試聴(B)』
+void CTrackListFrame::OnUpdateTrackListSpeakerUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_lCurTool == ID_TRACKLIST_SPEAKER ? 1 : 0);
+}
+
+// 『自動ページ更新』
+void CTrackListFrame::OnTrackListAutoPageUpdate () {
+ m_bAutoPageUpdate = !m_bAutoPageUpdate;
+}
+
+// 『自動ページ更新』
+void CTrackListFrame::OnUpdateTrackListAutoPageUpdateUI (CCmdUI* pCmdUI) {
+ pCmdUI->SetCheck (m_bAutoPageUpdate);
+}
+
+// 『トラックビューをCSV又はテキストで保存』
+void CTrackListFrame::OnTrackListSaveAs () {
+ CString strFileName;
+ CSekaijuFileDlg theFileDlg (FALSE);
+
+ CString strTitle;
+ VERIFY (strTitle.LoadString (AFX_IDS_APP_TITLE));
+
+ // 注意事項:MSDN2002/4のOPENFILENAME構造体の説明
+ // For compatibility reasons, the Places Bar is hidden if Flags is set to
+ // OFN_ENABLEHOOK and lStructSize is OPENFILENAME_SIZE_VERSION_400.
+ // CFileDialogクラスでは強制的にOFN_ENABLEHOOKでAfxCommDlgProcにフックする。
+
+ // 20081028 : m_ofnの値の設定(76or88)は次による
+ //#ifndef OPENFILENAME_SIZE_VERSION_400
+ // theFileDlg.m_ofn.lStructSize = sizeof(OPENFILENAME); //=76(Windows95/98/ME style)
+ //#else
+ // theFileDlg.m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; //=76(Windows95/98/ME style)
+ //#endif
+
+ #if (_WIN32_WINNT >= 0x0500)
+ theFileDlg.m_ofn.lStructSize = 88; //=88(With placebar)
+ theFileDlg.m_ofn.pvReserved = NULL;
+ theFileDlg.m_ofn.dwReserved = 0;
+ theFileDlg.m_ofn.FlagsEx = 0;
+ #else
+ theFileDlg.m_ofn.lStructSize = 76; //=76(Without placebar if OFN_ENABLEHOOK used)
+ #endif
+
+ theFileDlg.m_ofn.nMaxFileTitle = _MAX_PATH;
+
+ //theFileDlg.m_ofn.Flags |= lFlags;
+
+ // 拡張子フィルター
+ CString strFilter;
+ CString strDefault;
+ CString strFilterCSV[3];
+ CString strFilterTXT[3];
+ VERIFY (strFilterCSV[0].LoadString (IDS_COMMA_SEPARATED_TEXT_FILES_AD_CSV));
+ VERIFY (strFilterCSV[1].LoadString (IDS_AD_CSV));
+ VERIFY (strFilterCSV[2].LoadString (IDS_D_CSV));
+ VERIFY (strFilterTXT[0].LoadString (IDS_TAB_SEPARATED_TEXT_FILES_AD_TXT));
+ VERIFY (strFilterTXT[1].LoadString (IDS_AD_TXT));
+ VERIFY (strFilterTXT[2].LoadString (IDS_D_TXT));
+
+ // 拡張子フィルター追加設定
+ strFilter += strFilterCSV[0]; // カンマ区切りテキストファイル(*.csv)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterCSV[1]; // *.csv
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterTXT[0]; // タブ区切りテキストファイル(*.txt)
+ strFilter += (TCHAR)_T('\0');
+ strFilter += strFilterTXT[1]; // *.txt
+ strFilter += (TCHAR)_T('\0');
+ strFilter += (TCHAR)_T('\0');
+ theFileDlg.m_ofn.nMaxCustFilter = 1024;
+
+ theFileDlg.m_ofn.lpstrFilter = strFilter;
+#ifndef _MAC
+ theFileDlg.m_ofn.lpstrTitle = strTitle;
+#else
+ theFileDlg.m_ofn.lpstrPrompt = strTitle;
+#endif
+
+ // デフォルトの拡張子設定
+ theFileDlg.m_strDefExt = strFilterCSV[1];
+ theFileDlg.m_ofn.lpstrDefExt = theFileDlg.m_strDefExt;
+
+ // フィルターコンボボックスのデフォルト選択
+ if ((strFileName.Right (4)).CompareNoCase (strFilterCSV[2]) == 0) {
+ theFileDlg.m_ofn.nFilterIndex = 1;
+ }
+ else if ((strFileName.Right (4)).CompareNoCase (strFilterTXT[2]) == 0) {
+ theFileDlg.m_ofn.nFilterIndex = 2;
+ }
+
+ theFileDlg.m_ofn.lpstrFile = strFileName.GetBuffer (_MAX_PATH);
+
+ // ファイルダイアログ.DoModal
+ BOOL bResult = theFileDlg.DoModal() == IDOK ? TRUE : FALSE;
+
+ strFileName.ReleaseBuffer();
+
+ // 拡張子が付いていない場合は、選択したファイルタイプの拡張子を自動的に付ける
+ if (theFileDlg.m_ofn.nFilterIndex == 1 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterCSV[2]) != 0) { // .csv
+ strFileName += strFilterCSV[2];
+ }
+ else if (theFileDlg.m_ofn.nFilterIndex == 2 &&
+ (strFileName.Right (4)).CompareNoCase (strFilterTXT[2]) != 0) { // .txt
+ strFileName += strFilterTXT[2];
+ }
+
+ // キャンセルが押された場合は却下
+ if (bResult == FALSE) {
+ return;
+ }
+
+ // ビューがない場合は却下
+ if (m_pTrackModeView == NULL) {
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_CURRENT_VIEW_IS_NOT_EXIST));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+ CTrackListTrackModeView* pTrackModeView = (CTrackListTrackModeView*)m_pTrackModeView;
+
+ // 文字列バッファ確保
+ CString strTextLine;
+ CString strCell;
+ CString strSeparator;
+ if (theFileDlg.m_ofn.nFilterIndex == 1) {
+ strSeparator = _T(", ");
+ }
+ else {
+ strSeparator = _T("\t");
+ }
+
+ // ファイルオープン
+ CStdioFile theFile;
+ BOOL bRet = theFile.Open (strFileName, CFile::modeCreate | CFile::modeWrite);
+ if (bRet == FALSE) {
+ CString strMsg;
+ CString strFormat;
+ strFormat.LoadString (IDS_S_N_FILE_OPEN_FAILED);
+ strMsg.Format (strFormat, strFileName);
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ return;
+ }
+
+ // 先頭行の文字列書き込み
+ long i = 0;
+ long j = 0;
+ strTextLine.Format (_T(""));
+ strTextLine += strSeparator;
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ strCell = GetColumnTitle (j);
+ strTextLine += strCell;
+ if (j < TRACKLISTFRAME_NUMCOLUMN - 1) {
+ strTextLine += strSeparator;
+ }
+ else {
+ strTextLine += _T("\n");
+ }
+ }
+ theFile.WriteString (strTextLine);
+
+ // 各行の文字列書き込み
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (pMIDIData);
+ long lRowCount = MIDIData_CountTrack (pMIDIData);
+ for (i = 0; i < lRowCount; i++) {
+ strTextLine.Format (_T("%d"), i + 1);
+ strTextLine += strSeparator;
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ strCell = pTrackModeView->GetCellString (i, j);
+ strTextLine += strCell;
+ if (j < TRACKLISTFRAME_NUMCOLUMN - 1) {
+ strTextLine += strSeparator;
+ }
+ else {
+ strTextLine += _T("\n");
+ }
+ }
+ theFile.WriteString (strTextLine);
+ }
+
+ // ファイルクローズ
+ theFile.Close ();
+}
+
+// 『トラックビューをCSV又はテキストで保存』
+void CTrackListFrame::OnUpdateTrackListSaveAsUI (CCmdUI* pCmdUI) {
+}
+
+
+
+
+
diff --git a/src/TrackListFrame.h b/src/TrackListFrame.h
new file mode 100644
index 0000000..aece321
--- /dev/null
+++ b/src/TrackListFrame.h
@@ -0,0 +1,209 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストフレームウィンドウクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#define TRACKLISTFRAME_NUMCOLUMN 21
+
+#define TRACKLISTFRAME_TRACKNAME 0x01
+#define TRACKLISTFRAME_VISIBLE 0x30
+#define TRACKLISTFRAME_ENABLE 0x31
+#define TRACKLISTFRAME_VIEWMODE 0x33
+#define TRACKLISTFRAME_FORECOLOR 0x34
+#define TRACKLISTFRAME_BACKCOLOR 0x35
+#define TRACKLISTFRAME_INPUTON 0x36
+#define TRACKLISTFRAME_INPUTPORT 0x37
+#define TRACKLISTFRAME_INPUTCHANNEL 0x38
+#define TRACKLISTFRAME_OUTPUTON 0x39
+#define TRACKLISTFRAME_OUTPUTPORT 0x3A
+#define TRACKLISTFRAME_OUTPUTCHANNEL 0x3B
+#define TRACKLISTFRAME_TIMEPLUS 0x3C
+#define TRACKLISTFRAME_KEYPLUS 0x3D
+#define TRACKLISTFRAME_VELOCITYPLUS 0x3E
+#define TRACKLISTFRAME_NUMEVENT 0xFF
+#define TRACKLISTFRAME_CONTROLCHANGE 0xB0
+#define TRACKLISTFRAME_PROGRAMCHANGE 0xC0
+
+#ifndef _TRACKLISTFRAME_H_
+#define _TRACKLISTFRAME_H_
+
+class CTrackListFrame : public CChildFrame {
+ DECLARE_DYNCREATE (CTrackListFrame)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ long m_lToolBar1Height; // ツールバーの高さ[pixel]
+ long m_lScaleHeight; // 上部目盛りビューの高さ[pixel]
+ long m_lScaleWidth; // 左部目盛りビューの幅[pixel]
+ long m_lTrackHeight; // トラックビューの高さ[pixel]
+ long m_lModeWidth; // モードビュー(左ペイン)の幅[pixel]
+ long m_lTimeWidth; // タイムビュー(右ペイン)の幅[pixel]
+ long m_lHScrollBarHeight; // 水平スクロールバーの高さ[pixel]
+ long m_lVScrollBarWidth; // 垂直スクロールバーの幅[pixel]
+ long m_lColumnZoom; // 列方向拡大倍率[倍]
+ long m_lTimeZoom; // 時間方向拡大倍率[倍]
+ long m_lRowZoom; // 行方向拡大倍率[倍]
+ long m_lColumnScrollPos; // 列方向スクロール位置[pixel]
+ long m_lTimeScrollPos; // 時間方向スクロール位置[pixel]
+ long m_lRowScrollPos; // 行方向スクロール位置[pixel]
+ long m_lColumnBaseWidth[TRACKLISTFRAME_NUMCOLUMN]; // 各列の幅(拡大倍率をかけていない)[pixel]
+ CString m_strColumnTitle[TRACKLISTFRAME_NUMCOLUMN]; // 各列のタイトル文字列
+ long m_lColumnContent[TRACKLISTFRAME_NUMCOLUMN]; // 各列の表示内容識別コード
+ // 各列の表示内容識別コードは、
+ // TRACKLISTFRAME_TRACKNAME〜TRACKLISTFRAME_PROGRAMCHANGEの中から選択する。
+ // TRACKLISTFRAME_CONTROLCHANGEでは9〜16ビット目でCC#番号を指定する。
+
+public:
+ CSekaijuToolBar m_wndToolBar1; // ツールバー
+ CView* m_pDummyView; // ダミービュー(Visible=FALSE)へのポインタ
+ CView* m_pPrintView; // 印刷ビュー(Visible=FALSE)へのポインタ
+ CView* m_pScaleView; // 目盛りビューへのポインタ
+ CView* m_pModeScaleView; // 項目目盛りビューへのポインタ
+ CView* m_pTimeScaleView; // タイム目盛りビューへのポインタ
+ CView* m_pTrackScaleView; // トラック番号目盛りビューへのポインタ
+ CView* m_pTrackModeView; // トラック番号-項目ビュー(左ペイン)へのポインタ
+ CView* m_pTrackTimeView; // トラック番号-タイムビュー(右ペイン)へのポインタ
+ CScrollBar m_wndColumnScroll; // 列方向スクロールバー
+ CScrollBar m_wndTimeScroll; // 時間方向スクロールバー
+ CScrollBar m_wndRowScroll; // 行方向スクロールバー
+ CScrollBar m_wndSizeScroll; // サイズスクロールバー
+ CBitmapButton m_wndColumnZoomUp; // 列方向拡大ボタン
+ CBitmapButton m_wndColumnZoomDown; // 列方向縮小ボタン
+ CBitmapButton m_wndTimeZoomUp; // 時間方向拡大ボタン
+ CBitmapButton m_wndTimeZoomDown; // 時間方向縮小ボタン
+ CBitmapButton m_wndRowZoomUp; // 行方向拡大ボタン
+ CBitmapButton m_wndRowZoomDown; // 行方向縮小ボタン
+
+public:
+ CFont m_theFont; // トラックビューウィンドウで使うフォント
+ long m_lCurTool; // 現在選択されているツール番号(0=選択,1=試聴)
+ BOOL m_bAutoPageUpdate; // 自動的にページを更新するか?
+
+protected:
+ CPoint m_ptMouseDown; // マウスが押された座標(スプリッターを動かすのに使う)
+ CPoint m_ptMouseMoveOld; // マウスが動かされた前回の座標(スプリッターを動かすのに使う)
+
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListFrame (); // コンストラクタ
+ virtual ~CTrackListFrame(); // デストラクタ
+
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuDoc* GetDocument ();
+ virtual long GetColumnBaseWidth (long lColumn);
+ virtual long SetColumnBaseWidth (long lColumn, long lColumnBaseWidth);
+ virtual CString GetColumnTitle (long lColumn);
+ virtual long GetColumnContent (long lColumn);
+ virtual long GetRowZoom ();
+ virtual long GetColumnZoom ();
+ virtual long GetTimeZoom ();
+ virtual long GetColumnLeft (long lColumn);
+ virtual long GetColumnWidth (long lColumn);
+ virtual long XtoColumn (long x);
+ virtual long ColumntoX (long lMode);
+ virtual long XtoTime (long x);
+ virtual long TimetoX (long lTime);
+ virtual long YtoRow (long y);
+ virtual long RowtoY (long lKey);
+ virtual long GetVisibleTopRow ();
+ virtual long GetVisibleBottomRow ();
+ virtual long GetVisibleLeftTime ();
+ virtual long GetVisibleRightTime ();
+ virtual long GetTimeScrollPos ();
+ virtual long GetRowScrollPos ();
+ virtual long GetColumnScrollPos ();
+ virtual long SetTimeScrollPos (long lTimeScrollPos);
+ virtual long SetColumnScrollPos (long lModeScrollPos);
+ virtual long SetRowScrollPos (long lTrackScrollPos);
+ virtual void DrawSplitterCaptor (CDC* pDC, CPoint pt);
+ virtual void RecalcRowScrollInfo ();
+ virtual void RecalcColumnScrollInfo ();
+ virtual void RecalcTimeScrollInfo ();
+
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+ virtual void OnUpdateFrameTitle (BOOL bAddToTitle);
+ virtual void RecalcLayout (BOOL bNotify = TRUE);
+ virtual BOOL OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ virtual BOOL OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnSize (UINT nType, int cx, int cy);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg BOOL OnEraseBkgnd (CDC* pDC);
+ afx_msg void OnPaint( );
+ afx_msg void OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd);
+ afx_msg void OnClose ();
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnColumnZoomDown ();
+ afx_msg void OnColumnZoomUp ();
+ afx_msg void OnTimeZoomDown ();
+ afx_msg void OnTimeZoomUp ();
+ afx_msg void OnRowZoomDown ();
+ afx_msg void OnRowZoomUp ();
+ afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnTrackListInsertTrack ();
+ afx_msg void OnUpdateTrackListInsertTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListDuplicateTrack ();
+ afx_msg void OnUpdateTrackListDuplicateTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListDeleteTrack ();
+ afx_msg void OnUpdateTrackListDeleteTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListMoveUpTrack ();
+ afx_msg void OnUpdateTrackListMoveUpTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListMoveDownTrack ();
+ afx_msg void OnUpdateTrackListMoveDownTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListSelect ();
+ afx_msg void OnUpdateTrackListSelectUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListSpeaker ();
+ afx_msg void OnUpdateTrackListSpeakerUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListAutoPageUpdate ();
+ afx_msg void OnUpdateTrackListAutoPageUpdateUI (CCmdUI* pCmdUI);
+ afx_msg void OnTrackListSaveAs ();
+ afx_msg void OnUpdateTrackListSaveAsUI (CCmdUI* pCmdUI);
+
+
+ DECLARE_MESSAGE_MAP()
+};
+
+
+#endif
+
diff --git a/src/TrackListModeScaleView.cpp b/src/TrackListModeScaleView.cpp
new file mode 100644
index 0000000..934b7dc
--- /dev/null
+++ b/src/TrackListModeScaleView.cpp
@@ -0,0 +1,244 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストモードスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolbar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "TrackListModeScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE(CTrackListModeScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CTrackListModeScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListModeScaleView::CTrackListModeScaleView () {
+}
+
+// デストラクタ
+CTrackListModeScaleView::~CTrackListModeScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動
+void CTrackListModeScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ pDC->SetWindowOrg (pTrackListFrame->GetColumnScrollPos (), 0);
+}
+
+// 描画
+void CTrackListModeScaleView::OnDraw (CDC* pDC) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+ CFont* pOldFont = pDC->SelectObject (&(pTrackListFrame->m_theFont));
+ CRect theRect (0, 0, 0, 0);
+ long lColumnZoom = pTrackListFrame->GetColumnZoom ();
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ // 背景の塗りつぶし
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+ pDC->SetBkMode (TRANSPARENT);
+ // 各列の描画
+ for (int j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j ++) {
+ theRect.top = rcClient.top;
+ theRect.bottom = rcClient.bottom;
+ theRect.left = theRect.right;
+ theRect.right = theRect.right + pTrackListFrame->GetColumnBaseWidth (j) * lColumnZoom;
+ pDC->Draw3dRect (&theRect, lColorBtnHighlight, lColorBtnShadow);
+ pDC->DrawText (pTrackListFrame->GetColumnTitle (j), &theRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->SelectObject (pOldFont);
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CTrackListModeScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キー押し下げ時
+void CTrackListModeScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ pTrackListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+}
+
+
+// マウス左ボタン押された時
+void CTrackListModeScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), 0);
+ // カーソルが境界上にあるか調べる
+ long j = 0;
+ long lBorderX = 0;
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ lBorderX += pTrackListFrame->GetColumnBaseWidth (j) * pTrackListFrame->GetColumnZoom ();
+ if (lBorderX - 2 <= point.x && point.x <= lBorderX + 2) {
+ break;
+ }
+ }
+ // カーソルが境界上にあった場合
+ if (0 <= j && j < TRACKLISTFRAME_NUMCOLUMN) {
+ SetCapture ();
+ m_lTempColumnIndex = j;
+ m_lTempColumnBaseWidth = pTrackListFrame->GetColumnBaseWidth (j);
+ m_ptMouseDown = m_ptMouseMoveOld = point;
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+}
+
+// マウス右ボタン押された時
+void CTrackListModeScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+
+}
+
+// マウス左ボタン離されたとき
+void CTrackListModeScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ if (GetCapture () == this) {
+ ReleaseCapture ();
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ pTrackListFrame->RecalcColumnScrollInfo ();
+ pTrackListFrame->m_pModeScaleView->Invalidate ();
+ pTrackListFrame->m_pTrackModeView->Invalidate ();
+ }
+}
+
+// マウス右ボタン離されたとき
+void CTrackListModeScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+
+}
+
+// マウスが動かされたとき
+void CTrackListModeScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), 0);
+ // キャプター中
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CSize szMouseDelta = point.x - m_ptMouseDown.x;
+ long lNewColumnBaseWidth =
+ (m_lTempColumnBaseWidth * pTrackListFrame->GetColumnZoom () + szMouseDelta.cx) /
+ pTrackListFrame->GetColumnZoom ();
+ lNewColumnBaseWidth = CLIP (1, lNewColumnBaseWidth, 1024);
+ if (lNewColumnBaseWidth != pTrackListFrame->GetColumnBaseWidth (m_lTempColumnIndex)) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ pTrackListFrame->SetColumnBaseWidth (m_lTempColumnIndex, lNewColumnBaseWidth);
+ pTrackListFrame->m_pModeScaleView->Invalidate ();
+ pTrackListFrame->m_pTrackModeView->Invalidate ();
+ }
+ m_ptMouseMoveOld = point;
+ }
+ // 非キャプター中
+ else {
+ // カーソルが境界上にあるか調べる
+ long j = 0;
+ long lBorderX = 0;
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ lBorderX += pTrackListFrame->GetColumnBaseWidth (j) * pTrackListFrame->GetColumnZoom ();
+ if (lBorderX - 2 <= point.x && point.x <= lBorderX + 2) {
+ break;
+ }
+ }
+ // カーソルが境界上にあった場合
+ if (0 <= j && j < TRACKLISTFRAME_NUMCOLUMN) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeWE);
+ }
+ // カーソルが境界上にない場合
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorArrow);
+ }
+ }
+}
+
+// マウスホイールが回された時
+void CTrackListModeScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pTrackListFrame->SetRowScrollPos (lRowScrollPos);
+ }
+
+}
diff --git a/src/TrackListModeScaleView.h b/src/TrackListModeScaleView.h
new file mode 100644
index 0000000..343b2de
--- /dev/null
+++ b/src/TrackListModeScaleView.h
@@ -0,0 +1,73 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストモードスケールビュークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTMODESCALEVIEW_H_
+#define _TRACKLISTMODESCALEVIEW_H_
+
+class CTrackListModeScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CTrackListModeScaleView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMoveOld; // マウスが動かされたときの前回の前回の座標
+ long m_lTempColumnIndex; // 一時的な列番号
+ long m_lTempColumnBaseWidth; // 一時的な列幅(拡大倍率をかけていない)[pixel]
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListModeScaleView (); // コンストラクタ
+ virtual ~CTrackListModeScaleView(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
+
diff --git a/src/TrackListOption1Page.cpp b/src/TrackListOption1Page.cpp
new file mode 100644
index 0000000..39da531
--- /dev/null
+++ b/src/TrackListOption1Page.cpp
@@ -0,0 +1,124 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストオプション1ページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "TrackListOption1Page.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListOption1Page::CTrackListOption1Page () : CPropertyPage (CTrackListOption1Page::IDD) {
+ m_lDefRowZoom = 0;
+ m_lDefColumnZoom = 0;
+ m_lDefTimeZoom = 0;
+ m_lDefNameWidth = 0;
+ m_lDefColorWidth = 0;
+ m_lDefInputOnWidth = 0;
+ m_lDefInputPortWidth = 0;
+ m_lDefInputChWidth = 0;
+ m_lDefOutputOnWidth = 0;
+ m_lDefOutputPortWidth = 0;
+ m_lDefOutputChWidth = 0;
+ m_lDefViewModeWidth = 0;
+
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CTrackListOption1Page::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFROWZOOM, m_lDefRowZoom);
+ DDV_MinMaxInt (pDX, m_lDefRowZoom, 16, 64);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFCOLUMNZOOM, m_lDefColumnZoom);
+ DDV_MinMaxInt (pDX, m_lDefColumnZoom, 2, 16);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFTIMEZOOM, m_lDefTimeZoom);
+ DDV_MinMaxInt (pDX, m_lDefTimeZoom, 2, 16);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFNAMEWIDTH, m_lDefNameWidth);
+ DDV_MinMaxInt (pDX, m_lDefNameWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFCOLORWIDTH, m_lDefColorWidth);
+ DDV_MinMaxInt (pDX, m_lDefColorWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFINPUTONWIDTH, m_lDefInputOnWidth);
+ DDV_MinMaxInt (pDX, m_lDefInputOnWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFINPUTPORTWIDTH, m_lDefInputPortWidth);
+ DDV_MinMaxInt (pDX, m_lDefInputPortWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFINPUTCHWIDTH, m_lDefInputChWidth);
+ DDV_MinMaxInt (pDX, m_lDefInputChWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFOUTPUTONWIDTH, m_lDefOutputOnWidth);
+ DDV_MinMaxInt (pDX, m_lDefOutputOnWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFOUTPUTPORTWIDTH, m_lDefOutputPortWidth);
+ DDV_MinMaxInt (pDX, m_lDefOutputPortWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFOUTPUTCHWIDTH, m_lDefOutputChWidth);
+ DDV_MinMaxInt (pDX, m_lDefOutputChWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION1_DEFVIEWMODEWIDTH, m_lDefViewModeWidth);
+ DDV_MinMaxInt (pDX, m_lDefViewModeWidth, 1, 32);
+
+}
+
+// ダイアログの初期化
+BOOL CTrackListOption1Page::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFROWZOOMSP))->SetRange (16, 64);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFCOLUMNZOOMSP))->SetRange (2, 16);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFTIMEZOOMSP))->SetRange (2, 16);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFNAMEWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFCOLORWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFINPUTONWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFINPUTPORTWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFINPUTCHWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFOUTPUTONWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFOUTPUTPORTWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFOUTPUTCHWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION1_DEFVIEWMODEWIDTHSP))->SetRange (1, 32);
+ return bRet;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CTrackListOption1Page, CPropertyPage)
+END_MESSAGE_MAP ()
+
+
diff --git a/src/TrackListOption1Page.h b/src/TrackListOption1Page.h
new file mode 100644
index 0000000..7a15557
--- /dev/null
+++ b/src/TrackListOption1Page.h
@@ -0,0 +1,70 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストオプション1ページクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+//
+
+#ifndef _TRACKLISTOPTION1PAGE_H_
+#define _TRACKLISTOPTION1PAGE_H_
+
+class CTrackListOption1Page : public CPropertyPage {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lDefRowZoom; // デフォルトの列方向拡大倍率
+ long m_lDefColumnZoom; // デフォルトの行方向拡大倍率
+ long m_lDefTimeZoom; // デフォルトのタイム方向拡大倍率
+ long m_lDefNameWidth; // デフォルトの名前の幅[pixel]
+ long m_lDefColorWidth; // デフォルトの色の幅[pixel]
+ long m_lDefInputOnWidth; // デフォルトの入力ONの幅[pixel]
+ long m_lDefInputPortWidth; // デフォルトの入力ポートの幅[pixel]
+ long m_lDefInputChWidth; // デフォルトの入力CHの幅[pixel]
+ long m_lDefOutputOnWidth; // デフォルトの出力ONの幅[pixel]
+ long m_lDefOutputPortWidth; // デフォルトの出力ポートの幅[pixel]
+ long m_lDefOutputChWidth; // デフォルトの出力CHの幅[pixel]
+ long m_lDefViewModeWidth; // デフォルトのビューモードの幅[pixel]
+ // ※実際の列の幅[pixel]は、各列の幅に列方向拡大倍率をかけた値となる。
+
+public:
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+ CTrackListOption1Page (); // コンストラクタ
+ enum {IDD = IDD_TRACKLISTOPTION1};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ //afx_msg void OnChangeEnableAutoSave ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/TrackListOption2Page.cpp b/src/TrackListOption2Page.cpp
new file mode 100644
index 0000000..b22dd83
--- /dev/null
+++ b/src/TrackListOption2Page.cpp
@@ -0,0 +1,127 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストオプション2ページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxcmn.h>
+#include <afxext.h>
+
+#include "resource.h"
+#include "TrackListOption2Page.h"
+
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "SekaijuApp.h"
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListOption2Page::CTrackListOption2Page () : CPropertyPage (CTrackListOption2Page::IDD) {
+ m_lDefCC000Width = 0;
+ m_lDefCC032Width = 0;
+ m_lDefPCWidth = 0;
+ m_lDefCC007Width = 0;
+ m_lDefCC010Width = 0;
+ m_lDefCC091Width = 0;
+ m_lDefCC093Width = 0;
+ m_lDefCC094Width = 0;
+ m_lDefKeyShiftWidth = 0;
+ m_lDefVelShiftWidth = 0;
+ m_lDefTimeShiftWidth = 0;
+ m_lDefNumEventWidth = 0;
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// データエクスチェンジ
+void CTrackListOption2Page::DoDataExchange (CDataExchange* pDX) {
+ CDialog::DoDataExchange (pDX);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFCC000WIDTH, m_lDefCC000Width);
+ DDV_MinMaxInt (pDX, m_lDefCC000Width, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFCC032WIDTH, m_lDefCC032Width);
+ DDV_MinMaxInt (pDX, m_lDefCC032Width, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFPCWIDTH, m_lDefPCWidth);
+ DDV_MinMaxInt (pDX, m_lDefPCWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFCC007WIDTH, m_lDefCC007Width);
+ DDV_MinMaxInt (pDX, m_lDefCC007Width, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFCC010WIDTH, m_lDefCC010Width);
+ DDV_MinMaxInt (pDX, m_lDefCC010Width, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFCC091WIDTH, m_lDefCC091Width);
+ DDV_MinMaxInt (pDX, m_lDefCC091Width, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFCC093WIDTH, m_lDefCC093Width);
+ DDV_MinMaxInt (pDX, m_lDefCC093Width, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFCC094WIDTH, m_lDefCC094Width);
+ DDV_MinMaxInt (pDX, m_lDefCC094Width, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFKEYSHIFTWIDTH, m_lDefKeyShiftWidth);
+ DDV_MinMaxInt (pDX, m_lDefKeyShiftWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFVELSHIFTWIDTH, m_lDefVelShiftWidth);
+ DDV_MinMaxInt (pDX, m_lDefVelShiftWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFTIMESHIFTWIDTH, m_lDefTimeShiftWidth);
+ DDV_MinMaxInt (pDX, m_lDefTimeShiftWidth, 1, 32);
+ DDX_Text (pDX, IDC_TRACKLISTOPTION2_DEFNUMEVENTWIDTH, m_lDefNumEventWidth);
+ DDV_MinMaxInt (pDX, m_lDefNumEventWidth, 1, 32);
+ DDX_Check (pDX, IDC_TRACKLISTOPTION2_ENABLEROWZOOMKEY, m_bEnableRowZoomKey);
+ DDX_Check (pDX, IDC_TRACKLISTOPTION2_ENABLECOLUMNZOOMKEY, m_bEnableColumnZoomKey);
+ DDX_Check (pDX, IDC_TRACKLISTOPTION2_ENABLETIMEZOOMKEY, m_bEnableTimeZoomKey);
+
+}
+
+// ダイアログの初期化
+BOOL CTrackListOption2Page::OnInitDialog () {
+ BOOL bRet = CDialog::OnInitDialog ();
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFCC000WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFCC032WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFPCWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFCC007WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFCC010WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFCC091WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFCC093WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFCC094WIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFKEYSHIFTWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFVELSHIFTWIDTHSP))->SetRange (1, 32);
+ ((CSpinButtonCtrl*)GetDlgItem (IDC_TRACKLISTOPTION2_DEFTIMESHIFTWIDTHSP))->SetRange (1, 32);
+ return bRet;
+}
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+BEGIN_MESSAGE_MAP (CTrackListOption2Page, CPropertyPage)
+END_MESSAGE_MAP ()
+
+
+
diff --git a/src/TrackListOption2Page.h b/src/TrackListOption2Page.h
new file mode 100644
index 0000000..67b281b
--- /dev/null
+++ b/src/TrackListOption2Page.h
@@ -0,0 +1,72 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストオプション2ページクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTOPTION2PAGE_H_
+#define _TRACKLISTOPTION2PAGE_H_
+
+class CTrackListOption2Page : public CPropertyPage {
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+public:
+ long m_lDefCC000Width; // デフォルトのCC#0の幅[pixel]
+ long m_lDefCC032Width; // デフォルトのCC#32の幅[pixel]
+ long m_lDefPCWidth; // デフォルトのプログラムナンバーの幅[pixel]
+ long m_lDefCC007Width; // デフォルトのボリュームの幅[pixel]
+ long m_lDefCC010Width; // デフォルトのパンの幅[pixel]
+ long m_lDefCC091Width; // デフォルトのリバーブの幅[pixel]
+ long m_lDefCC093Width; // デフォルトのコーラスの幅[pixel]
+ long m_lDefCC094Width; // デフォルトのディレイの幅[pixel]
+ long m_lDefKeyShiftWidth; // デフォルトのキーシフトの幅[pixel]
+ long m_lDefVelShiftWidth; // デフォルトのベロシティシフトの幅[pixel]
+ long m_lDefTimeShiftWidth; // デフォルトのタイムシフトの幅[pixel]
+ long m_lDefNumEventWidth; // デフォルトのイベント数の幅[pixel]
+ // ※実際の列の幅[pixel]は、各列の幅に列方向拡大倍率をかけた値となる。
+ BOOL m_bEnableRowZoomKey; // 行方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bEnableColumnZoomKey; // 列方向ズームのショートカットキーCtrl+'+''-'を有効にする
+ BOOL m_bEnableTimeZoomKey; // 時間方向ズームのショートカットキーCtrl+'+''-'を有効にする
+
+public:
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+ CTrackListOption2Page (); // コンストラクタ
+ enum {IDD = IDD_TRACKLISTOPTION2};
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoDataExchange (CDataExchange* pDX); // DDX/DDV のサポート
+ virtual BOOL OnInitDialog ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ //afx_msg void OnChangeEnableAutoSave ();
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/TrackListPrintView.cpp b/src/TrackListPrintView.cpp
new file mode 100644
index 0000000..dde2cf5
--- /dev/null
+++ b/src/TrackListPrintView.cpp
@@ -0,0 +1,1259 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリスト印刷ビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include <afxpriv.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "common.h"
+#include "mousewheel.h"
+#include "ColorfulComboBox.h"
+#include "ColorfulCheckListBox.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolBar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "TrackListPrintView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define TRACKLISTPRINTVIEW_SCALEHEIGHT 80
+#define TRACKLISTPRINTVIEW_SCALEWIDTH 100
+#define TRACKLISTPRINTVIEW_LEFTMARGIN 200
+#define TRACKLISTPRINTVIEW_RIGHTMARGIN 200
+#define TRACKLISTPRINTVIEW_TOPMARGIN 200
+#define TRACKLISTPRINTVIEW_BOTTOMMARGIN 200
+
+IMPLEMENT_DYNCREATE (CTrackListPrintView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CTrackListPrintView, CSekaijuView)
+ ON_COMMAND (ID_FILE_PRINT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
+ ON_COMMAND (ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListPrintView::CTrackListPrintView () {
+ // 印刷用文字フォントの作成(2.5ミリ)
+ CString strDefaultFontName;
+ VERIFY (strDefaultFontName.LoadString (IDS_DEFAULTFONTNAME));
+ m_theFont.CreateFont (25, 0, 0, 0, FW_DONTCARE, 0, 0, 0, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH,
+ strDefaultFontName);
+
+}
+
+// デストラクタ
+CTrackListPrintView::~CTrackListPrintView () {
+ m_theFont.DeleteObject ();
+}
+
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// セルの文字列を取得する
+CString CTrackListPrintView::GetCellString (long lRow, long lColumn) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ ASSERT (0 <= lRow && lRow < MAXMIDITRACKNUM);
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ MIDIEvent* pMIDIEvent = NULL;
+ CString strText;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lValue = 0;
+ long lNumber = 0;
+ MIDIIn* pMIDIIn = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ CString strNone;
+ TCHAR szBuf1[2048];
+ TCHAR szBuf2[2048];
+ VERIFY (strNone.LoadString (IDS_NONE));
+ if (pMIDITrack) {
+ long lColumnContent = pTrackListFrame->GetColumnContent (lColumn);
+ switch (lColumnContent & 0xFFFF) {
+ // トラック名(20120107修正)
+ case TRACKLISTFRAME_TRACKNAME:
+ MIDITrack_GetName (pMIDITrack, szBuf1, TSIZEOF (szBuf1) - 1);
+ codestr2str (szBuf1, TCSLEN (szBuf1), szBuf2, TSIZEOF (szBuf2) - 1);
+ strText = szBuf2;
+ break;
+ // 可視(未使用)
+ case TRACKLISTFRAME_VISIBLE:
+ if (pSekaijuDoc->GetTrackVisible (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_SHOW));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_HIDE));
+ }
+ break;
+ // イネーブル(未使用)
+ case TRACKLISTFRAME_ENABLE:
+ if (pSekaijuDoc->GetTrackEnable (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_ENABLE));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_LOCK));
+ }
+ break;
+ // 入力ON
+ case TRACKLISTFRAME_INPUTON:
+ if (MIDITrack_GetInputOn (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_ON));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_OFF));
+ }
+ break;
+ // 出力ON
+ case TRACKLISTFRAME_OUTPUTON:
+ if (MIDITrack_GetOutputOn (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_ON));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_OFF));
+ }
+ break;
+ // 入力ポート番号
+ case TRACKLISTFRAME_INPUTPORT:
+ lValue = MIDITrack_GetInputPort (pMIDITrack);
+ ASSERT (0 <= lValue && lValue < MAXMIDIINDEVICENUM);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pMIDIIn = pSekaijuApp->m_pMIDIIn[lValue];
+ if (pMIDIIn) {
+ strText.Format (_T("%3d-%s"), lValue + 1, pMIDIIn->m_pDeviceName);
+ }
+ else {
+ strText.Format (_T("%3d-%s"), lValue + 1, strNone);
+ }
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ break;
+ // 入力チャンネル
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ lValue = MIDITrack_GetInputChannel (pMIDITrack);
+ if (0 <= lValue && lValue <= 15) {
+ strText.Format (_T("%3d"), lValue + 1);
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_N_A));
+ }
+ break;
+ // 出力ポート番号
+ case TRACKLISTFRAME_OUTPUTPORT:
+ lValue = MIDITrack_GetOutputPort (pMIDITrack);
+ ASSERT (0 <= lValue && lValue < MAXMIDIOUTDEVICENUM);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[lValue];
+ if (pMIDIOut) {
+ strText.Format (_T("%3d-%s"), lValue + 1, pMIDIOut->m_pDeviceName);
+ }
+ else {
+ strText.Format (_T("%3d-%s"), lValue + 1, strNone);
+ }
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ break;
+ // 出力チャンネル
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ lValue = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lValue && lValue <= 15) {
+ strText.Format (_T("%3d"), lValue + 1);
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_N_A));
+ }
+ break;
+ // 表示モード(通常/ドラム)
+ case TRACKLISTFRAME_VIEWMODE:
+ if (MIDITrack_GetViewMode (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_DRUM));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_NORM));
+ }
+ break;
+ // コントロールチェンジ
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ lValue = -1;
+ lNumber = pTrackListFrame->GetColumnContent (lColumn) >> 16;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == lNumber) {
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ break;
+ }
+ }
+ }
+ if (0 <= lValue && lValue <= 127) {
+ strText.Format (_T("%3d"), lValue);
+ }
+ else {
+ strText = _T("---");
+ }
+ break;
+ // プログラムチェンジ
+ case TRACKLISTFRAME_PROGRAMCHANGE:
+ lValue = -1;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ lValue = MIDIEvent_GetNumber (pMIDIEvent);
+ break;
+ }
+ }
+ if (0 <= lValue && lValue <= 127 && pMIDIEvent) {
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ ASSERT (0 <= lTrackOutputPort && lTrackOutputPort < 16);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ ASSERT (-1 <= lTrackOutputChannel && lTrackOutputChannel < 16);
+ if (lTrackOutputChannel == -1) {
+ lTrackOutputChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ }
+ ASSERT (0 <= lTrackOutputChannel && lTrackOutputChannel < 16);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ long lBankMSB = MIDIEvent_GetBankMSB (pMIDIEvent);
+ long lBankLSB = MIDIEvent_GetBankLSB (pMIDIEvent);
+ long lBank = (lBankMSB << 7) | lBankLSB; //MIDIEvent_GetBank (pMIDIEvent);
+ MIDIInstrumentDefinition* pInstDef = NULL;
+ // このトラックの表示モードが「通常」の場合
+ if (lTrackViewMode == 0) {
+ pInstDef = pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ }
+ // このトラックの表示モードが「ドラム」の場合
+ else {
+ pInstDef = pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort];
+ }
+ // このトラックのインストゥルメント定義が見つかった
+ if (pInstDef) {
+ MIDIPatchNameTable* pPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pInstDef, lBank);
+ // このインストゥルメント定義の指定バンクのPatchNameTableが見つかった
+ if (pPatchNameTable) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, 256);
+ MIDIPatchNameTable_GetName
+ (pPatchNameTable, lValue, szBuf, 255);
+ strText.Format (_T("%d-%s"), lValue, szBuf);
+ }
+ else {
+ strText.Format (_T("%d"), lValue);
+ }
+ }
+ else {
+ strText.Format (_T("%d"), lValue);
+ }
+ }
+ else {
+ strText = _T("---");
+ }
+ break;
+ // タイム+
+ case TRACKLISTFRAME_TIMEPLUS:
+ if (lFormat == 1 && lRow == 0) {
+ strText.Format (_T("---"));
+ }
+ else {
+ lValue = MIDITrack_GetTimePlus (pMIDITrack);
+ strText.Format (_T("%3d"), lValue);
+ }
+ break;
+ // キー+
+ case TRACKLISTFRAME_KEYPLUS:
+ if (lFormat == 1 && lRow == 0) {
+ strText.Format (_T("---"));
+ }
+ else {
+ lValue = MIDITrack_GetKeyPlus (pMIDITrack);
+ strText.Format (_T("%3d"), lValue);
+ }
+ break;
+ // ベロシティ+
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ if (lFormat == 1 && lRow == 0) {
+ strText.Format (_T("---"));
+ }
+ else {
+ lValue = MIDITrack_GetVelocityPlus (pMIDITrack);
+ strText.Format (_T("%3d"), lValue);
+ }
+ break;
+ // イベント数
+ case TRACKLISTFRAME_NUMEVENT:
+ lValue = MIDITrack_CountEvent (pMIDITrack);
+ strText.Format (_T("%8d"), lValue);
+ break;
+ }
+ }
+ return strText;
+}
+
+// 時刻[tick]をx座標[*1/10mm]に変換する
+long CTrackListPrintView::TimetoX (long lTime) {
+ // 4分音符を2mmとする。
+ long lTimeResolution = MIDIData_GetTimeResolution (GetDocument ()->m_pMIDIData);
+ return lTime * 20 / lTimeResolution;
+}
+
+
+
+// トラック番号部描画
+void CTrackListPrintView::DrawIndexScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+
+ long lRowZoom = 80;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lRowCount = m_lNumTrackPerPage * m_lMaxRowPage;
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long lCurRowPage = lCurPage % m_lMaxRowPage;
+ long lCurColPage = lCurPage / m_lMaxRowPage;
+ long i;
+ long iMin = m_lNumTrackPerPage * lCurRowPage;
+ long iMax = m_lNumTrackPerPage * (lCurRowPage + 1);
+ for (i = iMin; i < iMax; i++) {
+ long x1 = 0;
+ long x2 = TRACKLISTPRINTVIEW_SCALEWIDTH;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lColorBtnFace);
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ CString strText;
+ strText.Format (_T("%d"), pSekaijuApp->m_theGeneralOption.m_bEventZeroOrigin ? i : i + 1);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 左上描画
+void CTrackListPrintView::DrawScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ // 左上余白部描画
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (0, 0, TRACKLISTPRINTVIEW_SCALEWIDTH, TRACKLISTPRINTVIEW_SCALEHEIGHT, lColorBtnFace);
+}
+
+// リスト部描画
+void CTrackListPrintView::DrawIndexPropertyView (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+
+ long lRowZoom = 80;
+ long lLeftMargin = TRACKLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = TRACKLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = TRACKLISTPRINTVIEW_SCALEWIDTH;
+
+ long i, j;
+ // 行の背景色描画
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lRowCount = m_lNumTrackPerPage * m_lMaxRowPage;
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long lCurRowPage = lCurPage % m_lMaxRowPage;
+ long lCurColPage = lCurPage / m_lMaxRowPage;
+ long iMin = m_lNumTrackPerPage * lCurRowPage;
+ long iMax = m_lNumTrackPerPage * (lCurRowPage + 1);
+ for (i = iMin; i < iMax; i++) {
+ long x1 = 0;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * 2;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ long lBackColor = pSekaijuApp->m_theColorOption.m_lBackColor [i % 2];
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lBackColor);
+ }
+
+ // 横線の描画
+ CPen penTrack (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor [0]);
+ CPen* pOldPen = pDC->SelectObject (&penTrack);
+ for (i = iMin; i <= iMax; i++) {
+ long x1 = 0;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * 2;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ pDC->MoveTo (x1, y1 + 1);
+ pDC->LineTo (x2, y1 + 1);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // 縦線の描画
+ CPen penColumn (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor [0]);
+ pOldPen = pDC->SelectObject (&penColumn);
+ long lWidthDiv[] = {0, 7, 8, 10, 16, 18, 20, 26, 28, 32, 34, 36, 44, 46, 48, 50, 52, 54, 56, 58, 60, 64};
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ long x1 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j] / 32;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j + 1] / 32;
+ long y1 = 0;
+ long y2 = lRowZoom * lRowCount;
+ pDC->MoveTo (x1 - 1, y1);
+ pDC->LineTo (x1 - 1, y2);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // 各セルの文字などの描画
+ pDC->SetBkMode (TRANSPARENT);
+ for (i = iMin; i < iMax; i++) {
+ if (i < lTrackCount) {
+ pMIDITrack = pSekaijuDoc->GetTrack (i);
+ }
+ else {
+ pMIDITrack = NULL;
+ }
+ if (pMIDITrack) {
+ long lTrackForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ pDC->SetTextColor (lTrackForeColor);
+ // 各列について
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ long x1 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j] / 32;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j + 1] / 32;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ CRect rcCell (x1, y1, x2, y2);
+ CRect rcText = rcCell;
+ long lColumnContent = pTrackListFrame->GetColumnContent (j);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ rcText.right -= 10;
+ }
+ // 各セルの文字描画
+ CString strCellString;
+ CRect rcColor;
+ switch (lColumnContent & 0xFFFF) {
+ case TRACKLISTFRAME_FORECOLOR:
+ rcColor.left = rcCell.left + 10;
+ rcColor.right = rcCell.right - 10;
+ rcColor.top = rcCell.bottom + lRowZoom / 2 - 10;
+ rcColor.bottom = rcCell.bottom + lRowZoom / 2 + 10;
+ pDC->FillSolidRect (&rcColor, lTrackForeColor);
+ break;
+ case TRACKLISTFRAME_TRACKNAME:
+ case TRACKLISTFRAME_VISIBLE:
+ case TRACKLISTFRAME_ENABLE:
+ case TRACKLISTFRAME_INPUTON:
+ case TRACKLISTFRAME_INPUTPORT:
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ case TRACKLISTFRAME_OUTPUTON:
+ case TRACKLISTFRAME_OUTPUTPORT:
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ case TRACKLISTFRAME_VIEWMODE:
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ case TRACKLISTFRAME_PROGRAMCHANGE:
+ case TRACKLISTFRAME_TIMEPLUS:
+ case TRACKLISTFRAME_KEYPLUS:
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ case TRACKLISTFRAME_NUMEVENT:
+ strCellString = GetCellString (i, j);
+ pDC->DrawText (strCellString, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ break;
+ }
+ }
+ }
+ }
+
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 上部項目部描画
+void CTrackListPrintView::DrawPropertyScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ long lLeftMargin = TRACKLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = TRACKLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = TRACKLISTPRINTVIEW_SCALEWIDTH;
+ pDC->SetBkMode (TRANSPARENT);
+ pDC->SetTextColor (RGB (0, 0, 0));
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ long lWidthDiv[] = {0, 7, 8, 10, 16, 18, 20, 26, 28, 32, 34, 36, 44, 46, 48, 50, 52, 54, 56, 58, 60, 64};
+ for (long j = 0; j < 21; j++) {
+ long x1 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j] / 32;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * lWidthDiv[j + 1] / 32;
+ long y1 = 0;
+ long y2 = TRACKLISTPRINTVIEW_SCALEHEIGHT;
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lColorBtnFace);
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ CString strText (pTrackListFrame->GetColumnTitle (j));
+ pDC->DrawText (strText, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ }
+ pDC->SelectObject (pOldFont);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+// トラックプレビュー部描画
+void CTrackListPrintView::DrawTrackTimeView (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ long lEndTime, lEndMeasure, lEndBeat, lEndTick;
+ lEndTime = MIDIData_GetEndTime (pMIDIData);
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+
+ pDC->SetBkMode (TRANSPARENT);
+
+ long lRowZoom = 80;
+ long lLeftMargin = TRACKLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = TRACKLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = TRACKLISTPRINTVIEW_SCALEWIDTH;
+
+ long i, j;
+ // 行の背景色描画
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lRowCount = m_lNumTrackPerPage * m_lMaxRowPage;
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long lCurRowPage = (lCurPage - m_lMaxRowPage * m_lMaxColPage) % m_lMaxRowPage;
+ long lCurRollPage = (lCurPage - m_lMaxRowPage * m_lMaxColPage) / m_lMaxRowPage;
+ long iMin = m_lNumTrackPerPage * lCurRowPage;
+ long iMax = m_lNumTrackPerPage * (lCurRowPage + 1);
+ for (i = iMin; i < iMax; i++) {
+ long x1 = 0;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * m_lMaxRollPage;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ long lBackColor = pSekaijuApp->m_theColorOption.m_lBackColor [i % 2];
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lBackColor);
+ }
+
+ // 横線の描画
+ CPen penTrack (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor [0]);
+ CPen* pOldPen = pDC->SelectObject (&penTrack);
+ for (i = iMin; i <= iMax; i++) {
+ long x1 = 0;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * m_lMaxRollPage;
+ long y1 = lRowZoom * (lRowCount - i);
+ long y2 = y1 - lRowZoom;
+ pDC->MoveTo (x1, y1 + 1);
+ pDC->LineTo (x2, y1 + 1);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // 縦線(小節境界線又はフレーム境界線)の描画
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor [1]);
+ pOldPen = pDC->SelectObject (&penMeasure);
+ for (j = 0; j < lEndMeasure + 120; j++) {
+ long lTime;
+ MIDIData_MakeTime (pMIDIData, j, 0, 0, &lTime);
+ long x = this->TimetoX (lTime);
+ long y1 = 0;
+ long y2 = lRowZoom * lRowCount;
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, y1);
+ pDC->LineTo (x, y2);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // データ部の描画
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (iMin <= i && i < __min (iMax, lTrackCount)) {
+ long lTrackColor = MIDITrack_GetForeColor (pMIDITrack);
+ long y = lRowZoom * (lRowCount - i);
+ CPen theTrackPen (PS_SOLID, 1, lTrackColor);
+ pOldPen = pDC->SelectObject (&theTrackPen);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ // ノートイベントの描画
+ if (MIDIEvent_IsNote (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lKey = MIDIEvent_GetKey (pMIDIEvent);
+ long lDur = MIDIEvent_GetDuration (pMIDIEvent);
+ long x1 = this->TimetoX (lTime);
+ long x2 = this->TimetoX (lTime + lDur) + 1;
+ long y1 = y - lRowZoom + lRowZoom * lKey / 128;
+ long y2 = y1 + 1;
+ //CRect rcNote (x1, y1, x2, y2);
+ //pDC->FillSolidRect (&rcNote, lTrackColor);
+ pDC->MoveTo (x1, y1);
+ pDC->LineTo (x2, y1);
+ }
+ // キーアフタータッチの描画
+ else if (MIDIEvent_IsKeyAftertouch (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = this->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = y - lRowZoom;
+ long y2 = y1 + lRowZoom * (lValue) / 128;
+ //CRect rcNote (x1, y1, x2, y2);
+ //pDC->FillSolidRect (&rcNote, lTrackColor);
+ pDC->MoveTo (x1, y1);
+ pDC->LineTo (x1, y2);
+ if (lValue == 0) {
+ pDC->Ellipse (x1 - 5, y1 - 5, x1 + 5, y1 + 5);
+ }
+ }
+ // コントロールチェンジイベントの描画
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = this->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = y - lRowZoom;
+ long y2 = y1 + lRowZoom * (lValue) / 128;
+ //CRect rcNote (x1, y1, x2, y2);
+ //pDC->FillSolidRect (&rcNote, lTrackColor);
+ pDC->MoveTo (x1, y1);
+ pDC->LineTo (x1, y2);
+ if (lValue == 0) {
+ pDC->Ellipse (x1 - 5, y1 - 5, x1 + 5, y1 + 5);
+ }
+ }
+ // プログラムチェンジイベントの描画
+ else if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = this->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = y - lRowZoom;
+ long y2 = y1 + lRowZoom * (lValue) / 128;
+ //CRect rcNote (x1, y1, x2, y2);
+ //pDC->FillSolidRect (&rcNote, lTrackColor);
+ pDC->MoveTo (x1, y1);
+ pDC->LineTo (x1, y2);
+ if (lValue == 0) {
+ pDC->Ellipse (x1 - 5, y1 - 5, x1 + 5, y1 + 5);
+ }
+ }
+ // チャンネルアフタータッチの描画
+ else if (MIDIEvent_IsChannelAftertouch (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = this->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = y - lRowZoom;
+ long y2 = y1 + lRowZoom * (lValue) / 128;
+ //CRect rcNote (x1, y1, x2, y2);
+ //pDC->FillSolidRect (&rcNote, lTrackColor);
+ pDC->MoveTo (x1, y1);
+ pDC->LineTo (x1, y2);
+ if (lValue == 0) {
+ pDC->Ellipse (x1 - 5, y1 - 5, x1 + 5, y1 + 5);
+ }
+ }
+ // ピッチベンドの描画
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = this->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = y - lRowZoom / 2;
+ long y2 = y1 + lRowZoom * (lValue - 8192) / 16384;
+ //CRect rcNote (x1, y1, x2, y2);
+ //pDC->FillSolidRect (&rcNote, lTrackColor);
+ pDC->MoveTo (x1, y1);
+ pDC->LineTo (x1, y2);
+ if (lValue == 8192) {
+ pDC->Ellipse (x1 - 5, y1 - 5, x1 + 5, y1 + 5);
+ }
+ }
+ }
+ pDC->SelectObject (pOldPen);
+ }
+ i++;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+//
+void CTrackListPrintView::DrawFlagAndText (CDC* pDC, long lTime, LPCTSTR lpszText, long lColor) {
+ long lScaleHeight = TRACKLISTPRINTVIEW_SCALEHEIGHT;
+ long x = this->TimetoX (lTime);
+ CRect rcBack (x, lScaleHeight, x + 1024, lScaleHeight / 2);
+ CRect rcFlag (x, lScaleHeight - 10, x + 16, lScaleHeight / 2 + 10);
+ CRect rcText (x + 20, lScaleHeight, x + 1024, lScaleHeight / 2);
+ CPen pen;
+ pen.CreatePen (PS_SOLID, 1, lColor);
+ CPen* pOldPen = pDC->SelectObject (&pen);
+ pDC->FillSolidRect (&rcBack, ::GetSysColor (COLOR_BTNFACE));
+ pDC->FillSolidRect (&rcFlag, lColor);
+ pDC->MoveTo (x, lScaleHeight - 10);
+ pDC->LineTo (x, lScaleHeight / 2);
+ pDC->SetBkMode (TRANSPARENT);
+ pDC->SetTextColor (lColor);
+ pDC->DrawText (lpszText, rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ pDC->SelectObject (pOldPen);
+}
+
+// 上部時刻目盛り部描画
+void CTrackListPrintView::DrawTimeScaleView (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+
+ long lEndTime, lEndMeasure, lEndBeat, lEndTick;
+ lEndTime = MIDIData_GetEndTime (pMIDIData);
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ long lLeftMargin = TRACKLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = TRACKLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = TRACKLISTPRINTVIEW_SCALEWIDTH;
+
+ long j;
+
+ pDC->SetBkMode (TRANSPARENT);
+ pDC->SetTextColor (RGB (0, 0, 0));
+
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+
+ // エリア全体塗りつぶし
+ long x1 = 0;
+ long x2 = (m_sizLogPaper.cx - lLeftMargin - lRightMargin - lScaleWidth) * m_lMaxRollPage;
+ long y1 = 0;
+ long y2 = TRACKLISTPRINTVIEW_SCALEHEIGHT;
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lColorBtnFace);
+
+ // 上段に拍子記号・調性記号・マーカーの描画
+ long lTime = 0;
+ long lOldTime = 0;
+ CString strText1;
+ CString strText2;
+ pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ if (pMIDITrack) {
+ long lColorTrack1 = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (0 <= lTime && lTime <= lEndTime) {
+ // テンポ
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo;
+ lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ strText1.Format (_T("%1.2lf"), (double)60000000 / (double)lTempo);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 拍子記号
+ else if (MIDIEvent_IsTimeSignature (pMIDIEvent)) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ strText1.Format (_T("%d/%d"), lnn, 1 << ldd);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 調性記号
+ else if (MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ strText1.Format (_T("%d%s"), labs (lsf), lsf >= 0 ? _T("#") : _T("b"));
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // マーカー
+ else if (MIDIEvent_IsMarker (pMIDIEvent)) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIEvent_GetText (pMIDIEvent, szBuf, sizeof (szBuf) - 1);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += szBuf;
+ lOldTime = lTime;
+ }
+ }
+ }
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ }
+
+ // 下段に小節ボタン描画
+ pDC->SetTextColor (RGB (0, 0, 0));
+ for (j = 0; j <= lEndMeasure + 120; j++) {
+ long lTime1 = 0;
+ long lTime2 = 0;
+ MIDIData_MakeTime (pMIDIData, j, 0, 0, &lTime1);
+ MIDIData_MakeTime (pMIDIData, j + 1, 0, 0, &lTime2);
+ long x1 = this->TimetoX (lTime1);
+ long x2 = this->TimetoX (lTime2);
+ long y1 = 0;
+ long y2 = TRACKLISTPRINTVIEW_SCALEHEIGHT / 2;
+ pDC->FillSolidRect (CRect (x1, y1, x2, y2), lColorBtnFace);
+ pDC->FillSolidRect (CRect (x1, y2 - 1, x2, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x1 + 1, y2), lColorBtnHighlight);
+ pDC->FillSolidRect (CRect (x1, y1, x2, y1 + 1), lColorBtnShadow);
+ pDC->FillSolidRect (CRect (x2 - 1, y1, x2, y2), lColorBtnShadow);
+ CRect rcText (x1, y1, x2, y2);
+ CString strText;
+ strText.Format (_T("%d"), j + 1);
+ pDC->DrawText (strText, &rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+ }
+
+ pDC->SelectObject (pOldFont);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+
+
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 印刷時
+void CTrackListPrintView::OnPrint (CDC* pDC, CPrintInfo* pInfo) {
+
+ pDC->SetMapMode (MM_LOMETRIC);
+ CPoint ptWindowOrg (0, 0);
+
+ long lLeftMargin = TRACKLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = TRACKLISTPRINTVIEW_RIGHTMARGIN;
+ long lTopMargin = TRACKLISTPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = TRACKLISTPRINTVIEW_BOTTOMMARGIN;
+ long lScaleHeight = TRACKLISTPRINTVIEW_SCALEHEIGHT;
+ long lScaleWidth = TRACKLISTPRINTVIEW_SCALEWIDTH;
+ long lListHeight = (m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin) / 80 * 80;
+ long lListWidth = (m_sizLogPaper.cx - lScaleWidth- lLeftMargin - lRightMargin);
+
+ long lCurPage = pInfo->m_nCurPage - 1;
+ long lCurRowPage = 0;
+ long lCurColPage = 0;
+ long lCurRollPage = 0;
+ if (lCurPage < m_lMaxColPage * m_lMaxRowPage) {
+ lCurRowPage = lCurPage % m_lMaxRowPage;
+ lCurColPage = lCurPage / m_lMaxRowPage;
+ }
+ else {
+ lCurRowPage = (lCurPage - m_lMaxColPage * m_lMaxRowPage) % m_lMaxRowPage;
+ lCurRollPage = (lCurPage - m_lMaxColPage * m_lMaxRowPage) / m_lMaxRowPage;
+ }
+
+ CRgn theRgn;
+ CRect rcClip;
+
+ // トラック番号部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lListHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin + lListHeight * (m_lMaxRowPage - lCurRowPage - 1);
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawIndexScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 左上余白部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin;
+ rcClip.right = lLeftMargin + lScaleWidth;
+ rcClip.top = lBottomMargin + lListHeight;
+ rcClip.bottom = lBottomMargin + lListHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lListHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ if (lCurPage < m_lMaxColPage * m_lMaxRowPage) {
+
+ // トラックリスト部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lListWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lListHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lListWidth * lCurColPage;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin + lListHeight * (m_lMaxRowPage - lCurRowPage - 1);
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawIndexPropertyView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+
+ // 上部リスト項目名部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lListWidth;
+ rcClip.top = lBottomMargin + lListHeight;
+ rcClip.bottom = lBottomMargin + lListHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lListWidth * lCurColPage;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lListHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawPropertyScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+ }
+
+ else {
+
+ // トラックプレビュー部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lListWidth;
+ rcClip.top = lBottomMargin;
+ rcClip.bottom = lBottomMargin + lListHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lListWidth * lCurRollPage;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin + lListHeight * (m_lMaxRowPage - lCurRowPage - 1);
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawTrackTimeView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+
+ // 上部時刻目盛り部
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ rcClip.left = lLeftMargin + lScaleWidth;
+ rcClip.right = lLeftMargin + lScaleWidth + lListWidth;
+ rcClip.top = lBottomMargin + lListHeight;
+ rcClip.bottom = lBottomMargin + lListHeight + lScaleHeight;
+ if (pDC->IsKindOf (RUNTIME_CLASS (CPreviewDC))) {
+ CPreviewDC* pPreviewDC = (CPreviewDC*)pDC;
+ pPreviewDC->LPtoDP (&rcClip.TopLeft ());
+ pPreviewDC->LPtoDP (&rcClip.BottomRight ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.TopLeft ());
+ pPreviewDC->PrinterDPtoScreenDP (&rcClip.BottomRight ());
+ CPoint ptOrg;
+ ::GetViewportOrgEx (pDC->m_hDC, &ptOrg);
+ rcClip += ptOrg;
+ }
+ else {
+ pDC->LPtoDP (&rcClip.TopLeft ());
+ pDC->LPtoDP (&rcClip.BottomRight ());
+ }
+ theRgn.CreateRectRgnIndirect (rcClip);
+ pDC->SelectClipRgn (&theRgn);
+ ptWindowOrg.x = -lLeftMargin - lScaleWidth + lListWidth * lCurRollPage;
+ ptWindowOrg.y = m_sizLogPaper.cy - lBottomMargin - lListHeight;
+ pDC->SetWindowOrg (ptWindowOrg);
+ DrawTimeScaleView (pDC, pInfo);
+ pDC->SelectClipRgn (NULL);
+ theRgn.DeleteObject ();
+ }
+
+ // ヘッダー(タイトル)
+ ptWindowOrg.x = 0;
+ ptWindowOrg.y = m_sizLogPaper.cy;
+ pDC->SetWindowOrg (ptWindowOrg);
+ pDC->SetTextColor (RGB (0, 0 ,0));
+ CRect rcText;
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = m_sizLogPaper.cy - lTopMargin;
+ rcText.bottom = m_sizLogPaper.cy - lTopMargin / 2;
+ TCHAR szText[256];
+ memset (szText, 0, sizeof (szText));
+ MIDIData_GetTitle (GetDocument()->m_pMIDIData, szText, sizeof (szText));
+ CString strText;
+ if (TCSLEN (szText) == 0) {
+ strText = GetDocument()->GetTitle ();
+ }
+ else {
+ strText.Format (_T("%s"), szText);
+ }
+ CFont* pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+ // フッター(ページ数/全ページ数)
+ rcText.left = lLeftMargin;
+ rcText.right = m_sizLogPaper.cx - lRightMargin;
+ rcText.top = lTopMargin / 2;
+ rcText.bottom = lTopMargin;
+ strText.Format (_T("%d/%d"), pInfo->m_nCurPage, pInfo->GetMaxPage ());
+ pOldFont = pDC->SelectObject (&m_theFont);
+ pDC->DrawText (strText, rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ pDC->SelectObject (pOldFont);
+
+}
+
+// 印刷準備時
+BOOL CTrackListPrintView::OnPreparePrinting (CPrintInfo* pInfo) {
+ // デフォルトの印刷準備
+ return DoPreparePrinting (pInfo);
+}
+
+// 印刷開始時
+void CTrackListPrintView::OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ // 紙サイズの取得
+ m_sizDevPaper.cx = pDC->GetDeviceCaps (HORZRES); // [pixel]
+ m_sizDevPaper.cy = pDC->GetDeviceCaps (VERTRES); // [pixel]
+ m_sizLogPaper.cx = pDC->GetDeviceCaps (HORZSIZE) * 10; // [*0.1mm]
+ m_sizLogPaper.cy = pDC->GetDeviceCaps (VERTSIZE) * 10; // [*0.1mm]
+ m_sizLogPrinterDPI.cx = pDC->GetDeviceCaps (LOGPIXELSX); // [dpi]
+ m_sizLogPrinterDPI.cy = pDC->GetDeviceCaps (LOGPIXELSY); // [dpi]
+
+ // リスト全体の高さとページ数を計算
+ long lRowZoom = 80;
+ long lScaleHeight = TRACKLISTPRINTVIEW_SCALEHEIGHT;
+ long lTopMargin = TRACKLISTPRINTVIEW_TOPMARGIN;
+ long lBottomMargin = TRACKLISTPRINTVIEW_BOTTOMMARGIN;
+ long lNumTrack = MIDIData_CountTrack (pMIDIData);
+ m_lNumTrackPerPage = MAX ((m_sizLogPaper.cy - lScaleHeight - lTopMargin - lBottomMargin) / lRowZoom, 1);
+ m_lMaxRowPage = lNumTrack / MAX (m_lNumTrackPerPage, 1) + 1;
+ m_lMaxColPage = 2;
+
+ // ロール部の幅とページ数を計算
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ long lEndMeasure, lEndBeat, lEndTick;
+ MIDIData_BreakTime (pMIDIData, lEndTime, &lEndMeasure, &lEndBeat, &lEndTick);
+ long lLastTime = 0;
+ MIDIData_MakeTime (pMIDIData, lEndMeasure + 1, 0, 0, &lLastTime);
+ long lRollWidth = this->TimetoX (lLastTime);
+ long lLeftMargin = TRACKLISTPRINTVIEW_LEFTMARGIN;
+ long lRightMargin = TRACKLISTPRINTVIEW_RIGHTMARGIN;
+ long lScaleWidth = TRACKLISTPRINTVIEW_SCALEWIDTH;
+ long lTimeWidth = m_sizLogPaper.cx - lScaleWidth - lLeftMargin - lRightMargin;
+ m_lMaxRollPage = lRollWidth / MAX (lTimeWidth, 1) + 1;
+
+ // 印刷ページ数の設定
+ m_lMaxPage = m_lMaxRowPage * (m_lMaxColPage + m_lMaxRollPage);
+ pInfo->SetMaxPage (m_lMaxPage);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+}
+
+// 印刷終了時
+void CTrackListPrintView::OnEndPrinting (CDC* pDC, CPrintInfo* pInfo) {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
diff --git a/src/TrackListPrintView.h b/src/TrackListPrintView.h
new file mode 100644
index 0000000..acda43e
--- /dev/null
+++ b/src/TrackListPrintView.h
@@ -0,0 +1,80 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリスト印刷ビュークラス
+// (C)2002-2011 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTPRINTVIEW_H_
+#define _TRACKLISTPRINTVIEW_H_
+
+class CTrackListPrintView : public CSekaijuView {
+
+public:
+ DECLARE_DYNCREATE (CTrackListPrintView)
+
+ // CTrackListFrameからCTrackListPrintView::OnCmdMsgの呼び出しを許可する。
+ friend class CTrackListFrame;
+
+ // 印刷関係
+ CSize m_sizDevPaper; // 物理紙サイズ[ドット]
+ CSize m_sizLogPaper; // 論理紙サイズ[*1/10mm]
+ CSize m_sizLogPrinterDPI; // プリンタのDPI
+ CFont m_theFont; // 印刷用フォント
+ long m_lNumTrackPerPage; // 1ページあたりのトラック数
+ long m_lMaxRowPage; // 最大ページ数(縦方向)
+ long m_lMaxColPage; // 最大ページ数(横方向)
+ long m_lMaxRollPage; // 最大ページ数(ピアノロール方向)
+ long m_lMaxPage; // 最大ページ数(縦方向*(横方向+ピアノロール方向))
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListPrintView(); // コンストラクタ
+ virtual ~CTrackListPrintView (); // デストラクタ
+
+ //------------------------------------------------------------------------------
+ // オペレーション
+ //------------------------------------------------------------------------------
+protected:
+ CString GetCellString (long lRow, long lColumn);
+ long TimetoX (long lTime);
+ void DrawIndexScaleView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawScaleView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawIndexPropertyView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawPropertyScaleView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawTrackTimeView (CDC* pDC, CPrintInfo* pInfo);
+ void DrawFlagAndText (CDC* pDC, long lTime, LPCTSTR lpszText, long lColor);
+ void DrawTimeScaleView (CDC* pDC, CPrintInfo* pInfo);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrint (CDC* pDC, CPrintInfo* pInfo);
+ virtual BOOL OnPreparePrinting (CPrintInfo* pInfo);
+ virtual void OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting (CDC* pDC, CPrintInfo* pInfo);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/TrackListScaleView.cpp b/src/TrackListScaleView.cpp
new file mode 100644
index 0000000..4fa64c5
--- /dev/null
+++ b/src/TrackListScaleView.cpp
@@ -0,0 +1,146 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolbar.h"
+#include "SekaijuStatusBar.h"
+#include "MainFrame.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "TrackListScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CTrackListScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CTrackListScaleView, CSekaijuView)
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListScaleView::CTrackListScaleView () {
+}
+
+// デストラクタ
+CTrackListScaleView::~CTrackListScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 描画
+void CTrackListScaleView::OnDraw (CDC* pDC) {
+ CSekaijuDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ pDC->FillSolidRect (&rcClient, lColorBtnFace);
+
+}
+
+// ビューの更新
+void CTrackListScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ // 演奏開始した場合、リアルタイム入力開始した場合、位置移動した場合
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ if (pSekaijuApp->m_theGeneralOption.m_bEnableAutoPageUpdate) { // 20091224追加
+ pTrackListFrame->m_bAutoPageUpdate = TRUE;
+ }
+ }
+ // MIDIデータ又はMIDIトラック又はMIDIイベントが変更された場合
+ if ((lHint & SEKAIJUDOC_MIDIDATACHANGED) ||
+ (lHint & SEKAIJUDOC_MIDITRACKCHANGED) ||
+ (lHint & SEKAIJUDOC_MIDIEVENTCHANGED)) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lEndTime = MIDIData_GetEndTime (pMIDIData);
+ pMainFrame->SetPositionScrollRange (0, lEndTime, TRUE);
+ pTrackListFrame->RecalcRowScrollInfo ();
+ pTrackListFrame->RecalcColumnScrollInfo ();
+ pTrackListFrame->RecalcTimeScrollInfo ();
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// キー押し下げ時
+void CTrackListScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ pTrackListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+}
+
+// マウスホイールが回された時
+void CTrackListScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pTrackListFrame->SetRowScrollPos (lRowScrollPos);
+ }
+
+}
diff --git a/src/TrackListScaleView.h b/src/TrackListScaleView.h
new file mode 100644
index 0000000..68dfd6a
--- /dev/null
+++ b/src/TrackListScaleView.h
@@ -0,0 +1,52 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストスケールビュークラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTSCALEVIEW_H_
+#define _TRACKLISTSCALEVIEW_H_
+
+class CTrackListScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CTrackListScaleView)
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListScaleView(); // コンストラクタ
+ virtual ~CTrackListScaleView(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
+
+
diff --git a/src/TrackListTimeScaleView.cpp b/src/TrackListTimeScaleView.cpp
new file mode 100644
index 0000000..c6a00fe
--- /dev/null
+++ b/src/TrackListTimeScaleView.cpp
@@ -0,0 +1,695 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストタイムスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolbar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "TrackListTimeScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CTrackListTimeScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CTrackListTimeScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListTimeScaleView::CTrackListTimeScaleView () {
+}
+
+// デストラクタ
+CTrackListTimeScaleView::~CTrackListTimeScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 指定時刻にフラグとテキストを描画
+void CTrackListTimeScaleView::DrawFlagAndText
+(CDC* pDC, long lTime, LPCTSTR lpszText, long lColor) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ long x = pTrackListFrame->TimetoX (lTime);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ CRect rcBack (x, 0, x + 1024, 16);
+ CRect rcFlag (x, 3, x + 4, 12);
+ CRect rcText (x + 5, 0, x + 1024, 16);
+ CPen pen;
+ pen.CreatePen (PS_SOLID, 1, lColor);
+ CPen* pOldPen = pDC->SelectObject (&pen);
+ pDC->FillSolidRect (&rcBack, ::GetSysColor (COLOR_BTNFACE));
+ pDC->FillSolidRect (&rcFlag, lColor);
+ pDC->MoveTo (x, 3);
+ pDC->LineTo (x, 16);
+ pDC->SetBkMode (TRANSPARENT);
+ pDC->SetTextColor (lColor);
+ pDC->DrawText (lpszText, rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ pDC->SelectObject (pOldPen);
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CTrackListTimeScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ pDC->SetWindowOrg (pTrackListFrame->GetTimeScrollPos (), 0);
+}
+
+// 描画
+void CTrackListTimeScaleView::OnDraw (CDC* pDC) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ //long lTimeMode = MIDIData_GetTimeMode (pMIDIData);
+ //long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ //ong lDeltaMeasure = 1;
+ //switch (lTimeMode) {
+ //case MIDIDATA_SMPTE24BASE:
+ // lDeltaMeasure = 24;
+ // break;
+ //case MIDIDATA_SMPTE25BASE:
+ // lDeltaMeasure = 25;
+ // break;
+ //case MIDIDATA_SMPTE29BASE:
+ //case MIDIDATA_SMPTE30BASE:
+ // lDeltaMeasure = 30;
+ // break;
+ //}
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+ pDC->FillSolidRect (&rcClient, ::GetSysColor (COLOR_3DFACE));
+ CFont* pOldFont = pDC->SelectObject (&(pTrackListFrame->m_theFont));
+ long j;
+ long lVisibleLeftTime = pTrackListFrame->GetVisibleLeftTime ();
+ long lVisibleRightTime = pTrackListFrame->GetVisibleRightTime ();
+ long lVisibleTopRow = pTrackListFrame->GetVisibleTopRow ();
+ long lVisibleBottomRow = pTrackListFrame->GetVisibleBottomRow ();
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ TCHAR szBuf[256];
+
+ // 上段に拍子記号・調性記号・マーカーの描画
+ long lTime = 0;
+ long lOldTime = 0;
+ CString strText1;
+ CString strText2;
+ pMIDITrack = MIDIData_GetFirstTrack (pMIDIData);
+ if (pMIDITrack) {
+ long lColorTrack1 = MIDITrack_GetForeColor (pMIDITrack);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ lTime = MIDIEvent_GetTime (pMIDIEvent);
+ if (0 <= lTime && lTime <= lVisibleRightTime) {
+ // テンポ
+ if (MIDIEvent_IsTempo (pMIDIEvent)) {
+ long lTempo;
+ lTempo = MIDIEvent_GetTempo (pMIDIEvent);
+ strText1.Format (_T("%1.2lf"), (double)60000000 / (double)lTempo);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 拍子記号
+ else if (MIDIEvent_IsTimeSignature (pMIDIEvent)) {
+ long lnn, ldd, lcc, lbb;
+ MIDIEvent_GetTimeSignature (pMIDIEvent, &lnn, &ldd, &lcc, &lbb);
+ strText1.Format (_T("%d/%d"), lnn, 1 << ldd);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // 調性記号
+ else if (MIDIEvent_IsKeySignature (pMIDIEvent)) {
+ long lsf, lmi;
+ MIDIEvent_GetKeySignature (pMIDIEvent, &lsf, &lmi);
+ strText1.Format (_T("%d%s"), labs (lsf), lsf >= 0 ? _T("#") : _T("b"));
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += strText1;
+ lOldTime = lTime;
+ }
+ // マーカー
+ else if (MIDIEvent_IsMarker (pMIDIEvent)) {
+ memset (szBuf, 0, sizeof (szBuf));
+ MIDIEvent_GetText (pMIDIEvent, szBuf, TSIZEOF (szBuf) - 1);
+ if (lOldTime != lTime) {
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ strText2 = _T("");
+ }
+ if (strText2 != _T("")) {
+ strText2 += _T(", ");
+ }
+ strText2 += szBuf;
+ lOldTime = lTime;
+ }
+ }
+ }
+ if (strText2 != _T("")) {
+ DrawFlagAndText (pDC, lOldTime, strText2, lColorTrack1);
+ }
+ }
+
+ // 下段に小節ボタン描画
+
+ // 小節境界又はフレーム境界を配列に列挙
+ long lLeftMeasure, lLeftBeat, lLeftTick;
+ long lRightMeasure, lRightBeat, lRightTick;
+ MIDIData_BreakTime (pMIDIData, lVisibleLeftTime, &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_BreakTime (pMIDIData, lVisibleRightTime, &lRightMeasure, &lRightBeat, &lRightTick);
+ //if (lTimeMode != MIDIDATA_TPQNBASE) {
+ // lLeftMeasure = (lLeftMeasure / lDeltaMeasure) * lDeltaMeasure;
+ // lRightMeasure = (lRightMeasure / lDeltaMeasure) * lDeltaMeasure;
+ //}
+ long* pBorderTime = (long*)calloc (lRightMeasure - lLeftMeasure + 2, sizeof (long));
+ for (j = lLeftMeasure; j <= lRightMeasure + 1; j++) {
+ long lTime = 0;
+ MIDIData_MakeTime (pMIDIData, j, 0, 0, &lTime);
+ *(pBorderTime + j - lLeftMeasure) = lTime;
+ }
+
+ // 各小節ボタンの描画
+ pDC->SetBkMode (TRANSPARENT);
+ for (j = lLeftMeasure; j < lRightMeasure + 1; j += 1) {
+ long lTime0 = *(pBorderTime + j - lLeftMeasure);
+ long lTime1 = *(pBorderTime + j - lLeftMeasure + 1);
+ long x0 = pTrackListFrame->TimetoX (lTime0);
+ long x1 = pTrackListFrame->TimetoX (lTime1);
+ CRect theRect (x0, 16, x1, 32);
+ long lOffset = (j - lLeftMeasure);
+ BOOL bMeasureSelected = FALSE;
+ long lMeasureCount = 0;
+ long lSelectedMeasureCount = 0;
+ long lHalfSelectedMeasureCount = 0;
+ long lNothingMeasureCount = 0;
+ long lUnSelectedMeasureCount = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ lMeasureCount++;
+ long lRet = pSekaijuDoc->IsTrackMeasureSelected (pMIDITrack, j);
+ switch (lRet) {
+ case 0:
+ lNothingMeasureCount++;
+ break;
+ case 1:
+ lUnSelectedMeasureCount++;
+ break;
+ case 2:
+ lHalfSelectedMeasureCount++;
+ break;
+ case 3:
+ lSelectedMeasureCount++;
+ break;
+ }
+ }
+ if (lNothingMeasureCount == lMeasureCount) {
+ bMeasureSelected = FALSE;
+ }
+ else if (lSelectedMeasureCount > 0 && lUnSelectedMeasureCount == 0) {
+ bMeasureSelected = TRUE;
+ }
+ else {
+ bMeasureSelected = FALSE;
+ }
+ if (GetCapture () == this) {
+ long lMinMeasure = __min (m_lDownMeasure, m_lCurMeasure);
+ long lMaxMeasure = __max (m_lDownMeasure, m_lCurMeasure);
+ if (lMinMeasure <= j && j <= lMaxMeasure) {
+ bMeasureSelected = TRUE;
+ }
+ }
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), j + 1);
+ if (bMeasureSelected) {
+ pDC->FillSolidRect (&theRect, lColorBlack);
+ pDC->Draw3dRect (&theRect, lColorBlack, lColorBtnShadow);
+ pDC->SetTextColor (lColorWhite);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ else {
+ pDC->FillSolidRect (&theRect, lColorBtnFace);
+ pDC->Draw3dRect (&theRect, lColorBtnHighlight, lColorBtnShadow);
+ pDC->SetTextColor (lColorBtnText);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ }
+
+ pDC->SelectObject (pOldFont);
+
+ free (pBorderTime);
+
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+
+
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CTrackListTimeScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// ウィンドウ破棄時
+void CTrackListTimeScaleView::OnDestroy () {
+ CSekaijuView::OnDestroy ();
+
+}
+
+// キー押し下げ時
+void CTrackListTimeScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ switch (nChar) {
+ // Deleteキー
+ case VK_DELETE:
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ break;
+ // デフォルト
+ default:
+ pTrackListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+}
+
+// マウス左ボタン押された時
+void CTrackListTimeScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+ point += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+
+ // 上半分をクリックしたとき(演奏位置移動)
+ if (point.y < rcClient.Height () / 2) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lTime = pTrackListFrame->XtoTime (point.x);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, lTime);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+ // 下半分(小節番号部)をクリックしたとき(小節選択)
+ else {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ long j;
+
+ // 履歴の記録
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+
+ // 該当小節又は該当フレーム内の全イベントの選択
+ //long lOldMeasure, lOldBeat, lOldTick;
+ m_lOldTime = pTrackListFrame->XtoTime (m_ptMouseDown.x);
+ MIDIData_BreakTime (pMIDIData, m_lOldTime, &m_lOldMeasure, &m_lOldBeat, &m_lOldTick);
+ //long lCurMeasure, lCurBeat, lCurTick;
+ m_lDownTime = pTrackListFrame->XtoTime (point.x);
+ MIDIData_BreakTime (pMIDIData, m_lDownTime, &m_lDownMeasure, &m_lDownBeat, &m_lDownTick);
+ //long lCurMeasure, lCurBeat, lCurTick;
+ m_lCurTime = pTrackListFrame->XtoTime (point.x);
+ MIDIData_BreakTime (pMIDIData, m_lCurTime, &m_lCurMeasure, &m_lCurBeat, &m_lCurTick);
+ if (nFlags & MK_SHIFT) {
+ long lMinMeasure = __min (m_lOldMeasure, m_lCurMeasure);
+ long lMaxMeasure = __max (m_lOldMeasure, m_lCurMeasure);
+ forEachTrack (pMIDIData, pMIDITrack) {
+ for (j = lMinMeasure; j <= lMaxMeasure; j++) {
+ pSekaijuDoc->SelectTrackMeasure (pMIDITrack, j, 1, pCurHistoryUnit);
+ }
+ }
+ }
+ else {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ pSekaijuDoc->SelectTrackMeasure (pMIDITrack, m_lCurMeasure, 1, pCurHistoryUnit);
+ }
+ }
+
+
+ SetCapture ();
+ SetTimer (0x21, 55, NULL);
+ pTrackListFrame->m_bAutoPageUpdate = FALSE;
+ Invalidate ();
+
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// マウス右ボタン押された時
+void CTrackListTimeScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+ CSize sizWndOrg (pTrackListFrame->GetTimeScrollPos (), 0);
+ point += sizWndOrg;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ if (point.y > rcClient.bottom / 2) {
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ long lTime = pTrackListFrame->XtoTime (point.x);
+ //long lMeasure, lBeat, lTick;
+ //MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ //MIDIData_MakeTime (pMIDIData, lMeasure, 0, 0, &lTime);
+ pSekaijuDoc->m_lTempTime = lTime;
+ pSekaijuDoc->m_lTempTrackIndex = 0;
+ pSekaijuDoc->m_pTempTrack = pSekaijuDoc->GetTrack (0);
+ pSekaijuDoc->m_pTempEvent = NULL;
+ pSekaijuDoc->m_pTempTempoEvent = NULL;
+ pSekaijuDoc->m_pTempTimeSignatureEvent = NULL;
+ pSekaijuDoc->m_pTempKeySignatureEvent = NULL;
+ pSekaijuDoc->m_pTempMarkerEvent = NULL;
+ MIDIEvent* pTempEvent;
+ forEachEvent (pSekaijuDoc->m_pTempTrack, pTempEvent) {
+ if (MIDIEvent_GetTime (pTempEvent) > lTime) {
+ break;
+ }
+ if (MIDIEvent_IsTempo (pTempEvent)) {
+ pSekaijuDoc->m_pTempTempoEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsTimeSignature (pTempEvent)) {
+ pSekaijuDoc->m_pTempTimeSignatureEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsKeySignature (pTempEvent)) {
+ pSekaijuDoc->m_pTempKeySignatureEvent = pTempEvent;
+ }
+ if (MIDIEvent_IsMarker (pTempEvent)) {
+ pSekaijuDoc->m_pTempMarkerEvent = pTempEvent;
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU00));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pTrackListFrame);
+
+}
+
+// マウス左ボタン離されたとき
+void CTrackListTimeScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+ point += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+
+ if (GetCapture () == this) {
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ ReleaseCapture ();
+ KillTimer (0x21);
+
+ if (m_lDownMeasure != m_lCurMeasure) {
+ long lMinMeasure = __min (m_lDownMeasure, m_lCurMeasure);
+ long lMaxMeasure = __max (m_lDownMeasure, m_lCurMeasure);
+ //if (lDownMeasure <= lOldMeasure && lOldMeasure <= lCurMeasure ||
+ // lDownMeasure >= lOldMeasure && lOldMeasure >= lCurMeasure) {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ long j;
+ for (j = lMinMeasure; j <= lMaxMeasure; j++) {
+ pSekaijuDoc->SelectTrackMeasure (pMIDITrack, j, 1, pCurHistoryUnit);
+ }
+ }
+ }
+
+
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CTrackListTimeScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CTrackListTimeScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+ point += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+
+ // 小節又はフレームの仮選択又は仮選択解除
+ //long lDownMeasure, lDownBeat, lDownTick;
+ m_lDownTime = pTrackListFrame->XtoTime (m_ptMouseDown.x);
+ MIDIData_BreakTime (pMIDIData, m_lDownTime, &m_lDownMeasure, &m_lDownBeat, &m_lDownTick);
+ //long lOldMeasure, lOldBeat, lOldTick;
+ m_lOldTime = pTrackListFrame->XtoTime (m_ptMouseMove.x);
+ MIDIData_BreakTime (pMIDIData, m_lOldTime, &m_lOldMeasure, &m_lOldBeat, &m_lOldTick);
+ //long lCurMeasure, lCurBeat, lCurTick;
+ m_lCurTime = pTrackListFrame->XtoTime (point.x);
+ MIDIData_BreakTime (pMIDIData, m_lCurTime, &m_lCurMeasure, &m_lCurBeat, &m_lCurTick);
+ if (m_lOldMeasure != m_lCurMeasure) {
+ Invalidate (FALSE);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CTrackListTimeScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CTrackListTimeScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CTrackListTimeScaleView::OnTimer (UINT nIDEvent) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetTimeScrollPos (), 0);
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldTimeScrollPos = pTrackListFrame->GetTimeScrollPos ();
+ if (m_ptMouseMove.x < rcClient.left) {
+ pTrackListFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pTrackListFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.x >= rcClient.right) {
+ pTrackListFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pTrackListFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x - lOldTimeScrollPos);
+ WORD wY = (WORD)(m_ptMouseMove.y);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+// マウスホイールが回された時
+void CTrackListTimeScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pTrackListFrame->SetRowScrollPos (lRowScrollPos);
+ }
+}
+
+
+
diff --git a/src/TrackListTimeScaleView.h b/src/TrackListTimeScaleView.h
new file mode 100644
index 0000000..20fe39a
--- /dev/null
+++ b/src/TrackListTimeScaleView.h
@@ -0,0 +1,88 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストタイムスケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTTIMESCALEVIEW_H_
+#define _TRACKLISTTIMESCALEVIEW_H_
+
+class CTrackListTimeScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CTrackListTimeScaleView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListTimeScaleView (); // コンストラクタ
+ virtual ~CTrackListTimeScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lDownMeasure; // マウスが押された位置の小節(0〜)
+ long m_lDownBeat; // マウスが押された位置の拍(0〜)
+ long m_lDownTick; // マウスが押された位置のティック(0〜)
+ long m_lDownTime; // マウスが押された位置のタイム(0〜)[tick]
+ long m_lOldMeasure; // マウスが動かされた前回の位置の小節(0〜)
+ long m_lOldBeat; // マウスが動かされた前回の位置の拍(0〜)
+ long m_lOldTick; // マウスが動かされた前回の位置のティック(0〜)
+ long m_lOldTime; // マウスが動かされた前回の位置のタイム(0〜)[tick]
+ long m_lCurMeasure; // マウスが動かされた現在の位置の小節(0〜)
+ long m_lCurBeat; // マウスが動かされた現在の位置の拍(0〜)
+ long m_lCurTick; // マウスが動かされた現在の位置のティック(0〜)
+ long m_lCurTime; // マウスが動かされた現在の位置のタイム(0〜)[tick]
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual void DrawFlagAndText (CDC* pDC, long lTime, LPCTSTR lpszText, long lColor);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnDestroy ();
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/TrackListTrackModeView.cpp b/src/TrackListTrackModeView.cpp
new file mode 100644
index 0000000..c533d97
--- /dev/null
+++ b/src/TrackListTrackModeView.cpp
@@ -0,0 +1,3368 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストトラックモードビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "common.h"
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolbar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "TrackListTrackModeView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+#define IDC_TEXTBOX 3939
+
+IMPLEMENT_DYNCREATE (CTrackListTrackModeView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CTrackListTrackModeView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KILLFOCUS ()
+ ON_WM_KEYDOWN ()
+ ON_WM_KEYUP ()
+ ON_WM_CHAR ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListTrackModeView::CTrackListTrackModeView () {
+ m_lCurRow = 0;
+ m_lCurColumn = 0;
+ m_lCurButtonState = 0x00;
+ m_lCurButtonInterval = 200;
+ m_bSettingCellString = 0;
+}
+
+// デストラクタ
+CTrackListTrackModeView::~CTrackListTrackModeView () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// (X,Y)座標からセル番号を取得
+BOOL CTrackListTrackModeView::GetCellFromPoint
+(CPoint pt, long* pRow, long* pColumn) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ _ASSERT (pRow);
+ _ASSERT (pColumn);
+ *pRow = pTrackListFrame->YtoRow (pt.y);
+ *pColumn = pTrackListFrame->XtoColumn (pt.x);
+ return TRUE;
+}
+
+// 指定セルがビューからはみ出した場合のオートスクロール処理
+BOOL CTrackListTrackModeView::AutoScrolltoShowCell (long lRow, long lColumn) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ long lNewPos = 0;
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ // 指定セルがビューの左にはみ出した場合の処理
+ if (pTrackListFrame->GetColumnLeft (lColumn) < rcClient.left) {
+ lNewPos = pTrackListFrame->GetColumnLeft (lColumn);
+ pTrackListFrame->SetColumnScrollPos (lNewPos);
+ }
+ // 指定セルがビューの右にはみ出した場合の処理
+ else if (pTrackListFrame->GetColumnLeft (lColumn) +
+ pTrackListFrame->GetColumnWidth (lColumn) > rcClient.right) {
+ lNewPos = pTrackListFrame->GetColumnLeft (lColumn) +
+ pTrackListFrame->GetColumnWidth (lColumn) - rcClient.Width ();
+ pTrackListFrame->SetColumnScrollPos (lNewPos);
+ }
+ // 指定セルがビューの上にはみ出した場合の処理
+ if (lRow * lRowZoom < rcClient.top) {
+ lNewPos = lRow * lRowZoom;
+ pTrackListFrame->SetRowScrollPos (lNewPos);
+ }
+ // 指定セルがビューの下にはみ出した場合の処理
+ else if ((lRow + 1) * lRowZoom > rcClient.bottom) {
+ lNewPos = (lRow + 1) * lRowZoom - rcClient.Height ();
+ pTrackListFrame->SetRowScrollPos (lNewPos);
+ }
+ return TRUE;
+}
+
+// 現在テキストボックスで編集中かどうか返す。
+BOOL CTrackListTrackModeView::IsTextEditing () {
+ return (m_theTextBox.GetStyle () & WS_VISIBLE) ? TRUE : FALSE;
+}
+
+// テキストボックスでの編集を開始する。
+BOOL CTrackListTrackModeView::BeginTextEditing () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ //ASSERT (lFormat == 0 && m_lCurRow == 0 || lFormat == 1 && m_lCurRow != 0);
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ pSekaijuApp->m_bInplaceEditing = 1;
+ CString strCellString = GetCellString (m_lCurRow, m_lCurColumn);
+ m_theTextBox.SetWindowText (strCellString);
+ m_theTextBox.SetSel (0, -1, TRUE);
+ m_theTextBox.EmptyUndoBuffer ();
+ m_theTextBox.ShowWindow (SW_SHOW);
+ m_theTextBox.SetFocus ();
+ m_theTextBox.UpdateWindow ();
+ return TRUE;
+}
+
+// テキストボックスでの編集を終了し、新しい値を格納する。
+BOOL CTrackListTrackModeView::EndTextEditingOK () {
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 新しい履歴の作成・不足トラックの追加・値の設定はSetCellStringがやる。
+
+ // 現在のセルの編集テキストを反映
+ CString strText;
+ m_theTextBox.GetWindowText (strText);
+ if (SetCellString (m_lCurRow, m_lCurColumn, strText)) {
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+
+ // 編集終了
+ m_theTextBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+// テキストボックスでの編集を終了し、新しい値を格納しない。
+BOOL CTrackListTrackModeView::EndTextEditingCancel () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ m_theTextBox.ShowWindow (SW_HIDE);
+ this->SetFocus ();
+ pSekaijuApp->m_bInplaceEditing = 0;
+ return TRUE;
+}
+
+// 値の増減を開始する
+BOOL CTrackListTrackModeView::BeginValueUpDown () {
+ _RPTF0 (_CRT_WARN, "BeginValueUpDown\n");
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ ASSERT (m_lCurButtonState == 0x0000);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ long lNumber = lColumnContent >> 16;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ //ASSERT (lFormat == 0 && m_lCurRow == 0 || lFormat == 1 && m_lCurRow != 0);
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ long lChannel = 0;
+
+
+ // 項目別に
+ switch (lColumnContent & 0xFFFF) {
+ // 入力ポート番号、入力チャンネル、出力ポート番号、出力チャンネルの場合
+ case TRACKLISTFRAME_INPUTPORT:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_INPUTPORT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 既存のトラックを保持するために置き換える。
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ break;
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_INPUTCHANNEL));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 既存のトラックを保持するために置き換える。
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ break;
+ case TRACKLISTFRAME_OUTPUTPORT:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_OUTPUTPORT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 既存のトラックを保持するために置き換える。
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ break;
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_OUTPUTCHANNEL));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 既存のトラックを保持するために置き換える。
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ break;
+ // コントロールチェンジの場合
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_CONTROLCHANGE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // このトラックで最初のCC#lNumberイベントを探す。
+ lChannel = MIDITrack_GetOutputChannel (pTempTrack);
+ pTempEvent = MIDITrack_GetFirstKindEvent (pTempTrack, MIDIEVENT_CONTROLCHANGE | lChannel);
+ while (pTempEvent) {
+ if (MIDIEvent_GetNumber (pTempEvent) == lNumber) {
+ break;
+ }
+ pTempEvent = pTempEvent->m_pNextSameKindEvent;
+ }
+ // なかった場合、コントロールチェンジイベントを新規作成してトラックに追加。
+ if (pTempEvent == NULL) {
+ lChannel = CLIP (0, lChannel, 15);
+ VERIFY (pTempEvent = MIDIEvent_CreateControlChange (0, lChannel, lNumber, 0));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ }
+ // あった場合、既存のものを保持し、新しいコントロールチェンジイベントに置き換える。
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ }
+ break;
+ // プログラムチェンジの場合
+ case TRACKLISTFRAME_PROGRAMCHANGE:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_PROGRAMCHANGE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // このトラックで最初のプログラムチェンジイベントを探す。
+ lChannel = MIDITrack_GetOutputChannel (pTempTrack);
+ pTempEvent = MIDITrack_GetFirstKindEvent (pTempTrack, MIDIEVENT_PROGRAMCHANGE | lChannel);
+ // なかった場合、プログラムチェンジイベントを新規作成してトラックに追加。
+ if (pTempEvent == NULL) {
+ lChannel = CLIP (0, lChannel, 15);
+ VERIFY (pTempEvent = MIDIEvent_CreateProgramChange (0, lChannel, 0));
+ VERIFY (MIDITrack_InsertEvent (pTempTrack, pTempEvent));
+ }
+ // あった場合、既存のものを保持し、新しいプログラムチェンジイベントに置き換える。
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ }
+ break;
+ // タイム+、キー+、ベロシティ+の場合(20091126追加)
+ case TRACKLISTFRAME_TIMEPLUS:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_TIMEPLUS));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 既存のトラックを保持するために置き換える。
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ break;
+ case TRACKLISTFRAME_KEYPLUS:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_KEYPLUS));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 既存のトラックを保持するために置き換える。
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ break;
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_VELPLUS));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 既存のトラックを保持するために置き換える。
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ break;
+ }
+ return TRUE;
+}
+
+// 値の増減を終了する
+BOOL CTrackListTrackModeView::EndValueUpDown () {
+ _RPTF0 (_CRT_WARN, "EndValueUpDown\n");
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ long lNumber = lColumnContent >> 16;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ // 新しい履歴の用意
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ VERIFY (pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow));
+ long lChannel = MIDITrack_GetOutputChannel (pTempTrack);
+ lChannel = CLIP (0, lChannel, 15);
+ // 項目別に
+ switch (lColumnContent & 0xFFFF) {
+ case TRACKLISTFRAME_INPUTPORT:
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ case TRACKLISTFRAME_OUTPUTPORT:
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ // 履歴記録
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pTempTrack));
+ break;
+ // コントロールチェンジ
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ // このトラックで最初のCC#lNumberイベントを探す。
+ pTempEvent = MIDITrack_GetFirstKindEvent (pTempTrack, MIDIEVENT_CONTROLCHANGE | lChannel);
+ while (pTempEvent) {
+ if (MIDIEvent_GetNumber (pTempEvent) == lNumber) {
+ break;
+ }
+ pTempEvent = pTempEvent->m_pNextSameKindEvent;
+ }
+ // 注意:フォーマット0の最初以外のトラック又はフォーマット1の最初のトラックで設定してはならない。
+ ASSERT (pTempEvent);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ break;
+ // プログラムチェンジ
+ case MIDIEVENT_PROGRAMCHANGE:
+ // このトラックで最初のプログラムチェンジイベントを探す。
+ pTempEvent = MIDITrack_GetFirstKindEvent (pTempTrack, MIDIEVENT_PROGRAMCHANGE | lChannel);
+ // 注意:フォーマット0の最初以外のトラック又はフォーマット1の最初のトラックで設定してはならない。
+ ASSERT (pTempEvent);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ break;
+ // タイム+、キー+、ベロシティ+の場合(20091126追加)
+ case TRACKLISTFRAME_TIMEPLUS:
+ case TRACKLISTFRAME_KEYPLUS:
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ // 履歴記録
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pTempTrack));
+ }
+ return TRUE;
+}
+
+// 現在のセルの値を増減させる
+BOOL CTrackListTrackModeView::AddValueOfCurCell (long lDeltaValue) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ // 現在のトラックへのポインタを取得
+ // (該当するトラックは BeginValueUpDownで追加されているはずである)
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ VERIFY (pMIDITrack = pSekaijuDoc->GetTrack (m_lCurRow));
+ // 値の反映
+ long lValue = 0;
+ long lNumber = 0;
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ switch (lColumnContent & 0xFFFF) {
+ // コントロールチェンジ(0〜127)の場合
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ // 注意:フォーマット0の最初以外のトラック又はフォーマット1の最初のトラックでは設定してはならない。
+ lNumber = pTrackListFrame->GetColumnContent (m_lCurColumn) >> 16;
+ VERIFY (pMIDIEvent = pSekaijuDoc->GetTrackFirstControlChange (pMIDITrack, lNumber));
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ // (Bank Select MSB (CC#0) 又は Bank Select LSB (CC#32)) の場合かつパッチサーチONのとき
+ if ((lNumber == 0 || lNumber == 32) && pSekaijuApp->m_theGeneralOption.m_bPatchSearch) {
+ long lRet;
+ MIDIEvent* pCC0Event = pSekaijuDoc->FindBankMSB (pMIDIEvent);
+ long lBankMSB = 0;
+ if (pCC0Event) {
+ lBankMSB = MIDIEvent_GetValue (pCC0Event);
+ }
+ MIDIEvent* pCC32Event = pSekaijuDoc->FindBankLSB (pMIDIEvent);
+ long lBankLSB = 0;
+ if (pCC32Event) {
+ lBankLSB = MIDIEvent_GetValue (pCC32Event);
+ }
+ MIDIEvent* pPCEvent = pSekaijuDoc->FindProgramChange (pMIDIEvent);
+ long lProgramChange = 0;
+ if (pPCEvent) {
+ lProgramChange = MIDIEvent_GetNumber (pPCEvent);
+ }
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ MIDIInstrumentDefinition* pMIDIInstDef = lTrackViewMode ?
+ pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort] :
+ pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ // インストゥルメント定義が設定されている場合
+ if (pMIDIInstDef) {
+ MIDIPatchNameTable* pMIDIPatchNameTable = NULL;
+ long lBank = 0;
+ TCHAR szBuf[256];
+ long lNewValue = lValue + (lDeltaValue > 0 ? 1 : -1);
+ long lTempNewValue = lValue; // 最後に音色が見つかった新しい値
+ while (0 <= lNewValue && lNewValue <= 127) {
+ if (lNumber == 0) {
+ lBank = (lNewValue << 7) | lBankLSB;
+ }
+ else if (lNumber == 32) {
+ lBank = (lBankMSB << 7) | lNewValue;
+ }
+ // 音色があるか調べる
+ pMIDIPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pMIDIInstDef, lBank);
+ lRet = 0;
+ if (pMIDIPatchNameTable) {
+ lRet = MIDIPatchNameTable_GetName
+ (pMIDIPatchNameTable, lProgramChange, szBuf, TSIZEOF (szBuf));
+ }
+ // 音色があった場合
+ if (lRet > 0) {
+ lTempNewValue = lNewValue;
+ if (lNewValue - lValue >= lDeltaValue && lDeltaValue > 0 ||
+ lNewValue - lValue <= lDeltaValue && lDeltaValue < 0) {
+ break;
+ }
+ }
+ lNewValue += (lDeltaValue > 0 ? 1 : -1);
+ }
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lTempNewValue, 127)));
+ }
+ // インストゥルメント定義が設定されていない場合(通常の場合と同じ処理)
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ }
+ // 通常の場合
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ break;
+ // プログラムチェンジ(0〜127)の場合
+ case TRACKLISTFRAME_PROGRAMCHANGE:
+ // 注意:フォーマット0の最初以外のトラック又はフォーマット1の最初のトラックでは設定してはならない。
+ VERIFY (pMIDIEvent = pSekaijuDoc->GetTrackFirstProgramChange (pMIDITrack));
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ // パッチサーチONのとき
+ if (pSekaijuApp->m_theGeneralOption.m_bPatchSearch) {
+ long lRet;
+ MIDIEvent* pCC0Event = pSekaijuDoc->FindBankMSB (pMIDIEvent);
+ long lBankMSB = 0;
+ if (pCC0Event) {
+ lBankMSB = MIDIEvent_GetValue (pCC0Event);
+ }
+ MIDIEvent* pCC32Event = pSekaijuDoc->FindBankLSB (pMIDIEvent);
+ long lBankLSB = 0;
+ if (pCC32Event) {
+ lBankLSB = MIDIEvent_GetValue (pCC32Event);
+ }
+ MIDIEvent* pPCEvent = pMIDIEvent;
+ long lProgramChange = 0;
+ if (pPCEvent) {
+ lProgramChange = MIDIEvent_GetNumber (pPCEvent);
+ }
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ MIDIInstrumentDefinition* pMIDIInstDef = lTrackViewMode ?
+ pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort] :
+ pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ // インストゥルメント定義が設定されている場合
+ if (pMIDIInstDef) {
+ MIDIPatchNameTable* pMIDIPatchNameTable = NULL;
+ long lBank = 0;
+ TCHAR szBuf[256];
+ long lNewValue = lValue + (lDeltaValue > 0 ? 1 : -1);
+ long lTempNewValue = lValue; // 最後に音色が見つかった新しい値
+ while (0 <= lNewValue && lNewValue <= 127) {
+ lBank = (lBankMSB << 7) | lBankLSB;
+ // 音色があるか調べる
+ pMIDIPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pMIDIInstDef, lBank);
+ lRet = 0;
+ if (pMIDIPatchNameTable) {
+ lRet = MIDIPatchNameTable_GetName
+ (pMIDIPatchNameTable, lNewValue, szBuf, TSIZEOF (szBuf));
+ }
+ // 音色があった場合
+ if (lRet > 0) {
+ lTempNewValue = lNewValue;
+ if (lNewValue - lValue >= lDeltaValue && lDeltaValue > 0 ||
+ lNewValue - lValue <= lDeltaValue && lDeltaValue < 0) {
+ break;
+ }
+ }
+ lNewValue += (lDeltaValue > 0 ? 1 : -1);
+ }
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lTempNewValue, 127)));
+ }
+ // インストゥルメント定義が設定されていない場合(通常の場合と同じ処理)
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ }
+ // 通常の場合
+ else {
+ VERIFY (MIDIEvent_SetValue (pMIDIEvent, CLIP (0, lValue + lDeltaValue, 127)));
+ }
+ break;
+ // 入力ポート(0〜15)の場合
+ case TRACKLISTFRAME_INPUTPORT:
+ lValue = MIDITrack_GetInputPort (pMIDITrack);
+ VERIFY (MIDITrack_SetInputPort (pMIDITrack, CLIP (0, lValue + lDeltaValue, 15)));
+ break;
+ // 入力チャンネル(0〜15)の場合
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ lValue = MIDITrack_GetInputChannel (pMIDITrack);
+ VERIFY (MIDITrack_SetInputChannel (pMIDITrack, CLIP (-1, lValue + lDeltaValue, 15)));
+ break;
+ // 出力ポート(0〜15)の場合
+ case TRACKLISTFRAME_OUTPUTPORT:
+ lValue = MIDITrack_GetOutputPort (pMIDITrack);
+ VERIFY (MIDITrack_SetOutputPort (pMIDITrack, CLIP (0, lValue + lDeltaValue, 15)));
+ break;
+ // 出力チャンネル(0〜15)の場合
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ lValue = MIDITrack_GetOutputChannel (pMIDITrack);
+ VERIFY (MIDITrack_SetOutputChannel (pMIDITrack, CLIP (-1, lValue + lDeltaValue, 15)));
+ break;
+ // タイム+(-127〜127)の場合
+ case TRACKLISTFRAME_TIMEPLUS:
+ lValue = MIDITrack_GetTimePlus (pMIDITrack);
+ VERIFY (MIDITrack_SetTimePlus (pMIDITrack, CLIP (-127, lValue + lDeltaValue, 127)));
+ break;
+ // キー+(-127〜127)の場合
+ case TRACKLISTFRAME_KEYPLUS:
+ lValue = MIDITrack_GetKeyPlus (pMIDITrack);
+ VERIFY (MIDITrack_SetKeyPlus (pMIDITrack, CLIP (-127, lValue + lDeltaValue, 127)));
+ break;
+ // ベロシティ+(-127〜127)の場合
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ lValue = MIDITrack_GetVelocityPlus (pMIDITrack);
+ VERIFY (MIDITrack_SetVelocityPlus (pMIDITrack, CLIP (-127, lValue + lDeltaValue, 127)));
+ break;
+ }
+
+ return TRUE;
+}
+
+// セルの値のOn/Offを切り替える。
+BOOL CTrackListTrackModeView::ToggleValueOfCurCell () {
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lValue = 0;
+ MIDITrack* pTempTrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ CString strHistoryName;
+ // 設定する項目の値の反映
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ switch (lColumnContent & 0xFFFF) {
+ // (未使用項目)
+ case TRACKLISTFRAME_VISIBLE:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_VISIBLE_ON_OFF));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 履歴保持のため現状トラックを差し替え
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ // Visible ON/OFF切り替え
+ lValue = pSekaijuDoc->GetTrackVisible (pCloneTrack);
+ pSekaijuDoc->SetTrackVisible (pCloneTrack, !lValue);
+ // 履歴記録
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ break;
+ // (未使用項目)
+ case TRACKLISTFRAME_ENABLE:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_ENABLE_ON_OFF));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 履歴保持のため現状トラックを差し替え
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ // Enable ON/OFF切り替え
+ lValue = pSekaijuDoc->GetTrackEnable (pCloneTrack);
+ pSekaijuDoc->SetTrackEnable (pCloneTrack, !lValue);
+ // 履歴記録
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ break;
+ // MIDI入力ON/OFF
+ case TRACKLISTFRAME_INPUTON:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_INPUT_ON_OFF));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 履歴保持のため現状トラックを差し替え
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ // 入力ON/OFF切り替え
+ lValue = MIDITrack_GetInputOn (pCloneTrack);
+ MIDITrack_SetInputOn (pCloneTrack, !lValue);
+ // 履歴記録
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ break;
+ // MIDI出力ON/OFF
+ case TRACKLISTFRAME_OUTPUTON:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_OUTPUT_ON_OFF));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 履歴保持のため現状トラックを差し替え
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ // 出力ON/OFF切り替え
+ lValue = MIDITrack_GetOutputOn (pCloneTrack);
+ MIDITrack_SetOutputOn (pCloneTrack, !lValue);
+ lValue = MIDITrack_GetOutputOn (pCloneTrack);
+ // 履歴記録
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ // 出力ON→OFFになった場合
+ if (lValue == 0) {
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pSekaijuApp->ResetTempMIDIStatusArray ();
+ pSekaijuDoc->TimeMIDIStatus (lCurTime, pSekaijuApp->m_pTempMIDIStatus);
+ long lFlags;
+ // 再生中ならばノートのみ復元
+ if (pSekaijuApp->m_bPlaying) {
+ lFlags = SDS_NOTE;
+ pSekaijuApp->m_bIgnoreNoteEvent = 1;
+ }
+ // 停止中ならば何も復元しない
+ else {
+ lFlags = 0;
+ pSekaijuApp->m_bIgnoreNoteEvent = 0;
+ }
+ pSekaijuApp->SendDifferentStatus (lFlags);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ }
+ // 出力OFF→ONになった場合
+ else {
+ long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pSekaijuApp->ResetTempMIDIStatusArray ();
+ pSekaijuDoc->TimeMIDIStatus (lCurTime, pSekaijuApp->m_pTempMIDIStatus);
+ long lFlags;
+ // 再生中ならば(a)すべて又は(b)ノートのみを復元する
+ if (pSekaijuApp->m_bPlaying) {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? SDS_ALL : SDS_NOTE;
+ pSekaijuApp->m_bIgnoreNoteEvent = 1;
+ }
+ // 停止中ならば(a)ノートを除くすべてを復元するか(b)何も復元しない
+ else {
+ lFlags = pSekaijuApp->m_theGeneralOption.m_bSearchUpdate ? (SDS_ALL & ~SDS_NOTE) : 0;
+ pSekaijuApp->m_bIgnoreNoteEvent = 0;
+ }
+ pSekaijuApp->SendDifferentStatus (lFlags);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ }
+ break;
+ // 表示モード(通常/ドラム)
+ case TRACKLISTFRAME_VIEWMODE:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_VIEWMODE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 履歴保持のため現状トラックを差し替え
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ // 通常/ドラム切り替え
+ lValue = MIDITrack_GetViewMode (pCloneTrack);
+ MIDITrack_SetViewMode (pCloneTrack, !lValue);
+ // 履歴記録
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ break;
+ }
+ return TRUE;
+}
+
+// 色の選択
+BOOL CTrackListTrackModeView::DoColorEditing () {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ MIDITrack* pTempTrack = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ // 履歴の用意
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_COLOR));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (m_lCurRow + 1, 0x000F, pCurHistoryUnit);
+ pTempTrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pTempTrack == NULL) {
+ return FALSE;
+ }
+ // 色設定ダイアログの表示
+ long lColor = 0;
+ long lRet = 0;
+ CColorDialog theDlg;
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ switch (lColumnContent & 0xFFFF) {
+ // 前景色
+ case TRACKLISTFRAME_FORECOLOR:
+ lColor = MIDITrack_GetForeColor (pTempTrack);
+ theDlg.m_cc.rgbResult = lColor;
+ theDlg.m_cc.Flags |= (CC_FULLOPEN | CC_RGBINIT);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ lRet = theDlg.DoModal ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ if (lRet == IDOK) {
+ lColor = (theDlg.GetColor () & 0x00FFFFFF);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pTempTrack));
+ VERIFY (pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pTempTrack));
+ MIDITrack_SetForeColor (pCloneTrack, lColor);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack));
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ return TRUE;
+ }
+ break;
+ // 背景色(未使用)
+ case TRACKLISTFRAME_BACKCOLOR:
+ break;
+ }
+ return FALSE;
+}
+
+// セルの文字列を取得
+CString CTrackListTrackModeView::GetCellString (long lRow, long lColumn) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ ASSERT (0 <= lRow && lRow < MAXMIDITRACKNUM);
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ MIDIEvent* pMIDIEvent = NULL;
+ CString strText;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ long lValue = 0;
+ long lNumber = 0;
+ MIDIIn* pMIDIIn = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ CString strNone;
+ VERIFY (strNone.LoadString (IDS_NONE));
+ if (pMIDITrack) {
+ long lColumnContent = pTrackListFrame->GetColumnContent (lColumn);
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ switch (lColumnContent & 0xFFFF) {
+ // トラック名
+ case TRACKLISTFRAME_TRACKNAME:
+ strText = pSekaijuDoc->GetTrackName (pMIDITrack);
+ codestr2str ((LPTSTR)(LPCTSTR)strText, strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ strText = szBuf2;
+ break;
+ // 可視(未使用)
+ case TRACKLISTFRAME_VISIBLE:
+ if (pSekaijuDoc->GetTrackVisible (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_SHOW));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_HIDE));
+ }
+ break;
+ // イネーブル(未使用)
+ case TRACKLISTFRAME_ENABLE:
+ if (pSekaijuDoc->GetTrackEnable (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_ENABLE));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_LOCK));
+ }
+ break;
+ // 入力ON
+ case TRACKLISTFRAME_INPUTON:
+ if (MIDITrack_GetInputOn (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_ON));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_OFF));
+ }
+ break;
+ // 出力ON
+ case TRACKLISTFRAME_OUTPUTON:
+ if (MIDITrack_GetOutputOn (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_ON));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_OFF));
+ }
+ break;
+ // 入力ポート番号
+ case TRACKLISTFRAME_INPUTPORT:
+ lValue = MIDITrack_GetInputPort (pMIDITrack);
+ ASSERT (0 <= lValue && lValue < MAXMIDIINDEVICENUM);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pMIDIIn = pSekaijuApp->m_pMIDIIn[lValue];
+ if (pMIDIIn) {
+ strText.Format (_T("%3d-%s"), lValue + 1, pMIDIIn->m_pDeviceName);
+ }
+ else {
+ strText.Format (_T("%3d-%s"), lValue + 1, strNone);
+ }
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ break;
+ // 入力チャンネル
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ lValue = MIDITrack_GetInputChannel (pMIDITrack);
+ if (0 <= lValue && lValue <= 15) {
+ strText.Format (_T("%3d"), lValue + 1);
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_N_A));
+ }
+ break;
+ // 出力ポート番号
+ case TRACKLISTFRAME_OUTPUTPORT:
+ lValue = MIDITrack_GetOutputPort (pMIDITrack);
+ ASSERT (0 <= lValue && lValue < MAXMIDIOUTDEVICENUM);
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ pMIDIOut = pSekaijuApp->m_pMIDIOut[lValue];
+ if (pMIDIOut) {
+ strText.Format (_T("%3d-%s"), lValue + 1, pMIDIOut->m_pDeviceName);
+ }
+ else {
+ strText.Format (_T("%3d-%s"), lValue + 1, strNone);
+ }
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ break;
+ // 出力チャンネル
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ lValue = MIDITrack_GetOutputChannel (pMIDITrack);
+ if (0 <= lValue && lValue <= 15) {
+ strText.Format (_T("%3d"), lValue + 1);
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_N_A));
+ }
+ break;
+ // 表示モード(通常/ドラム)
+ case TRACKLISTFRAME_VIEWMODE:
+ if (MIDITrack_GetViewMode (pMIDITrack)) {
+ VERIFY (strText.LoadString (IDS_DRUM));
+ }
+ else {
+ VERIFY (strText.LoadString (IDS_NORM));
+ }
+ break;
+ // コントロールチェンジ
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ lValue = -1;
+ lNumber = pTrackListFrame->GetColumnContent (lColumn) >> 16;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ if (MIDIEvent_GetNumber (pMIDIEvent) == lNumber) {
+ lValue = MIDIEvent_GetValue (pMIDIEvent);
+ break;
+ }
+ }
+ }
+ if (0 <= lValue && lValue <= 127) {
+ strText.Format (_T("%3d"), lValue);
+ }
+ else {
+ strText = _T("---");
+ }
+ break;
+ // プログラムチェンジ
+ case TRACKLISTFRAME_PROGRAMCHANGE:
+ lValue = -1;
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ lValue = MIDIEvent_GetNumber (pMIDIEvent);
+ break;
+ }
+ }
+ if (0 <= lValue && lValue <= 127 && pMIDIEvent) {
+ long lTrackOutputPort = MIDITrack_GetOutputPort (pMIDITrack);
+ ASSERT (0 <= lTrackOutputPort && lTrackOutputPort < 16);
+ long lTrackOutputChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ ASSERT (-1 <= lTrackOutputChannel && lTrackOutputChannel < 16);
+ if (lTrackOutputChannel == -1) {
+ lTrackOutputChannel = MIDIEvent_GetChannel (pMIDIEvent);
+ }
+ ASSERT (0 <= lTrackOutputChannel && lTrackOutputChannel < 16);
+ long lTrackViewMode = MIDITrack_GetViewMode (pMIDITrack);
+ TCHAR szBuf[256];
+ memset (szBuf, 0, sizeof (szBuf));
+ long lBankMSB = MIDIEvent_GetBankMSB (pMIDIEvent);
+ long lBankLSB = MIDIEvent_GetBankLSB (pMIDIEvent);
+ long lBank = (lBankMSB << 7) | lBankLSB; //MIDIEvent_GetBank (pMIDIEvent);
+ MIDIInstrumentDefinition* pInstDef = NULL;
+ // このトラックの表示モードが「通常」の場合
+ if (lTrackViewMode == 0) {
+ pInstDef = pSekaijuApp->m_pMIDIInstDefNorm[lTrackOutputPort];
+ }
+ // このトラックの表示モードが「ドラム」の場合
+ else {
+ pInstDef = pSekaijuApp->m_pMIDIInstDefDrum[lTrackOutputPort];
+ }
+ // このトラックのインストゥルメント定義が見つかった
+ if (pInstDef) {
+ MIDIPatchNameTable* pPatchNameTable =
+ MIDIInstrumentDefinition_GetPatchNameTable (pInstDef, lBank);
+ // このインストゥルメント定義の指定バンクのPatchNameTableが見つかった
+ if (pPatchNameTable) {
+ TCHAR szBuf[256];
+ memset (szBuf, 0, 256);
+ MIDIPatchNameTable_GetName
+ (pPatchNameTable, lValue, szBuf, 255);
+ strText.Format (_T("%d-%s"), lValue, szBuf);
+ }
+ else {
+ strText.Format (_T("%d"), lValue);
+ }
+ }
+ else {
+ strText.Format (_T("%d"), lValue);
+ }
+ }
+ else {
+ strText = _T("---");
+ }
+ break;
+ // タイム+
+ case TRACKLISTFRAME_TIMEPLUS:
+ if (lFormat == 1 && lRow == 0) {
+ strText.Format (_T("---"));
+ }
+ else {
+ lValue = MIDITrack_GetTimePlus (pMIDITrack);
+ strText.Format (_T("%3d"), lValue);
+ }
+ break;
+ // キー+
+ case TRACKLISTFRAME_KEYPLUS:
+ if (lFormat == 1 && lRow == 0) {
+ strText.Format (_T("---"));
+ }
+ else {
+ lValue = MIDITrack_GetKeyPlus (pMIDITrack);
+ strText.Format (_T("%3d"), lValue);
+ }
+ break;
+ // ベロシティ+
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ if (lFormat == 1 && lRow == 0) {
+ strText.Format (_T("---"));
+ }
+ else {
+ lValue = MIDITrack_GetVelocityPlus (pMIDITrack);
+ strText.Format (_T("%3d"), lValue);
+ }
+ break;
+ // イベント数
+ case TRACKLISTFRAME_NUMEVENT:
+ lValue = MIDITrack_CountEvent (pMIDITrack);
+ strText.Format (_T("%8d"), lValue);
+ break;
+ }
+ }
+ return strText;
+}
+
+// セルの文字列を設定
+BOOL CTrackListTrackModeView::SetCellString (long lRow, long lColumn, CString strText) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ m_bSettingCellString = 1;
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ long lValue = 0;
+ long lNumber = 0;
+ MIDIIn* pMIDIIn = NULL;
+ MIDIOut* pMIDIOut = NULL;
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ ASSERT (0 <= lRow && lRow < MAXMIDITRACKNUM);
+ long lColumnContent = pTrackListFrame->GetColumnContent (lColumn);
+ switch (lColumnContent & 0xFFFF) {
+ // トラック名
+ case TRACKLISTFRAME_TRACKNAME:
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_TRACKNAME));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 最初のトラック名イベントを探索
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_GetKind (pTempEvent) == MIDIEVENT_TRACKNAME) {
+ break;
+ }
+ }
+ // 最初のトラック名イベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)(strText), strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ VERIFY (pTempEvent = MIDIEvent_CreateTrackName (0, szBuf2));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 最初のトラック名が見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ TCHAR szBuf2[2048];
+ memset (szBuf2, 0, sizeof (szBuf2));
+ str2codestr ((LPTSTR)(LPCTSTR)(strText), strText.GetLength (), szBuf2, TSIZEOF (szBuf2) - 1);
+ MIDIEvent_SetText (pCloneEvent, szBuf2);
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ break;
+ // 入力ポート番号
+ case TRACKLISTFRAME_INPUTPORT:
+ strText.TrimLeft ();
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_1_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue <= 0 || lValue > 16) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_1_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_INPUTPORT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 入力ポート番号の設定
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack);
+ pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pMIDITrack);
+ MIDITrack_SetInputPort (pCloneTrack, CLIP (0, lValue - 1, 15));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ m_bSettingCellString = 0;
+ return TRUE;
+ // 入力チャンネル
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ strText.TrimLeft ();
+ if (strText == _T("n/a")) {
+ strText = _T("0");
+ }
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue <= -1 || lValue > 16) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_INPUTCHANNEL));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 入力チャンネルの設定
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack);
+ pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pMIDITrack);
+ MIDITrack_SetInputChannel (pCloneTrack, CLIP (-1, lValue - 1, 15));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ m_bSettingCellString = 0;
+ return TRUE;
+ // 出力ポート番号
+ case TRACKLISTFRAME_OUTPUTPORT:
+ strText.TrimLeft ();
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_1_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue <= 0 || lValue > 16) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_1_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_OUTPUTPORT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 出力ポート番号の設定
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack);
+ pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pMIDITrack);
+ MIDITrack_SetOutputPort (pCloneTrack, CLIP (0, lValue - 1, 15));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ m_bSettingCellString = 0;
+ return TRUE;
+ // 出力チャンネル
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ strText.TrimLeft ();
+ if (strText == _T("n/a")) {
+ strText = _T("0");
+ }
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue <= -1 || lValue > 16) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_16));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ pSekaijuApp->m_theCriticalSection.Lock ();
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_OUTPUTCHANNEL));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 出力チャンネルの設定
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack);
+ pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pMIDITrack);
+ MIDITrack_SetOutputChannel (pCloneTrack, CLIP (-1, lValue - 1, 15));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack);
+ pSekaijuApp->m_theCriticalSection.Unlock ();
+ m_bSettingCellString = 0;
+ return TRUE;
+ // コントロールチェンジ(CC#0, CC#32, ボリューム, パン, リバーブ, コーラス, ディレイなど)
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ if (lFormat == 1 && lRow == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lNumber = pTrackListFrame->GetColumnContent (lColumn) >> 16;
+ strText.TrimLeft ();
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue < 0 || lValue > 127) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_CONTROLCHANGE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 最初のCC#lNumberイベントを探索
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_IsControlChange (pTempEvent)) {
+ if (MIDIEvent_GetNumber (pTempEvent) == lNumber) {
+ break;
+ }
+ }
+ }
+ // 最初のCC#lNumberイベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ long lChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ VERIFY (pTempEvent = MIDIEvent_CreateControlChange (0, lChannel, lNumber, lValue));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 最初のCC#lNumberが見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ VERIFY (MIDIEvent_SetValue (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+ // プログラムチェンジ
+ case TRACKLISTFRAME_PROGRAMCHANGE:
+ if (lFormat == 1 && lRow == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ strText.TrimLeft ();
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue < 0 || lValue > 127) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_0_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_PROGRAMCHANGE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ // 操作対象のトラックがない場合は、必要な数だけトラックを追加する。
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // 最初のプログラムチェンジイベントを探索
+ forEachEvent (pMIDITrack, pTempEvent) {
+ if (MIDIEvent_IsProgramChange (pTempEvent)) {
+ break;
+ }
+ }
+ // 最初のプログラムチェンジイベントが見つからなかった場合
+ if (pTempEvent == NULL) {
+ long lChannel = MIDITrack_GetOutputChannel (pMIDITrack);
+ VERIFY (pTempEvent = MIDIEvent_CreateProgramChange (0, lChannel, lValue));
+ VERIFY (MIDITrack_InsertEvent (pMIDITrack, pTempEvent));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pTempEvent));
+ }
+ // 最初のプログラムチェンジイベントが見つかった場合
+ else {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent));
+ VERIFY (MIDIEvent_SetValue (pCloneEvent, lValue));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent));
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+
+ // タイム+
+ case TRACKLISTFRAME_TIMEPLUS:
+ strText.TrimLeft ();
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_M127_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue < -127 || lValue > 127) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_M127_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_TIMEPLUS));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // タイム+の設定
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack);
+ pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pMIDITrack);
+ MIDITrack_SetTimePlus (pCloneTrack, CLIP (-127, lValue, 127));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack);
+ m_bSettingCellString = 0;
+ return TRUE;
+ // キー+
+ case TRACKLISTFRAME_KEYPLUS:
+ strText.TrimLeft ();
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_M127_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue < -127 || lValue > 127) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_M127_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_KEYPLUS));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // キー+の設定
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack);
+ pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pMIDITrack);
+ MIDITrack_SetKeyPlus (pCloneTrack, CLIP (-127, lValue, 127));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack);
+ m_bSettingCellString = 0;
+ return TRUE;
+ // ベロシティ+
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ strText.TrimLeft ();
+ if (IsNumeric (strText) == 0) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_M127_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ lValue = _ttol (strText);
+ if (lValue < -127 || lValue > 127) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_INPUT_HALF_WIDTH_NUMBER_FROM_M127_TO_127));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ m_bSettingCellString = 0;
+ return FALSE;
+ }
+ // 新しい履歴の用意
+ VERIFY (strHistoryName.LoadString (IDS_MODIFY_VELPLUS));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 現在のトラックへのポインタを取得
+ pSekaijuDoc->AddTrack (lRow + 1, 0x000F, pCurHistoryUnit);
+ pMIDITrack = pSekaijuDoc->GetTrack (lRow);
+ if (pMIDITrack == NULL) {
+ return FALSE;
+ }
+ // ベロシティ+の設定
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVETRACK, pMIDITrack);
+ pCloneTrack = pSekaijuDoc->ReplaceMIDITrack (pMIDITrack);
+ MIDITrack_SetVelocityPlus (pCloneTrack, CLIP (-127, lValue, 127));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pCloneTrack);
+ m_bSettingCellString = 0;
+ return TRUE;
+ // イベント数
+ case TRACKLISTFRAME_NUMEVENT:
+ return FALSE;
+ }
+ m_bSettingCellString = 0;
+ return TRUE;
+}
+
+// 現在のセルの長方形を描画
+BOOL CTrackListTrackModeView::DrawCurFrame (CDC* pDC) {
+ CRect rcCurFrame = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcCurFrame.left -= 1;
+ rcCurFrame.right -= 1;
+ rcCurFrame.top -= 1;
+ rcCurFrame.bottom -= 1;
+ CPen thePen (PS_SOLID, 3, RGB (0, 0, 0));
+ CPen* pOldPen = pDC->SelectObject (&thePen);
+ int nOldDrawMode = pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (rcCurFrame.left, rcCurFrame.top);
+ pDC->LineTo (rcCurFrame.left, rcCurFrame.bottom);
+ pDC->LineTo (rcCurFrame.right, rcCurFrame.bottom);
+ pDC->LineTo (rcCurFrame.right, rcCurFrame.top);
+ pDC->LineTo (rcCurFrame.left, rcCurFrame.top);
+ pDC->SetROP2 (nOldDrawMode);
+ pDC->SelectObject (pOldPen);
+ return TRUE;
+
+}
+
+// セルの長方形を取得
+CRect CTrackListTrackModeView::GetRectFromCell (long lRow, long lColumn) {
+ long j;
+ CRect rcCell (0, 0, 0 ,0);
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParentFrame ();
+ for (j = 0; j < lColumn; j++) {
+ rcCell.left += pTrackListFrame->GetColumnWidth (j);
+ }
+ rcCell.right = rcCell.left + pTrackListFrame->GetColumnWidth (j);
+ rcCell.top = lRow * pTrackListFrame->GetRowZoom ();
+ rcCell.bottom = (lRow + 1) * pTrackListFrame->GetRowZoom ();
+ return rcCell;
+}
+
+// テキストボックスの移動(VISIBLE==FALSE時含む)
+BOOL CTrackListTrackModeView::MoveTextBox (long lRow, long lColumn) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ ASSERT (0 <= lRow && lRow < MAXMIDITRACKNUM);
+ ASSERT (0 <= lColumn && lColumn < TRACKLISTFRAME_NUMCOLUMN);
+ CRect rcNewCell = GetRectFromCell (lRow, lColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos(), pTrackListFrame->GetRowScrollPos ());
+ long lButtonWidth = 12;//::GetSystemMetrics (SM_CXVSCROLL);
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ }
+ else {
+ lButtonWidth = 1;
+ }
+ m_theTextBox.MoveWindow
+ (rcNewCell.left, rcNewCell.top + pTrackListFrame->GetRowZoom () / 2 - 6,
+ rcNewCell.Width () - lButtonWidth, 13);
+ return TRUE;
+}
+
+
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CTrackListTrackModeView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ pDC->SetWindowOrg (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+}
+
+// 描画
+void CTrackListTrackModeView::OnDraw (CDC* pDC) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos());
+ CFont* pOldFont = pDC->SelectObject (&(pTrackListFrame->m_theFont));
+
+ long lButtonWidth = 12;//::GetSystemMetrics (SM_CXVSCROLL);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorGrayText = ::GetSysColor (COLOR_GRAYTEXT);
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+
+ long i, j;
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ long lColumnZoom = pTrackListFrame->GetColumnZoom ();
+ // 行の背景色描画
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lVisibleTopRow = pTrackListFrame->GetVisibleTopRow ();
+ long lVisibleBottomRow = pTrackListFrame->GetVisibleBottomRow ();
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ long lNormalColor = pSekaijuApp->m_theColorOption.m_lBackColor[i % 2];
+ long lSelectedColor =
+ (CLIP (0x00, ((lNormalColor >> 16) & 0xFF) - 0x00, 0xFF) << 16) |
+ (CLIP (0x00, ((lNormalColor >> 8) & 0xFF) - 0x20, 0xFF) << 8) |
+ (CLIP (0x00, ((lNormalColor >> 0) & 0xFF) - 0x20, 0xFF) << 0);
+ if (0 <= i && i < lTrackCount) {
+ pMIDITrack = pSekaijuDoc->GetTrack (i);
+ }
+ else {
+ pMIDITrack = NULL;
+ }
+ long lBackColor = lNormalColor;
+ if (pMIDITrack) {
+ if (pSekaijuDoc->IsTrackSelected (pMIDITrack)) {
+ lBackColor = lSelectedColor;
+ }
+ }
+ pDC->FillSolidRect
+ (rcClient.left, i * lRowZoom,
+ rcClient.Width (), (i + 1) * lRowZoom,
+ lBackColor);
+ }
+ // 横線の描画
+ CPen penTrack (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor [0]);
+ CPen* pOldPen = pDC->SelectObject (&penTrack);
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ long y = i * lRowZoom;
+ pDC->MoveTo (rcClient.left, y - 1);
+ pDC->LineTo (rcClient.right, y - 1);
+ }
+ pDC->SelectObject (pOldPen);
+ // 縦線の描画
+ CPen penColumn (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor [0]);
+ pOldPen = pDC->SelectObject (&penColumn);
+ long x = 0;
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ pDC->MoveTo (x - 1, rcClient.top);
+ pDC->LineTo (x - 1, rcClient.bottom);
+ x += pTrackListFrame->GetColumnBaseWidth (j) * lColumnZoom;
+ }
+ pDC->SelectObject (pOldPen);
+
+
+ // 文字の描画
+ CRect rcText (0, 0, 0, 0);
+ pDC->SetBkMode (TRANSPARENT);
+ i = 0;
+ j = 0;
+ // 描画すべき開始行と終了行の計算
+ long lStartRow = __max (lVisibleTopRow, 0);
+ long lEndRow = __min (MAXMIDITRACKNUM, lVisibleBottomRow + 1);
+ // 各セルの文字などの描画
+ for (i = lStartRow; i < lEndRow; i++) {
+ if (i < lTrackCount) {
+ pMIDITrack = pSekaijuDoc->GetTrack (i);
+ }
+ else {
+ pMIDITrack = NULL;
+ }
+ if (pMIDITrack) {
+ long lTrackForeColor = MIDITrack_GetForeColor (pMIDITrack);
+ pDC->SetTextColor (lTrackForeColor);
+ // 各列について
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ CRect rcCell = GetRectFromCell (i, j);
+ CRect rcText = rcCell;
+ long lColumnContent = pTrackListFrame->GetColumnContent (j);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ rcText.right -= 10;
+ }
+ // 各セルの文字描画
+ CString strCellString;
+ CRect rcColor;
+ switch (lColumnContent & 0xFFFF) {
+ case TRACKLISTFRAME_FORECOLOR:
+ rcColor.left = rcCell.left + 2;
+ rcColor.right = rcCell.right - 3;
+ rcColor.top = rcCell.top + lRowZoom / 2 - 6;
+ rcColor.bottom = rcCell.top + lRowZoom / 2 + 6;
+ pDC->FillSolidRect (&rcColor, lTrackForeColor);
+ break;
+ case TRACKLISTFRAME_TRACKNAME:
+ case TRACKLISTFRAME_VISIBLE:
+ case TRACKLISTFRAME_ENABLE:
+ case TRACKLISTFRAME_INPUTON:
+ case TRACKLISTFRAME_INPUTPORT:
+ case TRACKLISTFRAME_INPUTCHANNEL:
+ case TRACKLISTFRAME_OUTPUTON:
+ case TRACKLISTFRAME_OUTPUTPORT:
+ case TRACKLISTFRAME_OUTPUTCHANNEL:
+ case TRACKLISTFRAME_VIEWMODE:
+ case TRACKLISTFRAME_CONTROLCHANGE:
+ case TRACKLISTFRAME_PROGRAMCHANGE:
+ case TRACKLISTFRAME_TIMEPLUS:
+ case TRACKLISTFRAME_KEYPLUS:
+ case TRACKLISTFRAME_VELOCITYPLUS:
+ case TRACKLISTFRAME_NUMEVENT:
+ strCellString = GetCellString (i, j);
+ pDC->DrawText (strCellString, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+ break;
+ }
+ }
+ }
+ }
+
+ // 各セルのボタン類の描画
+ CPen penColorBtnText (PS_SOLID, 1, lColorBtnText);
+ CPen penColorGrayText (PS_SOLID, 1, lColorGrayText);
+ CBrush brsColorBtnText;
+ CBrush brsColorGrayText;
+ brsColorBtnText.CreateSolidBrush (lColorBtnText);
+ brsColorGrayText.CreateSolidBrush (lColorGrayText);
+ CBrush* pOldBrush = NULL;
+
+ CRect rcButton;
+ CRect rcCell;
+ POINT pt[3];
+ pOldPen = pDC->SelectObject (&penColorBtnText);
+ pOldBrush = pDC->SelectObject (&brsColorBtnText);
+
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ for (j = 0; j < TRACKLISTFRAME_NUMCOLUMN; j++) {
+ long lColumnContent = pTrackListFrame->GetColumnContent (j);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ rcCell = GetRectFromCell (i, j);
+ rcButton = rcCell;
+ // 上ボタン
+ rcButton.left = rcCell.right - lButtonWidth;
+ rcButton.bottom = rcCell.top + lRowZoom / 2;
+ pDC->FillSolidRect (&rcButton, ::GetSysColor (COLOR_3DFACE));
+ if (i == m_lCurRow && j == m_lCurColumn && (m_lCurButtonState & 0x01) == 0x01) {
+ pDC->Draw3dRect (&rcButton, lColorBtnShadow, lColorBtnHighlight);
+ }
+ else {
+ pDC->Draw3dRect (&rcButton, lColorBtnHighlight, lColorBtnShadow);
+ }
+ pt[0].x = rcCell.right - lButtonWidth / 2;
+ pt[0].y = rcCell.top + lRowZoom * 1 / 4 - 1;
+ pt[1].x = pt[0].x - 2;
+ pt[1].y = pt[0].y + 2;
+ pt[2].x = pt[0].x + 2;
+ pt[2].y = pt[0].y + 2;
+ pDC->Polygon (pt, 3);
+ // 下ボタン
+ rcButton.top = rcCell.top + lRowZoom / 2;
+ rcButton.bottom = rcCell.bottom;
+ pDC->FillSolidRect (&rcButton, ::GetSysColor (COLOR_3DFACE));
+ if (i == m_lCurRow && j == m_lCurColumn && (m_lCurButtonState & 0x02) == 0x02) {
+ pDC->Draw3dRect (&rcButton, lColorBtnShadow, lColorBtnHighlight);
+ }
+ else {
+ pDC->Draw3dRect (&rcButton, lColorBtnHighlight, lColorBtnShadow);
+ }
+ pt[0].x = rcCell.right - lButtonWidth / 2;
+ pt[0].y = rcCell.top + lRowZoom * 3 / 4 + 1;
+ pt[1].x = pt[0].x - 2;
+ pt[1].y = pt[0].y - 2;
+ pt[2].x = pt[0].x + 2;
+ pt[2].y = pt[0].y - 2;
+ pDC->Polygon (pt, 3);
+ }
+ }
+ }
+ pDC->SelectObject (pOldPen);
+ pDC->SelectObject (pOldBrush);
+
+ // カレントセルの枠描画
+ DrawCurFrame (pDC);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// コマンドルーティングのオーバーライド
+BOOL CTrackListTrackModeView::OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {
+ // 注意:pHandlerInfo==NULLの時はコマンドを実行し、NULLでないときは
+ // コマンドは実行せずpHandlerInfoの中身を設定することを意味する。
+ if (nCode == CN_COMMAND && pHandlerInfo == NULL) {
+ }
+ return CView::OnCmdMsg (nID, nCode, pExtra, pHandlerInfo);
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CTrackListTrackModeView::OnCreate (LPCREATESTRUCT lpcs) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParentFrame ();
+ ASSERT (pTrackListFrame);
+ m_theTextBox.Create (WS_CHILD /*| WS_VISIBLE | WS_BORDER*/ | ES_AUTOHSCROLL,
+ CRect (0, pTrackListFrame->GetRowZoom () / 2 - 6,
+ pTrackListFrame->GetColumnWidth (0), 13), this, IDC_TEXTBOX);
+ m_theTextBox.SetFont (&(pTrackListFrame->m_theFont));
+ return CSekaijuView::OnCreate (lpcs);
+
+}
+
+// フォーカスを失ったとき
+void CTrackListTrackModeView::OnKillFocus (CWnd* pNewWnd) {
+ _RPTF1 (_CRT_WARN, "CTrackListTrackModeView::OnKillFocus (pNewWnd=0x%08x)\n", (long)pNewWnd);
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ // インプレーステキストボックスにフォーカスが移った場合を除き
+ if (pNewWnd != &m_theTextBox && !m_bSettingCellString) {
+ // テキスト編集中の場合はその内容を確定
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CView::OnKillFocus (pNewWnd);
+}
+
+// キー押し下げ時
+void CTrackListTrackModeView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos());
+
+ // 古いセルの再描画(20100128:ちらつき防止のため条件式追加)
+ if (IsTextEditing () == FALSE && nChar != VK_CONTROL && nChar != VK_SHIFT && nChar != VK_MENU) {
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+ }
+
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+
+ switch (nChar) {
+ // 上キー
+ case VK_UP:
+ // テキスト編集中の場合はその内容を確定
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ // カレントセルをひとつ上へ移動
+ m_lCurRow = CLIP (0, m_lCurRow - 1, MAXMIDITRACKNUM - 1);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ break;
+ // 左キー
+ case VK_LEFT:
+ // テキスト編集中の場合はその内容を確定
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ // カレントセルをひとつ左へ移動
+ m_lCurColumn = CLIP (0, m_lCurColumn - 1, TRACKLISTFRAME_NUMCOLUMN - 1);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ break;
+ // 右キー
+ case VK_RIGHT:
+ // テキスト編集中の場合はその内容を確定
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ // カレントセルをひとつ右へ移動
+ m_lCurColumn = CLIP (0, m_lCurColumn + 1, TRACKLISTFRAME_NUMCOLUMN - 1);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ break;
+ // 下キー
+ case VK_DOWN:
+ // テキスト編集中の場合はその内容を確定
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ }
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ // カレントセルをひとつ下へ移動
+ m_lCurRow = CLIP (0, m_lCurRow + 1, MAXMIDITRACKNUM - 1);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ break;
+ // 改行(Enter)キー
+ case VK_RETURN:
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ ReleaseCapture ();
+ KillTimer (1);
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // キーボードで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x0F00) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xF0F0;
+ }
+ // テキスト編集中でない場合
+ if (IsTextEditing () == FALSE) {
+ // リアルタイム入力中は編集禁止
+ if (pSekaijuApp->m_bRecording) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // ロックされている場合は編集禁止
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // フォーマット0の場合は最初のトラック以外操作不能
+ if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでコントロールチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_CONTROLCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでプログラムチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_PROGRAMCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでタイム+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでキー+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでベロシティ+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else {
+ // 文字列又は数値の列
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_TRACKNAME ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ BeginTextEditing ();
+ }
+ // 色
+ else if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_FORECOLOR ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_BACKCOLOR) {
+ if (DoColorEditing () == TRUE) {
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ // BOOL型
+ else if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_VISIBLE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_ENABLE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTON ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTON ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VIEWMODE) {
+ ToggleValueOfCurCell ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ }
+ // テキスト編集中の場合(CInplaceEditクラスからPostMessageされる。)
+ else {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ break;
+ // エスケープ(Esc)キー(CInplaceEditクラスからPostMessageされる。)
+ case VK_ESCAPE:
+ EndTextEditingCancel ();
+ break;
+ // +キー
+ case VK_ADD:
+ case 187:
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ KillTimer (1);
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // Ctrlが押されている場合はズームアップ
+ if (GetCapture () == NULL && GetKeyState (VK_CONTROL) < 0) {
+ pTrackListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ }
+ // 項目が数値の場合のみ値の上昇
+ else if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ // リアルタイム入力中は編集禁止
+ if (pSekaijuApp->m_bRecording) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // ロックされている場合は編集禁止
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // フォーマット0の場合は最初のトラック以外操作不能
+ if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでコントロールチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_CONTROLCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでプログラムチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_PROGRAMCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでタイム+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでキー+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでベロシティ+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else { // 20091126elseを追加
+ // 初回押し時のみキーボード操作開始
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ SetCapture ();
+ m_lCurButtonState |= 0x0101;
+ }
+ // 値の増減
+ if (::GetKeyState (VK_SHIFT) < 0) {
+ AddValueOfCurCell (10);
+ }
+ else {
+ AddValueOfCurCell (1);
+ }
+ }
+ }
+ break;
+ // -キー
+ case VK_SUBTRACT:
+ case 189:
+ // マウスで操作中の場合はその操作を停止
+ if (m_lCurButtonState & 0x00F0) {
+ KillTimer (1);
+ ReleaseCapture ();
+ EndValueUpDown ();
+ m_lCurButtonState &= 0xFF00;
+ }
+ // Ctrlが押されている場合はズームダウン
+ if (GetCapture () == NULL && GetKeyState (VK_CONTROL) < 0) {
+ pTrackListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ }
+ // 項目が数値の場合のみ値の下落
+ else if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ // リアルタイム入力中は編集禁止
+ if (pSekaijuApp->m_bRecording) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // ロックされている場合は編集禁止
+ if (pSekaijuDoc->m_bEditLocked) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ return;
+ }
+ // フォーマット0の場合は最初のトラック以外操作不能
+ if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでコントロールチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_CONTROLCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでプログラムチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_PROGRAMCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでタイム+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでキー+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでベロシティ+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else { // 20091126elseを追加
+ // 初回押し時のみキーボード操作開始
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ SetCapture ();
+ m_lCurButtonState |= 0x0202;
+ }
+ // 値の増減
+ if (::GetKeyState (VK_SHIFT) < 0) {
+ AddValueOfCurCell (-10);
+ }
+ else {
+ AddValueOfCurCell (-1);
+ }
+ }
+ }
+ break;
+ // Deleteキー (20090823追加)
+ case VK_DELETE:
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_TRACKLIST_DELETETRACK, NULL);
+ break;
+ // Insertキー (20090823追加)
+ case VK_INSERT:
+ // Ctrlが押されている
+ if (GetKeyState (VK_CONTROL) < 0) {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_TRACKLIST_DUPLICATETRACK, NULL);
+ }
+ // Ctrlが押されていない
+ else {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_TRACKLIST_INSERTTRACK, NULL);
+ }
+ break;
+ }
+
+ // 新しいセルの描画(20100128:ちらつき防止のため条件式追加)
+ if (IsTextEditing () == FALSE && nChar != VK_CONTROL && nChar != VK_SHIFT && nChar != VK_MENU) {
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// キー押し上げ時
+void CTrackListTrackModeView::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ switch (nChar) {
+ // +キー
+ case VK_ADD:
+ case 187:
+ // キーボードで操作中の場合
+ if (m_lCurButtonState & 0x0F00) {
+ // +キー操作のみ停止
+ m_lCurButtonState &= ~0x0101;
+ // もはや何の操作も行われていないならば
+ if (m_lCurButtonState == 0x0000) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ // -キー
+ case VK_SUBTRACT:
+ case 189:
+ // キーボードで操作中の場合
+ if (m_lCurButtonState & 0x0F00) {
+ // -キー操作のみ停止
+ m_lCurButtonState &= ~0x0202;
+ // もはや何の操作も行われていないならば
+ if (m_lCurButtonState == 0x0000) {
+ ReleaseCapture ();
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+ break;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// 文字入力時
+void CTrackListTrackModeView::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_TRACKNAME && 32 <= nChar && nChar <= 126 ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT && 48 <= nChar && nChar <= 57 ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL && 48 <= nChar && nChar <= 57 ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT && 48 <= nChar && nChar <= 57 ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL && 48 <= nChar && nChar <= 57 ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE && 48 <= nChar && nChar <= 57 ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE && 48 <= nChar && nChar <= 57 ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS && (48 <= nChar && nChar <= 57 || nChar == '-') ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS && (48 <= nChar && nChar <= 57 || nChar == '-') ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS && (48 <= nChar && nChar <= 57 || nChar == '-')) {
+ BeginTextEditing ();
+ //m_theTextBox.PostMessage (WM_CHAR, nChar, (nRepCnt << 16) | nFlags);
+ m_theTextBox.PostMessage (WM_CHAR, nChar, (nFlags & 0xFFFF0000) | (nRepCnt & 0x0000FFFF));
+ // ↑20080722:下の行はWindows2000対応。
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+
+ ::Sleep (0);
+}
+
+// マウス左ボタン押された時
+void CTrackListTrackModeView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+
+ long lButtonWidth = 12;//::GetSystemMetrics (SM_CXVSCROLL);
+ BOOL bOldTextEditing = FALSE;
+ // テキスト編集の終了
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ bOldTextEditing = TRUE;
+ }
+
+ // 古いセルの描画
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+
+ // 新しいセルの設定
+ if (m_lCurButtonState == 0x0000) {
+ long i, j;
+ GetCellFromPoint (point, &i, &j);
+ if (0 <= i && i < MAXMIDITRACKNUM && 0 <= j && j < TRACKLISTFRAME_NUMCOLUMN) {
+ m_lCurRow = i;
+ m_lCurColumn = j;
+ }
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ }
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ // ボタンの押され具合を判別
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ // 上又は下のボタンが押された場合
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ else if (pSekaijuDoc->m_bEditLocked) {
+ ;
+ }
+ // フォーマット0の場合は最初のトラック以外操作不能
+ else if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでコントロールチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_CONTROLCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでプログラムチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_PROGRAMCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでタイム+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでキー+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでベロシティ+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else {
+ // マウスによる操作を開始できる場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pTrackListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0011;
+ AddValueOfCurCell (1);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0012;
+ AddValueOfCurCell (-1);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0010;
+ }
+ }
+ }
+ }
+
+ // 新しいセルの描画
+ rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// マウス右ボタン押された時
+void CTrackListTrackModeView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+
+ long lButtonWidth = 12;//::GetSystemMetrics (SM_CXVSCROLL);
+ BOOL bOldTextEditing = FALSE;
+ // テキスト編集の終了
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ bOldTextEditing = TRUE;
+ }
+
+ // 古いセルの描画
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+
+ // 新しいセルの設定
+ if (m_lCurButtonState == 0x0000) {
+ long i, j;
+ GetCellFromPoint (point, &i, &j);
+ if (0 <= i && i < MAXMIDITRACKNUM && 0 <= j && j < TRACKLISTFRAME_NUMCOLUMN) {
+ m_lCurRow = i;
+ m_lCurColumn = j;
+ }
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ }
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ // ボタンの押され具合を判別
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ // 上又は下のボタンが押された場合
+ if (point.x > rcNewCell.right - lButtonWidth) {
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ else if (pSekaijuDoc->m_bEditLocked) {
+ ;
+ }
+ // フォーマット0の場合は最初のトラック以外操作不能
+ else if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでコントロールチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_CONTROLCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでプログラムチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_PROGRAMCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでタイム+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでキー+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでベロシティ+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else {
+ // マウスによる操作を開始できる場合
+ if (m_lCurButtonState == 0x0000) {
+ BeginValueUpDown ();
+ // 上のボタンが押された場合
+ if (point.y < rcNewCell.top + pTrackListFrame->GetRowZoom () / 2) {
+ m_lCurButtonState |= 0x0021;
+ AddValueOfCurCell (10);
+ }
+ // 下のボタンが押された場合
+ else {
+ m_lCurButtonState |= 0x0022;
+ AddValueOfCurCell (-10);
+ }
+ m_lCurButtonInterval = 200;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ SetCapture ();
+ }
+ // 既にマウス操作がなされている場合
+ else if (m_lCurButtonState & 0x00F0) {
+ m_lCurButtonState |= 0x0020;
+ }
+ }
+ }
+ // ボタンは押されていない場合
+ else {
+ long lTrackIndex = pTrackListFrame->YtoRow (point.y);
+ pSekaijuDoc->m_lTempTime = pTrackListFrame->XtoTime (point.x);
+ pSekaijuDoc->m_pTempTrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ pSekaijuDoc->m_pTempEvent = NULL;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU01));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pTrackListFrame);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ }
+ // ボタンのないセルの場合
+ else {
+ long lTrackIndex = pTrackListFrame->YtoRow (point.y);
+ pSekaijuDoc->m_lTempTime = pTrackListFrame->XtoTime (point.x);
+ pSekaijuDoc->m_pTempTrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ pSekaijuDoc->m_pTempEvent = NULL;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU01));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pTrackListFrame);
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+
+ // 新しいセルの描画
+ rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス左ボタン離されたとき
+void CTrackListTrackModeView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // 左マウスで操作中の場合のみ
+ if (m_lCurButtonState & 0x0010) {
+ // 左マウス操作の終了
+ m_lCurButtonState &= ~0x0010;
+ // もはやマウスで操作されていない場合
+ if ((m_lCurButtonState & 0x00F0) == 0x0000) {
+ EndValueUpDown ();
+ m_lCurButtonState = 0x0000;
+ KillTimer (1);
+ ReleaseCapture ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+
+ // 新しいセルの描画
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン離されたとき
+void CTrackListTrackModeView::OnRButtonUp (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ // 右マウスで操作中の場合のみ
+ if (m_lCurButtonState & 0x0020) {
+ // 右マウス操作の終了
+ m_lCurButtonState &= ~0x0020;
+ // もはやマウスで操作されていない場合
+ if ((m_lCurButtonState & 0x00F0) == 0x0000) {
+ EndValueUpDown ();
+ m_lCurButtonState = 0x0000;
+ KillTimer (1);
+ ReleaseCapture ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED);
+ }
+ }
+
+ // 新しいセルの描画
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウスが動かされたとき
+void CTrackListTrackModeView::OnMouseMove (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CTrackListTrackModeView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+
+ long lButtonWidth = 12;//::GetSystemMetrics (SM_CXVSCROLL);
+ // OnLButtonDownを実行し、現在編集中のセルを取りやめ、新しいフォーカスにセルを移動
+ SendMessage (WM_LBUTTONDOWN, nFlags, ((point.y & 0x0000FFFF) << 16) | (point.x & 0x0000FFFF));
+ if (IsTextEditing () == TRUE) {
+ return;
+ }
+ if (m_lCurButtonState != 0x0000) {
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+
+ // 新しいセルの取得
+ long i, j;
+ GetCellFromPoint (point, &i, &j);
+ if (0 <= i && i < MAXMIDITRACKNUM && 0 <= j && j < TRACKLISTFRAME_NUMCOLUMN) {
+ m_lCurRow = i;
+ m_lCurColumn = j;
+ }
+ CRect rcCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_TRACKNAME ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ // セル内のボタン以外の部分
+ if (point.x < rcCell.right - lButtonWidth) {
+ // フォーマット0の場合は最初のトラック以外操作不能
+ if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでコントロールチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_CONTROLCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでプログラムチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_PROGRAMCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでタイム+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでキー+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでベロシティ+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else {
+ // テキスト編集モードに突入
+ BeginTextEditing ();
+ }
+ }
+ }
+ else if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_FORECOLOR ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_BACKCOLOR) {
+ // フォーマット0の場合は最初のトラック以外操作不能
+ if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else {
+ // カラーダイアログ表示
+ if (DoColorEditing () == TRUE) {
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL); // TODO
+ }
+ }
+ }
+ else if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_VISIBLE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_ENABLE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTON ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTON ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VIEWMODE) {
+ // フォーマット0の場合は最初のトラック以外操作不能
+ if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else {
+ // 値の反転
+ ToggleValueOfCurCell ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews (NULL); // TODO
+ }
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CTrackListTrackModeView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+
+}
+
+// タイマー時
+void CTrackListTrackModeView::OnTimer (UINT nIDEvent) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*) GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ if (nIDEvent == 1) {
+ // タイマーの加速
+ if (m_lCurButtonInterval > 50) {
+ KillTimer (1);
+ m_lCurButtonInterval = 50;
+ SetTimer (1, m_lCurButtonInterval, NULL);
+ }
+ // 上ボタンが左クリックで押されている場合
+ if ((m_lCurButtonState & 0x00FF) == 0x0011) {
+ AddValueOfCurCell (1);
+ }
+ // 下ボタンが左クリックで押されている場合
+ else if ((m_lCurButtonState & 0x00FF) == 0x0012) {
+ AddValueOfCurCell (-1);
+ }
+ // 上ボタンが右クリックで押されている場合
+ if ((m_lCurButtonState & 0x00FF) == 0x0021) {
+ AddValueOfCurCell (10);
+ }
+ // 下ボタンが右クリックで押されている場合
+ else if ((m_lCurButtonState & 0x00FF) == 0x0022) {
+ AddValueOfCurCell (-10);
+ }
+ // 上ボタンが両クリックで押されている場合
+ if ((m_lCurButtonState & 0x00FF) == 0x0031) {
+ AddValueOfCurCell (10);
+ }
+ // 下ボタンが両クリックで押されている場合
+ else if ((m_lCurButtonState & 0x00FF) == 0x0032) {
+ AddValueOfCurCell (-10);
+ }
+ }
+ // セルの再描画
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell, FALSE);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+}
+
+// マウスホイールが回された時
+void CTrackListTrackModeView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ // 演奏位置の移動
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ // カレントセルの値の増減
+ else if (GetKeyState (VK_MENU) < 0) {
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+
+ // テキスト編集の終了
+ if (IsTextEditing ()) {
+ EndTextEditingOK ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ }
+
+ // 古いセルの描画
+ CRect rcOldCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcOldCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcOldCell.InflateRect (2, 2);
+ InvalidateRect (&rcOldCell);
+
+ // 新しいセルの設定
+ AutoScrolltoShowCell (m_lCurRow, m_lCurColumn);
+ MoveTextBox (m_lCurRow, m_lCurColumn);
+ CRect rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+
+ // ボタンの押され具合を判別
+ ASSERT (0 <= m_lCurColumn && m_lCurColumn < TRACKLISTFRAME_NUMCOLUMN);
+ long lColumnContent = pTrackListFrame->GetColumnContent (m_lCurColumn);
+ if ((lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_INPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTPORT ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_OUTPUTCHANNEL ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_CONTROLCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_PROGRAMCHANGE ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS ||
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ long lFormat = MIDIData_GetFormat (pMIDIData);
+ // フォーマット0の場合は最初のトラック以外操作不能
+ if (lFormat == 0 && m_lCurRow >= 1) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_EDIT_THIS_TRACK_IN_FORMAT0_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでコントロールチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_CONTROLCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_CONTROLCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでプログラムチェンジの使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == MIDIEVENT_PROGRAMCHANGE) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_INSERT_PROGRAMCHANGE_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでタイム+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_TIMEPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_TIMEPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでキー+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_KEYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_KEYPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // フォーマット1の場合は最初のトラックでベロシティ+の使用不可
+ else if (lFormat == 1 && m_lCurRow == 0 &&
+ (lColumnContent & 0xFFFF) == TRACKLISTFRAME_VELOCITYPLUS) {
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ CString strMsg;
+ VERIFY (strMsg.LoadString (IDS_UNABLE_TO_SET_VELPLUS_TO_THE_FIRST_TRACK_IN_FORMAT1_MIDIDATA));
+ AfxMessageBox (strMsg, MB_ICONEXCLAMATION);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ }
+ // 現在のセルを操作可能な場合
+ else {
+ // マウスによる操作を開始できる場合
+ if (m_lCurButtonState == 0x0000) {
+ long lDeltaValue = GetKeyState (VK_SHIFT) < 0 ? 10 : 1;
+ BeginValueUpDown ();
+ // 上回しの場合
+ if (lDelta > 0) {
+ AddValueOfCurCell (lDeltaValue);
+ }
+ // 下回しの場合
+ else {
+ AddValueOfCurCell (-lDeltaValue);
+ }
+ EndValueUpDown ();
+ pSekaijuDoc->SetModifiedFlag (TRUE);
+ pSekaijuDoc->UpdateAllViews
+ (NULL, SEKAIJUDOC_MIDIEVENTCHANGED | SEKAIJUDOC_MIDITRACKCHANGED);
+ }
+ }
+ }
+
+ // 新しいセルの描画
+ rcNewCell = GetRectFromCell (m_lCurRow, m_lCurColumn);
+ rcNewCell -= CSize (pTrackListFrame->GetColumnScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ rcNewCell.InflateRect (2, 2);
+ InvalidateRect (&rcNewCell);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ // 画面スクロール
+ else {
+ long lRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pTrackListFrame->SetRowScrollPos (lRowScrollPos);
+ }
+}
diff --git a/src/TrackListTrackModeView.h b/src/TrackListTrackModeView.h
new file mode 100644
index 0000000..9ecb804
--- /dev/null
+++ b/src/TrackListTrackModeView.h
@@ -0,0 +1,106 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストトラックモードビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTTRACKMODEVIEW_H_
+#define _TRACKLISTTRACKMODEVIEW_H_
+
+#include "InplaceEdit.h"
+
+class CTrackListTrackModeView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CTrackListTrackModeView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListTrackModeView(); // コンストラクタ
+ virtual ~CTrackListTrackModeView(); // デストラクタ
+
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+ long m_lCurRow; // 現在の行番号(0〜)
+ long m_lCurColumn; // 現在の列番号(0〜)
+ long m_lCurButtonState; // 現在の行・列のボタン状態
+ long m_lCurButtonInterval; // ボタンの増減間隔
+
+protected:
+ // テキストボックス
+ CInplaceEdit m_theTextBox;
+
+ // マウスキャプターさくら
+ CPoint m_ptMouseDown; // マウスが押された座標
+ CPoint m_ptMouseMove; // マウスが動かされた前回の座標
+
+
+ BOOL m_bSettingCellString; // セルの文字列を編集中であるか
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual BOOL GetCellFromPoint (CPoint pt, long* pRow, long* pColumn);
+ virtual BOOL AutoScrolltoShowCell (long lRow, long lColumn);
+ virtual BOOL IsTextEditing ();
+ virtual BOOL BeginTextEditing ();
+ virtual BOOL EndTextEditingOK ();
+ virtual BOOL EndTextEditingCancel ();
+ virtual BOOL BeginValueUpDown ();
+ virtual BOOL EndValueUpDown ();
+ virtual BOOL AddValueOfCurCell (long lDeltaValue);
+ virtual BOOL ToggleValueOfCurCell ();
+ virtual BOOL DoColorEditing ();
+ virtual CRect GetRectFromCell (long lRow, long lColumn);
+ virtual BOOL MoveTextBox (long lRow, long lColumn);
+ virtual CString GetCellString (long lRow, long lColumn);
+ virtual BOOL SetCellString (long nRow, long nColumn, CString strText);
+ virtual BOOL DrawCurFrame (CDC* pDC);
+
+ // オーバーライド
+protected:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+ virtual BOOL OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
+
+ // メッセージマップ
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnActivate (UINT nState, CWnd* pWndOther, BOOL bMinimized);
+ afx_msg void OnKillFocus (CWnd* pNewWnd);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+
+ DECLARE_MESSAGE_MAP ();
+};
+
+#endif
+
diff --git a/src/TrackListTrackScaleView.cpp b/src/TrackListTrackScaleView.cpp
new file mode 100644
index 0000000..5debbb7
--- /dev/null
+++ b/src/TrackListTrackScaleView.cpp
@@ -0,0 +1,432 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストトラックスケールビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuView.h"
+#include "SekaijuToolbar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "TrackListTrackScaleView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CTrackListTrackScaleView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CTrackListTrackScaleView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_KEYDOWN ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_LBUTTONDBLCLK ()
+ ON_WM_RBUTTONDBLCLK ()
+ ON_WM_TIMER ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListTrackScaleView::CTrackListTrackScaleView () {
+}
+
+// デストラクタ
+CTrackListTrackScaleView::~CTrackListTrackScaleView () {
+}
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動をオーバーライド
+void CTrackListTrackScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ pDC->SetWindowOrg (0, pTrackListFrame->GetRowScrollPos ());
+}
+
+// 描画
+void CTrackListTrackScaleView::OnDraw (CDC* pDC) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack;
+ BOOL bTrackZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bTrackZeroOrigin;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pTrackListFrame->GetRowScrollPos ());
+ pDC->SetBkMode (TRANSPARENT);
+ CFont* pOldFont = pDC->SelectObject (&(pTrackListFrame->m_theFont));
+ long lVisibleTopRow = pTrackListFrame->GetVisibleTopRow ();
+ long lVisibleBottomRow = pTrackListFrame->GetVisibleBottomRow ();
+ long y = 0;
+ TCHAR szBuf[256];
+ long i = 0;
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE);
+ long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW);
+ long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT);
+ long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT);
+ long lColorBlack = RGB (0, 0, 0);
+ long lColorWhite = RGB (255, 255, 255);
+
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ y = i * lRowZoom;
+ memset (szBuf, 0, sizeof (szBuf));
+ _sntprintf (szBuf, 255, _T("%d"), i + (bTrackZeroOrigin ? 0 : 1));
+ BOOL bTrackSelected = FALSE;
+ if (0 <= i && i < lTrackCount) { // 20080903位置修正
+ pMIDITrack = pSekaijuDoc->GetTrack (i);
+ bTrackSelected = pSekaijuDoc->IsTrackSelected (pMIDITrack);
+ if (GetCapture () == this) {
+ long lMinRow = __min (m_lDownRow, m_lCurRow);
+ long lMaxRow = __max (m_lDownRow, m_lCurRow);
+ if (lMinRow <= i && i <= lMaxRow) {
+ bTrackSelected = TRUE;
+ }
+ }
+ }
+ else { // 20080903位置修正
+ pMIDITrack = NULL;
+ bTrackSelected = FALSE;
+ }
+ CRect theRect (0, y, rcClient.Width (), y + lRowZoom);
+ if (bTrackSelected) {
+ pDC->FillSolidRect (&theRect, lColorBlack);
+ pDC->Draw3dRect (&theRect, lColorBlack, lColorBtnShadow);
+ pDC->SetTextColor (lColorWhite);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ else {
+ pDC->FillSolidRect (&theRect, lColorBtnFace);
+ pDC->Draw3dRect (&theRect, lColorBtnHighlight, lColorBtnShadow);
+ pDC->SetTextColor (lColorBtnText);
+ pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+ }
+ }
+ pDC->SelectObject (pOldFont);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+
+}
+
+// ビューの更新
+void CTrackListTrackScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+BOOL CTrackListTrackScaleView::OnCreate (LPCREATESTRUCT lpcs) {
+ return CSekaijuView::OnCreate (lpcs);
+}
+
+// キー押し下げ時
+void CTrackListTrackScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ switch (nChar) {
+ // Deleteキー
+ case VK_DELETE:
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ break;
+ // デフォルト
+ default:
+ pTrackListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+}
+
+// マウス左ボタン押された時
+void CTrackListTrackScaleView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pTrackListFrame->GetRowScrollPos ());
+ point += CSize (0, pTrackListFrame->GetRowScrollPos ());
+
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ)
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+
+
+ // 該当トラック内の全イベントの選択
+ m_lOldRow = pTrackListFrame->YtoRow (m_ptMouseDown.y);
+ m_lDownRow = pTrackListFrame->YtoRow (point.y);
+ m_lCurRow = pTrackListFrame->YtoRow (point.y);
+ if (nFlags & MK_SHIFT) {
+ long lMinRow = __min (m_lOldRow, m_lCurRow);
+ long lMaxRow = __max (m_lOldRow, m_lCurRow);
+ long i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (lMinRow <= i && i <= lMaxRow) {
+ pSekaijuDoc->SelectTrack (pMIDITrack, 1, pCurHistoryUnit);
+ }
+ i++;
+ }
+ }
+ else {
+ pMIDITrack = pSekaijuDoc->GetTrack (m_lCurRow);
+ if (pMIDITrack) {
+ pSekaijuDoc->SelectTrack (pMIDITrack, 1, pCurHistoryUnit);
+ }
+ }
+
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ Invalidate ();
+
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CTrackListTrackScaleView::OnRButtonDown (UINT nFlags, CPoint point) {
+}
+
+// マウス左ボタン離されたとき
+void CTrackListTrackScaleView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pTrackListFrame->GetRowScrollPos ());
+ point += CSize (0, pTrackListFrame->GetRowScrollPos ());
+
+ if (GetCapture () == this) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ KillTimer (0x21);
+ ReleaseCapture ();
+
+ if (m_lDownRow != m_lCurRow) {
+ long lMinRow = __min (m_lDownRow, m_lCurRow);
+ long lMaxRow = __max (m_lDownRow, m_lCurRow);
+ long i = 0;
+ //if (lDownRow <= lOldRow && lOldRow <= lCurRow ||
+ // lDownRow >= lOldRow && lOldRow >= lCurRow) {
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (lMinRow <= i && i <= lMaxRow) {
+ pSekaijuDoc->SelectTrack (pMIDITrack, 1, pCurHistoryUnit);
+ }
+ i++;
+ }
+ }
+
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIEVENTCHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIDATACHANGED);
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+
+}
+
+// マウス右ボタン離されたとき
+void CTrackListTrackScaleView::OnRButtonUp (UINT nFlags, CPoint point) {
+}
+
+// マウスが動かされたとき
+void CTrackListTrackScaleView::OnMouseMove (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pTrackListFrame->GetRowScrollPos ());
+ point += CSize (0, pTrackListFrame->GetRowScrollPos ());
+
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+
+ m_lCurRow = pTrackListFrame->YtoRow (point.y);
+ m_lDownRow = pTrackListFrame->YtoRow (m_ptMouseDown.y);
+ m_lOldRow = pTrackListFrame->YtoRow (m_ptMouseMove.y);
+ if (m_lOldRow != m_lCurRow) {
+ Invalidate (FALSE);
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+
+
+}
+
+// マウス左ボタンがダブルクリックされたとき
+void CTrackListTrackScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+// マウス右ボタンがダブルクリックされたとき
+void CTrackListTrackScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) {
+}
+
+
+// タイマー時
+void CTrackListTrackScaleView::OnTimer (UINT nIDEvent) {
+
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (0, pTrackListFrame->GetRowScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ if (m_ptMouseMove.y < rcClient.top) {
+ pTrackListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pTrackListFrame->m_wndRowScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y >= rcClient.bottom) {
+ pTrackListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pTrackListFrame->m_wndRowScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldRowScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ }
+ }
+}
+
+// マウスホイールが回された時
+void CTrackListTrackScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pTrackListFrame->SetRowScrollPos (lRowScrollPos);
+ }
+}
+
+
diff --git a/src/TrackListTrackScaleView.h b/src/TrackListTrackScaleView.h
new file mode 100644
index 0000000..fbb98cd
--- /dev/null
+++ b/src/TrackListTrackScaleView.h
@@ -0,0 +1,78 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストトラックスケールビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTTRACKSCALEVIEW_H_
+#define _TRACKLISTTRACKSCALEVIEW_H_
+
+class CTrackListTrackScaleView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CTrackListTrackScaleView)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ UINT m_nMouseDownFlags; // マウスが押されたときのフラグ
+ UINT m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lDownRow; // マウスが押されたときの行番号
+ long m_lCurRow; // マウスが指す現在の行番号
+ long m_lOldRow; // マウスが指す前回の行番号
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListTrackScaleView(); // コンストラクタ
+ virtual ~CTrackListTrackScaleView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo = NULL);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg BOOL OnCreate (LPCREATESTRUCT lpcs);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDblClk (UINT nFlags, CPoint point);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+#endif
diff --git a/src/TrackListTrackTimeView.cpp b/src/TrackListTrackTimeView.cpp
new file mode 100644
index 0000000..6fa738c
--- /dev/null
+++ b/src/TrackListTrackTimeView.cpp
@@ -0,0 +1,1262 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストトラックタイムビュークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 "winver.h"
+#include <afxwin.h>
+#include <afxext.h>
+#include <afxmt.h>
+#include "../../MIDIIO/MIDIIO.h"
+#include "../../MIDIData/MIDIData.h"
+#include "../../MIDIClock/MIDIClock.h"
+#include "../../MIDIStatus/MIDIStatus.h"
+#include "../../MIDIInstrument/MIDIInstrument.h"
+#include "mousewheel.h"
+#include "HistoryRecord.h"
+#include "HistoryUnit.h"
+#include "SekaijuApp.h"
+#include "SekaijuDoc.h"
+#include "SekaijuToolbar.h"
+#include "SekaijuStatusBar.h"
+#include "ChildFrame.h"
+#include "TrackListFrame.h"
+#include "SekaijuView.h"
+#include "TrackListTrackTimeView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+IMPLEMENT_DYNCREATE (CTrackListTrackTimeView, CSekaijuView)
+
+// メッセージマップ
+BEGIN_MESSAGE_MAP (CTrackListTrackTimeView, CSekaijuView)
+ ON_WM_CREATE ()
+ ON_WM_DESTROY ()
+ ON_WM_TIMER ()
+ ON_WM_TIMER ()
+ ON_WM_KEYDOWN ()
+ ON_WM_KEYUP ()
+ ON_WM_LBUTTONDOWN ()
+ ON_WM_RBUTTONDOWN ()
+ ON_WM_LBUTTONUP ()
+ ON_WM_RBUTTONUP ()
+ ON_WM_MOUSEMOVE ()
+ ON_WM_MOUSEWHEEL40 ()
+END_MESSAGE_MAP ()
+
+//------------------------------------------------------------------------------
+// 構築と破壊
+//------------------------------------------------------------------------------
+
+// コンストラクタ
+CTrackListTrackTimeView::CTrackListTrackTimeView () {
+ m_lCurTime = m_lOldTime = 0;
+ m_lOldY1 = m_lOldY2 = 0;
+ m_bOldDraw = TRUE;
+ m_lTempMode = 0;
+}
+
+// デストラクタ
+CTrackListTrackTimeView::~CTrackListTrackTimeView () {
+}
+
+//------------------------------------------------------------------------------
+// オペレーション
+//------------------------------------------------------------------------------
+
+// 旧位置の縦線消去
+void CTrackListTrackTimeView::EraseOldLine (CDC* pDC) {
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+ if (rcClient.left <= m_lOldX && m_lOldX <= rcClient.right && m_bOldDraw == TRUE) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_lOldX, m_lOldY1);
+ pDC->LineTo (m_lOldX, m_lOldY2);
+ }
+}
+
+// 現在位置の縦線描画
+void CTrackListTrackTimeView::DrawCurLine (CDC* pDC) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient); // TODO
+ long x = pTrackListFrame->TimetoX (m_lCurTime);
+ if (rcClient.left <= x && x <= rcClient.right) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ m_bOldDraw = TRUE;
+ m_lOldTime = m_lCurTime;
+ m_lOldX = x;
+ m_lOldY1 = rcClient.top;
+ m_lOldY2 = rcClient.bottom;
+ }
+ else {
+ m_bOldDraw = FALSE;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+// オーバーライド
+//------------------------------------------------------------------------------
+
+// 原点の移動
+void CTrackListTrackTimeView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ pDC->SetWindowOrg (pTrackListFrame->GetTimeScrollPos (), pTrackListFrame->GetRowScrollPos ());
+}
+
+// 描画
+void CTrackListTrackTimeView::OnDraw (CDC* pDC) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ long lVisibleLeftTime = pTrackListFrame->GetVisibleLeftTime ();
+ long lVisibleRightTime = pTrackListFrame->GetVisibleRightTime ();
+ long lVisibleTopRow = pTrackListFrame->GetVisibleTopRow ();
+ long lVisibleBottomRow = pTrackListFrame->GetVisibleBottomRow ();
+ long i, j;
+
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient); //TODO
+
+ CPen penMeasure (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[1]);
+ CPen penBeat (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lVertColor[0]);
+ CPen penTrack (PS_SOLID, 1, pSekaijuApp->m_theColorOption.m_lHorzColor[0]);
+
+ // 小節境界又はフレーム境界を配列に列挙及び、各セルの選択状態把握
+ long lLeftMeasure, lLeftBeat, lLeftTick;
+ long lRightMeasure, lRightBeat, lRightTick;
+ MIDIData_BreakTime (pMIDIData, lVisibleLeftTime, &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_BreakTime (pMIDIData, lVisibleRightTime, &lRightMeasure, &lRightBeat, &lRightTick);
+ long* pBorderTime = (long*)calloc (lRightMeasure - lLeftMeasure + 2, sizeof (long));
+ for (i = lLeftMeasure; i <= lRightMeasure + 1; i++) {
+ long lTime = 0;
+ MIDIData_MakeTime (pMIDIData, i, 0, 0, &lTime);
+ *(pBorderTime + i - lLeftMeasure) = lTime;
+ }
+
+ // 背景色と横線の描画
+ CPen* pOldPen = pDC->SelectObject (&penTrack);
+ // 一部選択されている小節の背景ブラシ作成(20100517追加)
+ // WORD HatchBits[8] = { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 };
+ WORD HatchBits[8] = { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 };
+ CBitmap bm;
+ bm.CreateBitmap (8, 8, 1, 1, HatchBits);
+ CBrush brush;
+ brush.CreatePatternBrush (&bm);
+ CBrush* pOldBrush = (CBrush*)pDC->SelectObject(&brush);
+
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+
+ i = 0;
+ for (i = lVisibleTopRow; i <= lVisibleBottomRow; i++) {
+ long lNormalColor = pSekaijuApp->m_theColorOption.m_lBackColor[i % 2];
+ long lSelectedColor =
+ (CLIP (0x00, ((lNormalColor >> 16) & 0xFF) - 0x00, 0xFF) << 16) |
+ (CLIP (0x00, ((lNormalColor >> 8) & 0xFF) - 0x20, 0xFF) << 8) |
+ (CLIP (0x00, ((lNormalColor >> 0) & 0xFF) - 0x20, 0xFF) << 0);
+ long y = i * lRowZoom;
+ pMIDITrack = pSekaijuDoc->GetTrack (i);
+ for (j = lLeftMeasure; j <= lRightMeasure; j++) {
+ long lTime1 = *(pBorderTime + j - lLeftMeasure);
+ long lTime2 = *(pBorderTime + j + 1 - lLeftMeasure);
+ long x1 = pTrackListFrame->TimetoX (lTime1);
+ long x2 = pTrackListFrame->TimetoX (lTime2);
+ long lOffset =
+ (i - lVisibleTopRow) * (lRightMeasure - lLeftMeasure + 2) +
+ (j - lLeftMeasure);
+ if (pMIDITrack) {
+ long lTrackMeasureSelected = pSekaijuDoc->IsTrackMeasureSelected (pMIDITrack, j);
+ switch (lTrackMeasureSelected) {
+ case 0: // 小節内にイベントはない
+ case 1: // 小節内のイベントはひとつも選択されていない(20100517調整)
+ pDC->FillSolidRect (x1, y, x2 - x1, lRowZoom, lNormalColor);
+ break;
+ case 2: // 小節内の一部のイベントが選択されている(20100517追加)
+ pDC->SetTextColor (lSelectedColor); // いったんFillSolidRectすると戻ってしまうので
+ pDC->SetBkColor (lNormalColor); // brushの前景色と背景色は毎回設定する必要あり。
+ pDC->FillRect (CRect (x1, y, x2, y + lRowZoom), &brush);
+ break;
+ case 3: // 小節内の全てのイベントが選択されている(20100517調整)
+ pDC->FillSolidRect (x1, y, x2 - x1, lRowZoom, lSelectedColor);
+ break;
+ }
+ }
+ // トラックは存在しない(20100517調整)
+ else {
+ pDC->FillSolidRect
+ (x1, y, x2 - x1, lRowZoom, lNormalColor);
+ }
+ }
+ pDC->MoveTo (rcClient.left, y - 1);
+ pDC->LineTo (rcClient.right, y - 1);
+ }
+
+ pDC->SelectObject(pOldBrush);
+
+
+ // 縦線(小節境界線又はフレーム境界線)の描画
+ for (i = lLeftMeasure; i <= lRightMeasure; i++) {
+ long lTime = *(pBorderTime + i - lLeftMeasure);
+ long x = pTrackListFrame->TimetoX (lTime);
+ pDC->SelectObject (&penMeasure);
+ pDC->MoveTo (x, rcClient.top);
+ pDC->LineTo (x, rcClient.bottom);
+ }
+ pDC->SelectObject (pOldPen);
+
+ // データ部の描画
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (lVisibleTopRow <= i && i <= lVisibleBottomRow) {
+ long y = i * lRowZoom;
+ long lTrackColor = MIDITrack_GetForeColor (pMIDITrack);
+ long lSelectedColor = RGB (0, 0, 0);
+ CPen theTrackPen (PS_SOLID, 1, lTrackColor);
+ CPen theSelectedPen (PS_SOLID, 1, lSelectedColor);
+ forEachEvent (pMIDITrack, pMIDIEvent) {
+ long lIsEventSelected = pSekaijuDoc->IsEventSelected (pMIDIEvent);
+ long lColor = lIsEventSelected ? lSelectedColor : lTrackColor;
+ // ノートイベントの描画
+ if (MIDIEvent_IsNote (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lKey = MIDIEvent_GetKey (pMIDIEvent);
+ long lDur = MIDIEvent_GetDuration (pMIDIEvent);
+ long x1 = pTrackListFrame->TimetoX (lTime);
+ long x2 = pTrackListFrame->TimetoX (lTime + lDur) + 1;
+ long y1 = y + lRowZoom * (127 - lKey) / 128;
+ long y2 = y1 + 1;
+ CRect rcNote (x1, y1, x2, y2);
+ pDC->FillSolidRect (&rcNote, lColor);
+ }
+ // キーアフタータッチの描画
+ else if (MIDIEvent_IsKeyAftertouch (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = pTrackListFrame->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = (i + 1) * lRowZoom;
+ long y2 = y1 - lRowZoom * (lValue) / 128;
+ CRect rcNote (x1, y1, x2, y2);
+ pDC->FillSolidRect (&rcNote, lColor);
+ if (lValue == 0) {
+ pDC->SelectObject (lIsEventSelected ? &theSelectedPen : &theTrackPen);
+ pDC->Ellipse (x1 - 2, y1 - 2, x1 + 2, y1 + 2);
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // コントロールチェンジイベントの描画
+ else if (MIDIEvent_IsControlChange (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = pTrackListFrame->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = (i + 1) * lRowZoom;
+ long y2 = y1 - lRowZoom * (lValue) / 128;
+ CRect rcNote (x1, y1, x2, y2);
+ pDC->FillSolidRect (&rcNote, lColor);
+ if (lValue == 0) {
+ pDC->SelectObject (lIsEventSelected ? &theSelectedPen : &theTrackPen);
+ pDC->Ellipse (x1 - 2, y1 - 2, x1 + 2, y1 + 2);
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // プログラムチェンジイベントの描画
+ else if (MIDIEvent_IsProgramChange (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = pTrackListFrame->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = (i + 1) * lRowZoom;
+ long y2 = y1 - lRowZoom * (lValue) / 128;
+ CRect rcNote (x1, y1, x2, y2);
+ pDC->FillSolidRect (&rcNote, lColor);
+ if (lValue == 0) {
+ pDC->SelectObject (lIsEventSelected ? &theSelectedPen : &theTrackPen);
+ pDC->Ellipse (x1 - 2, y1 - 2, x1 + 2, y1 + 2);
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // チャンネルアフタータッチの描画
+ else if (MIDIEvent_IsChannelAftertouch (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = pTrackListFrame->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = (i + 1) * lRowZoom;
+ long y2 = y1 - lRowZoom * (lValue) / 128;
+ CRect rcNote (x1, y1, x2, y2);
+ pDC->FillSolidRect (&rcNote, lColor);
+ if (lValue == 0) {
+ pDC->SelectObject (lIsEventSelected ? &theSelectedPen : &theTrackPen);
+ pDC->Ellipse (x1 - 2, y1 - 2, x1 + 2, y1 + 2);
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ // ピッチベンドの描画
+ else if (MIDIEvent_IsPitchBend (pMIDIEvent)) {
+ long lTime = MIDIEvent_GetTime (pMIDIEvent);
+ long lValue = MIDIEvent_GetValue (pMIDIEvent);
+ long x1 = pTrackListFrame->TimetoX (lTime);
+ long x2 = x1 + 1;
+ long y1 = (i + 1) * lRowZoom - lRowZoom / 2;
+ long y2 = y1 - lRowZoom * (lValue - 8192) / 16384; // 20110508修正
+ CRect rcNote (x1, y1, x2, y2);
+ pDC->FillSolidRect (&rcNote, lColor);
+ if (lValue == 8192) {
+ pDC->SelectObject (lIsEventSelected ? &theSelectedPen : &theTrackPen);
+ pDC->Ellipse (x1 - 2, y1 - 2, x1 + 2, y1 + 2);
+ pDC->SelectObject (pOldPen);
+ }
+ }
+ }
+ }
+ i++;
+ }
+
+ // 現在位置の縦線描画
+ DrawCurLine (pDC);
+
+ // マウストラッカーが必要な場合、マウストラッカーの描画
+ if (GetCapture () == this) {
+ if (m_lTempMode == 0x0401) {
+ pDC->SetROP2 (R2_NOT);
+ pDC->MoveTo (m_lMinX, m_lMinY);
+ pDC->LineTo (m_lMinX, m_lMaxY);
+ pDC->LineTo (m_lMaxX, m_lMaxY);
+ pDC->LineTo (m_lMaxX, m_lMinY);
+ pDC->LineTo (m_lMinX, m_lMinY);
+ pDC->SetROP2 (R2_COPYPEN);
+ }
+ }
+
+ free (pBorderTime);
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// ビューの更新
+void CTrackListTrackTimeView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
+ // クリティカルセクションはロックされているものとする。
+ if ((lHint & SEKAIJUDOC_PLAYSTARTED) ||
+ (lHint & SEKAIJUDOC_RECORDSTARTED) ||
+ (lHint & SEKAIJUDOC_POSITIONCHANGED)) {
+ PostMessage (WM_TIMER, 0x11, NULL);
+ }
+ CSekaijuView::OnUpdate (pSender, lHint, pHint);
+}
+
+// ウィンドウクラスの変更
+BOOL CTrackListTrackTimeView::PreCreateWindow (CREATESTRUCT& cs) {
+ CView::PreCreateWindow (cs);
+ cs.lpszClass = AfxRegisterWndClass
+ (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS,
+ NULL, // デフォルトカーソル無し
+ (HBRUSH)::GetStockObject (WHITE_BRUSH), // デフォルト背景ブラシ
+ NULL); // デフォルトアイコン無し
+ return TRUE;
+}
+
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
+// ウィンドウ生成時
+int CTrackListTrackTimeView::OnCreate (LPCREATESTRUCT lpCreateStruct) {
+ SetTimer (0x11, 55, NULL);
+ return CSekaijuView::OnCreate (lpCreateStruct);
+}
+
+// ウィンドウ破棄時
+void CTrackListTrackTimeView::OnDestroy () {
+ KillTimer (0x11);
+ CSekaijuView::OnDestroy ();
+}
+
+// タイマー呼び出し時
+void CTrackListTrackTimeView::OnTimer (UINT nIDEvent) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ if (nIDEvent == 0x11) {
+ if (pSekaijuDoc->m_pMIDIData && pSekaijuDoc->m_pMIDIClock) {
+ // クリティカルセクションロック
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ CDC* pDC = GetDC ();
+ OnPrepareDC (pDC, NULL);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ pDC->DPtoLP (&rcClient);
+ m_lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock);
+ // 現在位置縦線の更新
+ if (m_lOldTime != m_lCurTime) {
+ CPen thePen (PS_SOLID, 1, RGB (255, 0, 0));
+ CPen* pOldPen = pDC->SelectObject (&thePen);
+ EraseOldLine (pDC);
+ DrawCurLine (pDC);
+ pDC->SelectObject (pOldPen);
+ }
+
+ // ページの更新およびオートスクロール(手動スクロール時はしない)
+ if (pTrackListFrame->m_bAutoPageUpdate == TRUE) {
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lTimeMode, lTimeResolution;
+ MIDIData_GetTimeBase (pMIDIData, &lTimeMode, &lTimeResolution);
+ if (lTimeMode == MIDIDATA_TPQNBASE) {
+ // 現在位置が右側へはみ出した場合
+ long lRightMeasure; long lRightBeat; long lRightTick; long lTempRightTime;
+ MIDIData_BreakTime (pMIDIData, pTrackListFrame->GetVisibleRightTime (),
+ &lRightMeasure, &lRightBeat, &lRightTick);
+ MIDIData_MakeTime (pMIDIData, lRightMeasure, 0, 0, &lTempRightTime);
+ if (m_lCurTime >= lTempRightTime) {
+ long lNewMeasure; long lNewBeat; long lNewTick;
+ MIDIData_BreakTime (pMIDIData, m_lCurTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ MIDIData_MakeTime (pMIDIData, lNewMeasure, 0, 0, &lTempRightTime);
+ long x = pTrackListFrame->TimetoX (lTempRightTime);
+ pTrackListFrame->SetTimeScrollPos (x);
+ }
+ // 現在位置が左側へはみ出した場合
+ long lLeftMeasure; long lLeftBeat; long lLeftTick; long lTempLeftTime;
+ MIDIData_BreakTime (pMIDIData, pTrackListFrame->GetVisibleLeftTime (),
+ &lLeftMeasure, &lLeftBeat, &lLeftTick);
+ MIDIData_MakeTime (pMIDIData, lLeftMeasure, 0, 0, &lTempLeftTime);
+ if (m_lCurTime < lTempLeftTime) {
+ long lNewMeasure; long lNewBeat; long lNewTick;
+ MIDIData_BreakTime (pMIDIData, m_lCurTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ MIDIData_MakeTime (pMIDIData, lNewMeasure, 0, 0, &lTempLeftTime);
+ long x = pTrackListFrame->TimetoX (lTempLeftTime);
+ pTrackListFrame->SetTimeScrollPos (x);
+ }
+ }
+ else {
+ // 現在位置が右側へはみ出した場合
+ long lRightFrameNumber = pTrackListFrame->GetVisibleRightTime () / lTimeResolution;
+ long lTempRightTime = lRightFrameNumber * lTimeResolution;
+ if (m_lCurTime >= lTempRightTime) {
+ lTempRightTime = (m_lCurTime / lTimeResolution) * lTimeResolution;
+ long x = pTrackListFrame->TimetoX (lTempRightTime);
+ pTrackListFrame->SetTimeScrollPos (x);
+ }
+ // 現在位置が左側へはみ出した場合
+ long lLeftFrameNumber = pTrackListFrame->GetVisibleLeftTime () / lTimeResolution;
+ long lTempLeftTime = lLeftFrameNumber * lTimeResolution;
+ if (m_lCurTime < lTempLeftTime) {
+ lTempLeftTime = (m_lCurTime / lTimeResolution) * lTimeResolution;
+ long x = pTrackListFrame->TimetoX (lTempLeftTime);
+ pTrackListFrame->SetTimeScrollPos (x);
+ }
+ }
+ }
+
+ ReleaseDC (pDC);
+ // クリティカルセクション解除
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+ }
+ // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理
+ else if (nIDEvent == 0x21) {
+ if (GetCapture () == this) {
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += CSize (pTrackListFrame->GetTimeScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ if (!rcClient.PtInRect (m_ptMouseMove)) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ long lOldTimeScrollPos = pTrackListFrame->GetTimeScrollPos ();
+ long lOldRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ if (m_ptMouseMove.x < rcClient.left) {
+ pTrackListFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pTrackListFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.x > rcClient.right) {
+ pTrackListFrame->SendMessage (WM_HSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pTrackListFrame->m_wndTimeScroll.GetSafeHwnd ()));
+ }
+ if (m_ptMouseMove.y < rcClient.top) {
+ pTrackListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP,
+ (LPARAM)(pTrackListFrame->m_wndRowScroll.GetSafeHwnd ()));
+ }
+ else if (m_ptMouseMove.y > rcClient.bottom) {
+ pTrackListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN,
+ (LPARAM)(pTrackListFrame->m_wndRowScroll.GetSafeHwnd ()));
+ }
+ WORD wX = (WORD)(m_ptMouseMove.x - lOldTimeScrollPos);
+ WORD wY = (WORD)(m_ptMouseMove.y - lOldRowScrollPos);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX));
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ }
+ }
+ }
+}
+
+
+// キーが押された時
+void CTrackListTrackTimeView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ switch (nChar) {
+ // Control
+ case VK_CONTROL:
+ if (1) {
+ WORD wX = (WORD)(m_ptMouseMove.x - pTrackListFrame->GetTimeScrollPos ());
+ WORD wY = (WORD)(m_ptMouseMove.y - pTrackListFrame->GetRowScrollPos ());
+ UINT nFlags = m_nMouseMoveFlags | MK_CONTROL;
+ PostMessage (WM_MOUSEMOVE, (WPARAM)nFlags, (LPARAM)((wY << 16) | wX));
+ }
+ break;
+ // Deleteキー
+ case VK_DELETE:
+ // 『編集(E)』-『削除』実行 (20090823追加)
+ PostMessage (WM_COMMAND, ID_EDIT_DELETE, NULL);
+ break;
+ // デフォルト
+ default:
+ pTrackListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt);
+ break;
+ }
+ return;
+}
+
+// キーが離された時
+void CTrackListTrackTimeView::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ switch (nChar) {
+ // Control
+ case VK_CONTROL:
+ if (1) {
+ WORD wX = (WORD)(m_ptMouseMove.x - pTrackListFrame->GetTimeScrollPos ());
+ WORD wY = (WORD)(m_ptMouseMove.y - pTrackListFrame->GetRowScrollPos ());
+ UINT nFlags = m_nMouseMoveFlags & (~MK_CONTROL);
+ PostMessage (WM_MOUSEMOVE, (WPARAM)nFlags, (LPARAM)((wY << 16) | wX));
+ }
+ break;
+ }
+ return;
+}
+
+
+// マウス左ボタン押された時
+void CTrackListTrackTimeView::OnLButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pTrackListFrame->GetTimeScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += sizWndOrg;
+ ASSERT (m_lTempMode == 0);
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ CString strHistoryName;
+ m_lTempTool = pTrackListFrame->m_lCurTool;
+ m_lTempTime = pTrackListFrame->XtoTime (point.x);
+ m_lTempTrackIndex = pTrackListFrame->YtoRow (point.y);
+ CRect rcRegion;
+ long lNewTrackIndex = pTrackListFrame->YtoRow (point.y);
+ long lNewTime = pTrackListFrame->XtoTime (point.x);
+ long lNewMeasure, lNewBeat, lNewTick;
+ BOOL bPtInSelectedCell = FALSE;
+
+ switch (m_lTempTool) {
+ // 選択
+ case ID_TRACKLIST_SELECT:
+ // 既存の選択されているセル上にマウスカーソルがあるか調べる
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ pMIDITrack = pSekaijuDoc->GetTrack (lNewTrackIndex);
+ if (pMIDITrack) {
+ if (pSekaijuDoc->IsTrackMeasureSelected (pMIDITrack, lNewMeasure) >= 2) { // 20100517新規修正
+ bPtInSelectedCell = TRUE;
+ }
+ }
+
+ // 既存の選択されているセルの上にマウスが置かれた場合(コピー又は移動モード)
+ if (bPtInSelectedCell) {
+ long i = 0;
+ long j = 0;
+ MIDITrack* pTempTrack;
+ MIDIEvent* pTempEvent;
+ m_theTempSelectedEventArray.RemoveAll ();
+ m_theTempEndofTrackEventArray.RemoveAll ();
+ // 複写の場合(CONTROLが押されている)
+ if (nFlags & MK_CONTROL) {
+ VERIFY (strHistoryName.LoadString (IDS_DUPLICATE_MEASURE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 選択されていないEOTイベントの履歴保持
+ forEachTrack (pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ if (pSekaijuDoc->IsEventSelected (pLastEvent) == 0) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ m_theTempEndofTrackEventArray.Add (pCloneEvent);
+ }
+ }
+ }
+ }
+ // イベントの複写
+ forEachTrack (pMIDIData, pTempTrack) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (pSekaijuDoc->IsEventSelected (pTempEvent) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ if (MIDIEvent_IsEndofTrack (pTempEvent)) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ pCloneEvent->m_lUser1 = i;
+ pCloneEvent->m_lUser2 = MIDIEvent_GetTime (pCloneEvent);
+ m_theTempSelectedEventArray.Add (pCloneEvent);
+ pTempEvent = pCloneEvent;
+ }
+ else {
+ // 複写元イベントを非選択状態にする。
+ pCloneEvent = pSekaijuDoc->SelectEvent (pTempEvent, 0, pCurHistoryUnit);
+ if (pCloneEvent == NULL) {
+ continue;
+ }
+ // イベントの複写をし、複写したイベントを選択状態にする。
+ pCloneEvent = pSekaijuDoc->DuplicateMIDIEvent (pCloneEvent);
+ if (pCloneEvent) {
+ pCloneEvent->m_lUser1 = i;
+ pCloneEvent->m_lUser2 = MIDIEvent_GetTime (pCloneEvent);
+ pSekaijuDoc->SetEventSelected (pCloneEvent, 1);
+ m_theTempSelectedEventArray.Add (pCloneEvent);
+ pTempEvent = pCloneEvent;
+ }
+ }
+ }
+ }
+ i++;
+ }
+ m_lTempMode = 0x0403;
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAllCopy);
+ }
+ // 移動の場合(CONTROLが押されていない)
+ else {
+ VERIFY (strHistoryName.LoadString (IDS_MOVE_MEASURE));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 選択されていないEOTイベントの履歴保持
+ forEachTrack (pMIDIData, pMIDITrack) {
+ MIDIEvent* pLastEvent = MIDITrack_GetLastEvent (pMIDITrack);
+ if (pLastEvent) {
+ if (MIDIEvent_IsEndofTrack (pLastEvent)) {
+ if (pSekaijuDoc->IsEventSelected (pLastEvent) == 0) {
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent);
+ pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent);
+ m_theTempEndofTrackEventArray.Add (pCloneEvent);
+ }
+ }
+ }
+ }
+ // 移動するイベントを履歴保持し、移動イベント用用配列に登録
+ forEachTrack (pMIDIData, pTempTrack) {
+ forEachEvent (pTempTrack, pTempEvent) {
+ if (pSekaijuDoc->IsEventSelected (pTempEvent) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL) {
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pTempEvent));
+ pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pTempEvent);
+ pCloneEvent->m_lUser1 = i;
+ pCloneEvent->m_lUser2 = MIDIEvent_GetTime (pCloneEvent);
+ m_theTempSelectedEventArray.Add (pCloneEvent);
+ pTempEvent = pCloneEvent;
+ }
+ }
+ i++;
+ }
+ m_lTempMode = 0x0402;
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ //rcRegion = GetNoteRect (m_pTempEvent);
+ //InvalidateRect (rcRegion - sizWndOrg);
+ Invalidate ();
+ pTrackListFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ }
+
+ // 選択されていないセルの上にマウスが置かれた場合(選択モード)
+ else {
+ VERIFY (strHistoryName.LoadString (IDS_SELECT_DESELECT));
+ VERIFY (pSekaijuDoc->AddHistoryUnit (strHistoryName));
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 旧選択範囲の選択解除
+ long i = 0;
+ if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) {
+ pSekaijuDoc->SelectNoObject (pCurHistoryUnit);
+ }
+ long lMinTime, lMinMeasure, lMinBeat, lMinTick;
+ long lMaxTime, lMaxMeasure, lMaxBeat, lMaxTick;
+ // 新しい選択範囲矩形を描画する
+ m_lMinY = pTrackListFrame->RowtoY (lNewTrackIndex);
+ m_lMaxY = pTrackListFrame->RowtoY (lNewTrackIndex + 1);
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lMinMeasure, &lMinBeat, &lMinTick);
+ MIDIData_MakeTime (pMIDIData, lMinMeasure, 0, 0, &lMinTime);
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lMaxMeasure, &lMaxBeat, &lMaxTick);
+ MIDIData_MakeTime (pMIDIData, lMaxMeasure + 1, 0, 0, &lMaxTime);
+ m_lMinX = pTrackListFrame->TimetoX (lMinTime);
+ m_lMaxX = pTrackListFrame->TimetoX (lMaxTime);
+ //dc.MoveTo (lMinX, lMinY);
+ //dc.LineTo (lMinX, lMaxY);
+ //dc.LineTo (lMaxX, lMaxY);
+ //dc.LineTo (lMaxX, lMinY);
+ //dc.LineTo (lMinX, lMinY);
+ //dc.SetROP2 (R2_COPYPEN);
+ m_lTempMode = 0x0401;
+ Invalidate ();
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSelectAdd2);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSelect2);
+ }
+ pTrackListFrame->m_bAutoPageUpdate = FALSE;
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ }
+ break;
+
+ // スクラブ
+ case ID_TRACKLIST_SPEAKER:
+ if (pSekaijuApp->m_bPlaying) {
+ pTrackListFrame->SendMessage (WM_COMMAND, (WPARAM)ID_CONTROL_PLAY, (LPARAM)0);
+ }
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ m_lTempMode = 0x0501;
+ pTrackListFrame->m_bAutoPageUpdate = FALSE;
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ SetTimer (0x21, 55, NULL);
+ SetCapture ();
+ break;
+ }
+ m_ptMouseDown = m_ptMouseMove = point;
+ m_nMouseDownFlags = m_nMouseMoveFlags = nFlags;
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+}
+
+// マウス右ボタン押された時
+void CTrackListTrackTimeView::OnRButtonDown (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+
+ CPoint ptMenu (point);
+ ClientToScreen (&ptMenu);
+ CSize sizWndOrg (pTrackListFrame->GetTimeScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += sizWndOrg;
+
+ long lTrackIndex = pTrackListFrame->YtoRow (point.y);
+ long lTime = pTrackListFrame->XtoTime (point.x);
+ long lMeasure, lBeat, lTick;
+ MIDIData_BreakTime (pMIDIData, lTime, &lMeasure, &lBeat, &lTick);
+ MIDIData_MakeTime (pMIDIData, lMeasure, 0, 0, &lTime);
+ pSekaijuDoc->m_lTempTime = lTime;
+ pSekaijuDoc->m_lTempTrackIndex = lTrackIndex;
+ pSekaijuDoc->m_pTempTrack = pSekaijuDoc->GetTrack (lTrackIndex);
+ pSekaijuDoc->m_pTempEvent = NULL;
+
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+
+ CMenu theMenu;
+ VERIFY (theMenu.LoadMenu (IDR_POPUPMENU02));
+ CMenu* pContextMenu = theMenu.GetSubMenu (0);
+ pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+ ptMenu.x, ptMenu.y, pTrackListFrame);
+
+}
+
+// マウス左ボタン離されたとき
+void CTrackListTrackTimeView::OnLButtonUp (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pTrackListFrame->GetTimeScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += sizWndOrg;
+
+ long lDownTrackIndex = pTrackListFrame->YtoRow (m_ptMouseDown.y);
+ long lOldTrackIndex = pTrackListFrame->YtoRow (m_ptMouseMove.y);
+ long lNewTrackIndex = pTrackListFrame->YtoRow (point.y);
+ long lDownTime = pTrackListFrame->XtoTime (m_ptMouseDown.x);
+ long lOldTime = pTrackListFrame->XtoTime (m_ptMouseMove.x);
+ long lNewTime = pTrackListFrame->XtoTime (point.x);
+ CRect rcRegion;
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock (); // 20080821位置修正
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pMIDITrack = NULL;
+ MIDIEvent* pMIDIEvent = NULL;
+ MIDITrack* pCloneTrack = NULL;
+ MIDIEvent* pCloneEvent = NULL;
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ switch (m_lTempTool) {
+ // 選択
+ case ID_TRACKLIST_SELECT:
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ // 移動中又は複写中
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ long j;
+ long lDownMeasure, lDownBeat, lDownTick;
+ long lOldMeasure, lOldBeat, lOldTick;
+ long lNewMeasure, lNewBeat, lNewTick;
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lDownMeasure, &lDownBeat, &lDownTick);
+ MIDIData_BreakTime (pMIDIData, lOldTime, &lOldMeasure, &lOldBeat, &lOldTick);
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ long lTempSelectedEventCount = m_theTempSelectedEventArray.GetSize ();
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ MIDIEvent* pTempEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pTempEvent->m_lUser1 = 0;
+ pTempEvent->m_lUser2 = 0;
+ }
+ // 複写の場合
+ if (m_lTempMode == 0x0403) {
+ // 元の位置と変わっていない場合、複写したイベントを削除し、履歴に登録しない。
+ if (lNewTrackIndex == lDownTrackIndex &&
+ lNewMeasure == lDownMeasure) {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ MIDIEvent_Delete (pCloneEvent);
+ pCloneEvent = NULL;
+ }
+ }
+ // 元に位置と異なる場所に複写した場合、複写したイベントを履歴登録
+ else {
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ }
+ }
+ // 移動の場合
+ else if (m_lTempMode == 0x0402) {
+ // 移動したイベントを履歴登録
+ for (j = 0; j < lTempSelectedEventCount; j++) {
+ pCloneEvent = (MIDIEvent*)(m_theTempSelectedEventArray.GetAt (j));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ }
+ // 選択されていないEOTイベントの復元と履歴登録
+ long lTempEndofTrackEventCount = m_theTempEndofTrackEventArray.GetSize ();
+ for (j = 0; j < lTempEndofTrackEventCount; j++) {
+ pCloneEvent = (MIDIEvent*)(m_theTempEndofTrackEventArray.GetAt (j));
+ pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pCloneEvent);
+ }
+ }
+ // 選択範囲変更中
+ else {
+ long i, j;
+ long lMinMeasure, lMinBeat, lMinTick;
+ long lMaxMeasure, lMaxBeat, lMaxTick;
+ long lMinTrackIndex;
+ long lMaxTrackIndex;
+ lMinTrackIndex = __min (lDownTrackIndex, lNewTrackIndex);
+ lMaxTrackIndex = __max (lDownTrackIndex, lNewTrackIndex);
+ if (lDownTime < lNewTime) {
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lMinMeasure, &lMinBeat, &lMinTick);
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lMaxMeasure, &lMaxBeat, &lMaxTick);
+ }
+ else {
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lMinMeasure, &lMinBeat, &lMinTick);
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lMaxMeasure, &lMaxBeat, &lMaxTick);
+ }
+ i = 0;
+ forEachTrack (pMIDIData, pMIDITrack) {
+ if (lMinTrackIndex <= i && i <= lMaxTrackIndex) {
+ for (j = lMinMeasure; j <= lMaxMeasure; j++) {
+ pSekaijuDoc->SelectTrackMeasure (pMIDITrack, j, 1, pCurHistoryUnit);
+ }
+ }
+ i++;
+ }
+ }
+ pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED |
+ SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED);
+ break;
+
+ // スクラブ
+ case ID_TRACKLIST_SPEAKER:
+ pSekaijuApp->SendAllNoteOff ();
+ pSekaijuApp->SendAllSoundOff ();
+ pSekaijuDoc->UpdateAllViews (NULL);
+ break;
+ }
+ m_lTempMode = 0;
+ KillTimer (0x21);
+ ReleaseCapture ();
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+}
+
+// マウス右ボタン離されたとき
+void CTrackListTrackTimeView::OnRButtonUp (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+}
+
+// マウスが動かされたとき
+void CTrackListTrackTimeView::OnMouseMove (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+
+ // 録音中は何もしない
+ if (pSekaijuApp->m_bRecording) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+ // MIDIデータがロックされている場合は何もしない
+ if (pSekaijuDoc->m_bEditLocked) {
+ ::SetCursor (pSekaijuApp->m_hCursorNo);
+ return;
+ }
+
+ CClientDC dc (this);
+ OnPrepareDC (&dc, NULL);
+ CSize sizWndOrg (pTrackListFrame->GetTimeScrollPos (), pTrackListFrame->GetRowScrollPos ());
+ point += sizWndOrg;
+ CRect rcClient;
+ GetClientRect (&rcClient);
+ rcClient += sizWndOrg;
+ long lDownTrackIndex = pTrackListFrame->YtoRow (m_ptMouseDown.y);
+ long lOldTrackIndex = pTrackListFrame->YtoRow (m_ptMouseMove.y);
+ long lNewTrackIndex = pTrackListFrame->YtoRow (point.y);
+ long lDownTime = pTrackListFrame->XtoTime (m_ptMouseDown.x);
+ long lOldTime = pTrackListFrame->XtoTime (m_ptMouseMove.x);
+ long lNewTime = pTrackListFrame->XtoTime (point.x);
+ CRect rcRegion;
+
+ // キャプター中ならば
+ if (GetCapture () == this) {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ MIDITrack* pTempTrack = NULL;
+ MIDIEvent* pTempEvent = NULL;
+ MIDITrack* pNewTrack = NULL;
+ MIDIEvent* pNewEvent = NULL;
+ // ツール別の操作
+ switch (m_lTempTool) {
+ // 選択
+ case ID_TRACKLIST_SELECT:
+ // 移動又はコピー中
+ if (m_lTempMode == 0x0402 || m_lTempMode == 0x0403) {
+ long j;
+ long lDownMeasure, lDownBeat, lDownTick;
+ long lOldMeasure, lOldBeat, lOldTick;
+ long lNewMeasure, lNewBeat, lNewTick;
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lDownMeasure, &lDownBeat, &lDownTick);
+ MIDIData_BreakTime (pMIDIData, lOldTime, &lOldMeasure, &lOldBeat, &lOldTick);
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ // トラックが変更された場合
+ if (lOldTrackIndex != lNewTrackIndex) {
+ CHistoryUnit* pCurHistoryUnit = NULL;
+ VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ());
+ long lTimeResolution = MIDIData_GetTimeResolution (pMIDIData);
+ long lDeltaTrackIndex = lNewTrackIndex - lDownTrackIndex;
+ long lSelectedEventCount = m_theTempSelectedEventArray.GetSize ();
+ for (j = 0; j < lSelectedEventCount; j++) {
+ pTempEvent = (MIDIEvent*)m_theTempSelectedEventArray.GetAt (j);
+ pTempTrack = MIDIEvent_GetParent (pTempEvent);
+ if (pTempTrack != MIDIData_GetFirstTrack (pMIDIData) &&
+ pTempEvent->m_pPrevCombinedEvent == NULL &&
+ !(MIDIEvent_IsEndofTrack (pTempEvent) &&
+ MIDITrack_GetLastEvent (pTempTrack) == pTempEvent)) {
+ long lTempTrackIndex = pTempEvent->m_lUser1;
+ long lTargetTrackIndex = lTempTrackIndex + lDeltaTrackIndex;
+ lTargetTrackIndex = CLIP (1, lTargetTrackIndex, (MAXMIDITRACKNUM - 1));
+ MIDITrack* pTargetTrack = pSekaijuDoc->GetTrack (lTargetTrackIndex);
+ // トラックが足りない場合はトラックを追加する
+ //pSekaijuDoc->AddTrack (lTargetTrackIndex, 0x0007, pHistoryUnit);
+ long lTrackCount = MIDIData_CountTrack (pMIDIData);
+ long i;
+ for (i = lTrackCount; i <= lTargetTrackIndex; i++) {
+ VERIFY (pNewTrack = MIDITrack_Create ());
+ VERIFY (MIDITrack_SetForeColor (pNewTrack, pSekaijuApp->m_theColorOption.m_lForeColor[i % 8]));
+ VERIFY (MIDITrack_SetInputOn (pNewTrack, TRUE));
+ VERIFY (MIDITrack_SetInputChannel (pNewTrack, (i + 15) % 16));
+ VERIFY (MIDITrack_SetOutputOn (pNewTrack, TRUE));
+ VERIFY (MIDITrack_SetOutputChannel (pNewTrack, (i + 15) % 16));
+ VERIFY (MIDIData_AddTrack (pMIDIData, pNewTrack));
+ VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTTRACK, pNewTrack));
+ VERIFY (pNewEvent = MIDIEvent_CreateEndofTrack (lTimeResolution * 4));
+ VERIFY (MIDITrack_InsertEvent (pNewTrack, pNewEvent));
+ //pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_INSERTEVENT, pNewEvent);
+ // EOTが挿入されたことはここでは履歴登録せず、LButtonUp時に登録する。
+ //pTargetTrack = pSekaijuDoc->GetTrack (lTargetTrackIndex);
+ }
+ ASSERT (pTempTrack);
+ VERIFY (pTargetTrack = pSekaijuDoc->GetTrack (lTargetTrackIndex));
+ VERIFY (MIDITrack_RemoveEvent (pTempTrack, pTempEvent));
+ VERIFY (MIDITrack_InsertEvent (pTargetTrack, pTempEvent));
+ // 注意: EndofTrackイベントはRemoveすることはできるが,二重にInsertすることはできない。
+ // TODO: EndofTrackイベントの親トラックがなくなってしまうバグがまだあり。
+ }
+ }
+ Invalidate ();
+ }
+
+ // 小節が変更された場合
+ if (lOldMeasure != lNewMeasure) {
+ long lDownTime0 = 0;
+ long lNewTime0 = 0;
+ MIDIData_MakeTime (pMIDIData, lDownMeasure, 0, 0, &lDownTime0);
+ MIDIData_MakeTime (pMIDIData, lNewMeasure, 0, 0, &lNewTime0);
+ long lDeltaTime = lNewTime0 - lDownTime0;
+ long lSelectedEventCount = m_theTempSelectedEventArray.GetSize ();
+ for (j = 0; j < lSelectedEventCount; j++) {
+ pTempEvent = (MIDIEvent*)m_theTempSelectedEventArray.GetAt (j);
+ if (pTempEvent->m_pPrevCombinedEvent == NULL) {
+ long lTempTime = pTempEvent->m_lUser2;
+ long lTargetTime = lTempTime + lDeltaTime;
+ lTargetTime = CLIP (0, lTargetTime, 0x7FFFFFFF);
+ MIDIEvent_SetTime (pTempEvent, lTargetTime);
+ }
+ }
+ Invalidate ();
+ }
+ }
+
+ // 選択範囲変更中
+ else if (m_lTempMode == 0x0401) {
+ long lMinTime, lMinMeasure, lMinBeat, lMinTick;
+ long lMaxTime, lMaxMeasure, lMaxBeat, lMaxTick;
+ long lMinTrackIndex;
+ long lMaxTrackIndex;
+
+ // 古い選択範囲矩形を消す
+ lMinTrackIndex = __min (lDownTrackIndex, lOldTrackIndex);
+ lMaxTrackIndex = __max (lDownTrackIndex, lOldTrackIndex);
+ m_lMinY = pTrackListFrame->RowtoY (lMinTrackIndex);
+ m_lMaxY = pTrackListFrame->RowtoY (lMaxTrackIndex + 1);
+ if (lDownTime < lOldTime) {
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lMinMeasure, &lMinBeat, &lMinTick);
+ MIDIData_MakeTime (pMIDIData, lMinMeasure, 0, 0, &lMinTime);
+ MIDIData_BreakTime (pMIDIData, lOldTime, &lMaxMeasure, &lMaxBeat, &lMaxTick);
+ MIDIData_MakeTime (pMIDIData, lMaxMeasure + 1, 0, 0, &lMaxTime);
+ }
+ else {
+ MIDIData_BreakTime (pMIDIData, lOldTime, &lMinMeasure, &lMinBeat, &lMinTick);
+ MIDIData_MakeTime (pMIDIData, lMinMeasure, 0, 0, &lMinTime);
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lMaxMeasure, &lMaxBeat, &lMaxTick);
+ MIDIData_MakeTime (pMIDIData, lMaxMeasure + 1, 0, 0, &lMaxTime);
+ }
+ m_lMinX = pTrackListFrame->TimetoX (lMinTime);
+ m_lMaxX = pTrackListFrame->TimetoX (lMaxTime);
+ rcRegion = CRect (m_lMinX, m_lMinY, m_lMaxX, m_lMinY);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_lMinX, m_lMaxY, m_lMaxX, m_lMaxY);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_lMinX, m_lMinY, m_lMinX, m_lMaxX);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_lMaxX, m_lMinY, m_lMaxX, m_lMaxY);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+
+
+ // 新しい選択範囲矩形を描画する
+ lMinTrackIndex = __min (lDownTrackIndex, lNewTrackIndex);
+ lMaxTrackIndex = __max (lDownTrackIndex, lNewTrackIndex);
+ m_lMinY = pTrackListFrame->RowtoY (lMinTrackIndex);
+ m_lMaxY = pTrackListFrame->RowtoY (lMaxTrackIndex + 1);
+ if (lDownTime < lNewTime) {
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lMinMeasure, &lMinBeat, &lMinTick);
+ MIDIData_MakeTime (pMIDIData, lMinMeasure, 0, 0, &lMinTime);
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lMaxMeasure, &lMaxBeat, &lMaxTick);
+ MIDIData_MakeTime (pMIDIData, lMaxMeasure + 1, 0, 0, &lMaxTime);
+ }
+ else {
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lMinMeasure, &lMinBeat, &lMinTick);
+ MIDIData_MakeTime (pMIDIData, lMinMeasure, 0, 0, &lMinTime);
+ MIDIData_BreakTime (pMIDIData, lDownTime, &lMaxMeasure, &lMaxBeat, &lMaxTick);
+ MIDIData_MakeTime (pMIDIData, lMaxMeasure + 1, 0, 0, &lMaxTime);
+ }
+ m_lMinX = pTrackListFrame->TimetoX (lMinTime);
+ m_lMaxX = pTrackListFrame->TimetoX (lMaxTime);
+ rcRegion = CRect (m_lMinX, m_lMinY, m_lMaxX, m_lMinY);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_lMinX, m_lMaxY, m_lMaxX, m_lMaxY);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_lMinX, m_lMinY, m_lMinX, m_lMaxX);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ rcRegion = CRect (m_lMaxX, m_lMinY, m_lMaxX, m_lMaxY);
+ rcRegion.NormalizeRect ();
+ rcRegion.InflateRect (1, 1);
+ InvalidateRect (rcRegion - sizWndOrg);
+ }
+
+ break;
+
+ // スクラブ
+ case ID_TRACKLIST_SPEAKER:
+ m_lTempTime = pTrackListFrame->XtoTime (point.x);
+ pSekaijuApp->SetPlayPosition (pSekaijuDoc, m_lTempTime);
+ pSekaijuApp->SendDifferentStatus (SDS_ALL);
+ break;
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ // 非キャプター中
+ else {
+
+ // ツール別の操作
+ switch (pTrackListFrame->m_lCurTool) {
+ // 選択
+ case ID_TRACKLIST_SELECT:
+ {
+ pSekaijuDoc->m_theCriticalSection.Lock ();
+ MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData;
+ long lNewMeasure, lNewBeat, lNewTick;
+ long lOldMeasure, lOldBeat, lOldTick;
+ MIDIData_BreakTime (pMIDIData, lNewTime, &lNewMeasure, &lNewBeat, &lNewTick);
+ MIDIData_BreakTime (pMIDIData, lOldTime, &lOldMeasure, &lOldBeat, &lOldTick);
+ MIDITrack* pMIDITrack = pSekaijuDoc->GetTrack (lNewTrackIndex);
+ if (pMIDITrack) {
+ if (pSekaijuDoc->IsTrackMeasureSelected (pMIDITrack, lNewMeasure) >= 2) { // 20100517新規修正
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAllCopy);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSizeAll);
+ }
+ }
+ else {
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSelectAdd2);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSelect2);
+ }
+ }
+ }
+ else {
+ if (nFlags & MK_CONTROL) {
+ ::SetCursor (pSekaijuApp->m_hCursorSelectAdd2);
+ }
+ else {
+ ::SetCursor (pSekaijuApp->m_hCursorSelect2);
+ }
+ }
+ pSekaijuDoc->m_theCriticalSection.Unlock ();
+ ::Sleep (0);
+ }
+ break;
+ case ID_TRACKLIST_SPEAKER:
+ ::SetCursor (pSekaijuApp->m_hCursorSpeaker);
+ break;
+ }
+ }
+ m_ptMouseMove = point;
+ m_nMouseMoveFlags = nFlags;
+}
+
+
+// マウスホイールが回された時
+void CTrackListTrackTimeView::OnMouseWheel40 (UINT nFlags, CPoint point) {
+ CTrackListFrame* pTrackListFrame = (CTrackListFrame*)GetParent ();
+ CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp ();
+ CSekaijuDoc* pSekaijuDoc = GetDocument ();
+ long lDelta = (short)HIWORD (nFlags);
+ long lFlags = LOWORD (nFlags);
+ if (lFlags & MK_CONTROL) {
+ if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 ||
+ lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE);
+ }
+ else {
+ pTrackListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE);
+ }
+ }
+ else {
+ long lRowScrollPos = pTrackListFrame->GetRowScrollPos ();
+ long lRowZoom = pTrackListFrame->GetRowZoom ();
+ lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA;
+ pTrackListFrame->SetRowScrollPos (lRowScrollPos);
+ }
+
+}
+
diff --git a/src/TrackListTrackTimeView.h b/src/TrackListTrackTimeView.h
new file mode 100644
index 0000000..242c35e
--- /dev/null
+++ b/src/TrackListTrackTimeView.h
@@ -0,0 +1,96 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// トラックリストトラックタイムビュークラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _TRACKLISTTRACKTIMEVIEW_H_
+#define _TRACKLISTTRACKTIMEVIEW_H_
+
+class CTrackListTrackTimeView : public CSekaijuView {
+
+ DECLARE_DYNCREATE (CTrackListTrackTimeView)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CTrackListTrackTimeView (); // コンストラクタ
+ virtual ~CTrackListTrackTimeView (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ long m_lCurTime; // 現在の描画タイム[tick]
+ long m_lOldTime; // 前回の描画タイム[tick]
+ long m_lOldX; // 前回の縦線x座標[pixel]
+ long m_lOldY1; // 前回の縦線y上座標[pixel]
+ long m_lOldY2; // 前回の縦線y下座標[pixel]
+ BOOL m_bOldDraw; // 前回縦線を描画したか?
+ CPoint m_ptMouseDown; // マウスが押されたときの座標
+ CPoint m_ptMouseMove; // マウスが動かされたときの前回の座標
+ int m_nMouseDownFlags; // マウスが押されたときのフラグ
+ int m_nMouseMoveFlags; // マウスが動かされたときの前回のフラグ
+ long m_lTempMode; // 一時的なモード
+ long m_lTempTool; // 一時的なツール(0〜)
+ long m_lTempTime; // 一時的なタイム(0〜)[tick]
+ long m_lTempTrackIndex; // 一時的なトラック番号(0〜65535)
+ long m_lMinX;
+ long m_lMaxX;
+ long m_lMinY;
+ long m_lMaxY;
+ CPtrArray m_theTempSelectedEventArray;
+ CPtrArray m_theTempEndofTrackEventArray;
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+protected:
+ virtual void EraseOldLine (CDC* pDC);
+ virtual void DrawCurLine (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnDraw (CDC* pDC);
+ virtual void OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint);
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ DECLARE_MESSAGE_MAP ()
+};
+
+
+
+#endif
diff --git a/src/childframe.h b/src/childframe.h
new file mode 100644
index 0000000..63f23e3
--- /dev/null
+++ b/src/childframe.h
@@ -0,0 +1,56 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MDI子フレームウィンドウクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _CHILDFRAME_H_
+#define _CHILDFRAME_H_
+
+class CChildFrame : public CMDIChildWnd {
+ DECLARE_DYNCREATE (CChildFrame)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CChildFrame (); // コンストラクタ
+ virtual ~CChildFrame (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ CDocument* GetDocument (); // ドキュメントへのポインタ取得
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void PostNcDestroy ();
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+ afx_msg void OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd);
+
+};
+
+#endif
+
diff --git a/src/colorfulchecklistbox.h b/src/colorfulchecklistbox.h
new file mode 100644
index 0000000..3d3e5ab
--- /dev/null
+++ b/src/colorfulchecklistbox.h
@@ -0,0 +1,58 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// カラフルなチェックリストボックスクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _COLORFULCHECKLISTBOX_H_
+#define _COLORFULCHECKLISTBOX_H_
+
+class CColorfulCheckListBox : public CCheckListBox {
+ DECLARE_DYNCREATE (CColorfulCheckListBox)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CColorfulCheckListBox (); // コンストラクタ
+ virtual ~CColorfulCheckListBox (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ int AddItem (LPCTSTR lpszText, COLORREF lForeColor, COLORREF lBackColor);
+ void RemoveAllItem ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+ virtual void MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct);
+ virtual void DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnDestroy ();
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/common.h b/src/common.h
new file mode 100644
index 0000000..95c5fcd
--- /dev/null
+++ b/src/common.h
@@ -0,0 +1,57 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 共用ルーチン
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CLIP
+#define CLIP(A,B,C) ((B)<(A)?(A):((B)>(C)?(C):(B)))
+#endif
+
+// 数字として認識できる文字列か調べる(戻り値:認識できた数字の文字数)
+long IsNumeric (const TCHAR* pszText);
+
+/* 16進法で使用可能な文字なら1を、そうでなければ0を返す */
+long IsHexDigit (TCHAR c);
+
+/* バイナリ配列を16進テキスト文字列(半角スペース区切り)に変換する */
+long bin2txt (BYTE* pBin, long lBinLen, TCHAR* pszText, long lTextLen);
+
+/* 16進テキスト文字列(半角スペース区切り)をバイナリ配列に変換する */
+long txt2bin (TCHAR* pszText, long lTextLen, BYTE* pBin, long lBinLen);
+
+/* '\t''\r''\n''\\'コード入りの文字列をコード無しの文字列(C言語スタイル)に変換する */
+/* 戻り値:出来上がった文字列のバイト数 */
+long codestr2str (TCHAR* pszCodeStr, long lCodeStrLen, TCHAR* pszStr, long lStrLen);
+
+/* コード無しの文字列(C言語スタイル)を'\t''\r''\n''\\'コード入りの文字列に変換する */
+/* 戻り値:出来上がった文字列のバイト数 */
+long str2codestr (TCHAR* pszStr, long lStrLen, TCHAR* pszCodeStr, long lCodeStrLen);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/eventlistframe.h b/src/eventlistframe.h
new file mode 100644
index 0000000..8f9ef79
--- /dev/null
+++ b/src/eventlistframe.h
@@ -0,0 +1,221 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// イベントリストフレームウィンドウクラス
+// (C)2002-2012 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _EVENTLISTFRAME_H_
+#define _EVENTLISTFRAME_H_
+
+class CEventListFrame : public CChildFrame {
+ DECLARE_DYNCREATE (CEventListFrame)
+
+ //--------------------------------------------------------------------------
+ // アトリビュート
+ //--------------------------------------------------------------------------
+protected:
+ long m_lToolBar1Height; // ツールバーの高さ[pixel]
+ long m_lScaleHeight; // 項目目盛りビューの高さ[pixel]
+ long m_lIndexHeight; // イベント番号-項目ビューの高さ[pixel]
+ long m_lScaleWidth; // イベント番号目盛りビューの幅[pixel]
+ long m_lPropertyWidth; // イベント番号-項目ビューの幅[pixel]
+ long m_lTrackListWidth; // トラックリストボックスの幅[pixel]
+ long m_lTrackListHeight; // トラックリストボックスの高さ[pixel]
+ long m_lEventKindListHeight; // イベントの種類リストボックスの高さ[pixel]
+ long m_lHScrollBarHeight; // 水平スクロールバーの高さ[pixel]
+ long m_lVScrollBarWidth; // 垂直スクロールバーの幅[pixel]
+ long m_lRowZoom; // 行方向ズーム倍率[倍]
+ long m_lColumnZoom; // 列方向ズーム倍率[倍]
+ long m_lRowScrollPos; // 行方向スクロール位置[pixel]
+ long m_lColumnScrollPos; // 列方向スクロール位置[pixel]
+
+public:
+ CSekaijuToolBar m_wndToolBar1; // ツールバー
+ CColorfulComboBox m_wndEventTrackCombo; // ツールバー上のイベントのトラック番号コンボボックス
+ CEdit m_wndEventTimeEdit; // ツールバー上のイベントのタイムエディットボックス
+ CComboBox m_wndEventKindCombo; // ツールバー上のイベントの種類コンボボックス
+ CComboBox m_wndEventChannelCombo; // ツールバー上のイベントのチャンネルコンボボックス
+ CView* m_pDummyView; // ダミービュー(Visible=FALSE)へのポインタ
+ CView* m_pPrintView; // 印刷用ビュー(Visible=FALSE)へのポインタ
+ CView* m_pScaleView; // 目盛りビューへのポインタ
+ CView* m_pPropertyScaleView; // 項目目盛りビューへのポインタ
+ CView* m_pIndexScaleView; // イベント番号目盛りビューへのポインタ
+ CView* m_pIndexPropertyView; // イベント番号-項目ビューへのポインタ
+ CCheckListBox* m_pTrackListBox; // トラックリストボックスへのポインタ
+ CCheckListBox* m_pEventKindListBox; // イベントの種類リストボックスへのポインタ
+ CScrollBar m_wndColumnScroll; // 列方向スクロールバー
+ CScrollBar m_wndRowScroll; // 行方向スクロールバー
+ CScrollBar m_wndSizeScroll; // サイズスクロールバー
+ CBitmapButton m_wndColumnZoomUp; // 列方向拡大ボタン
+ CBitmapButton m_wndColumnZoomDown; // 列方向縮小ボタン
+ CBitmapButton m_wndRowZoomUp; // 行方向拡大ボタン
+ CBitmapButton m_wndRowZoomDown; // 行方向縮小ボタン
+
+public:
+ BOOL m_bAutoPageUpdate; // 自動的にページを更新するか?
+
+protected:
+ CPoint m_ptMouseDown; // マウスが押されたときの座標(スプリッターを動かすのに使う)
+ CPoint m_ptMouseMoveOld; // マウスが動かされたときの前回の座標(スプリッターを動かすのに使う)
+ BOOL m_bSplitterMovingH; // 現在水平スプリッターを動かしているところか?
+ BOOL m_bSplitterMovingV; // 現在垂直スプリッターを動かしているところか?
+ CPtrArray m_theVisibleEventArray; // 表示させるイベントへのポインタの配列
+ CFont m_theFont; // イベントリストウィンドウで使うフォント
+ long m_lColumnBaseWidth[8]; // 各列の幅[pixel]
+ CString m_strColumnTitle[8]; // 各列のタイトル文字列(例:"トラック", "時:分:秒:ミリ秒"...)
+
+protected:
+ BOOL m_bOnlyCurTrack; // 現在のトラックのみを表示するか?
+ BOOL m_bShowAllTrack; // すべてのトラックを表示するか?
+ BOOL m_bTrackVisible[MAXMIDITRACKNUM]; // 各々のトラック[0〜65525]は可視か?
+ BOOL m_bOnlyCurEventKind; // 現在のイベントの種類のみを表示するか?
+ BOOL m_bShowAllEventKind; // すべてのイベントの種類を表示するか?
+ BOOL m_bEventKindVisible[256]; // 各々のイベントの種類[0〜255]は可視か?
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CEventListFrame (); // コンストラクタ
+ virtual ~CEventListFrame (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ virtual CSekaijuDoc* GetDocument ();
+ virtual CFont* GetParentFont ();
+ virtual long GetVisibleTopRow ();
+ virtual long GetVisibleBottomRow ();
+ virtual long GetColumnBaseWidth (long lColumn);
+ virtual long SetColumnBaseWidth (long lColumn, long lBaseWidth);
+ virtual CString GetColumnTitle (long lColumn);
+ virtual long SetColumnTitle (long lColumn, const TCHAR* pszColumnTitle);
+ virtual long GetColumnLeft (long lColumn);
+ virtual long GetColumnWidth (long lColumn);
+ virtual long XtoColumn (long x);
+ virtual long ColumntoX (long lColumn);
+ virtual long YtoRow (long y);
+ virtual long RowtoY (long lRow);
+ virtual long GetColumnZoom ();
+ virtual long GetRowZoom ();
+ virtual long GetColumnScrollPos ();
+ virtual long GetRowScrollPos ();
+ virtual long SetColumnScrollPos (long lColumnScrollPos);
+ virtual long SetRowScrollPos (long lRowScrollPos);
+ virtual long GetVisibleEventCount ();
+ virtual MIDIEvent* GetVisibleEvent (long lIndex);
+ virtual void DrawSplitterCaptor (CDC* pDC, CPoint pt);
+ virtual BOOL MakeVisibleEventArray ();
+ virtual BOOL ReplaceVisibleEvent (MIDIEvent* pOldEvent, MIDIEvent* pNewEvent);
+ virtual long GetCurTrackIndex ();
+ virtual long GetCurEventKind ();
+ virtual BOOL SetCurTrackIndex (long lCurTrackIndex);
+ virtual BOOL SetCurEventKind (long lCurEventKind);
+ virtual BOOL SetCurChannel (long lCurChannel);
+ virtual BOOL IsTrackVisible (long lTrackIndex);
+ virtual BOOL SetTrackVisible (long lTrackIndex);
+ virtual BOOL IsEventKindVisible (long lEventKind);
+ virtual BOOL SetEventKindVisible (long lEventKind);
+ virtual BOOL UpdateTrackCombo ();
+ virtual BOOL UpdateTrackList ();
+ virtual long EventKindtoListIndex (long lEventKind);
+ virtual long ListIndextoEventKind (long lListIndex);
+ virtual void RecalcRowScrollInfo ();
+ virtual void RecalcColumnScrollInfo ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+ virtual void OnUpdateFrameTitle (BOOL bAddToTitle);
+ virtual void RecalcLayout (BOOL bNotify = TRUE);
+ virtual BOOL OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ virtual BOOL OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnSize (UINT nType, int cx, int cy);
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg BOOL OnEraseBkgnd (CDC* pDC);
+ afx_msg void OnMDIActivate (BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd);
+ afx_msg void OnClose ();
+ afx_msg void OnPaint();
+ afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonDown (UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnRButtonUp (UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove (UINT nFlags, CPoint point);
+ afx_msg void OnColumnZoomDown ();
+ afx_msg void OnColumnZoomUp ();
+ afx_msg void OnRowZoomDown ();
+ afx_msg void OnRowZoomUp ();
+ afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+
+
+ afx_msg void OnEventListInsertEvent ();
+ afx_msg void OnUpdateEventListInsertEventUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListDuplicateEvent ();
+ afx_msg void OnUpdateEventListDuplicateEventUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListDeleteEvent ();
+ afx_msg void OnUpdateEventListDeleteEventUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListOnlyCurTrack ();
+ afx_msg void OnUpdateEventListOnlyCurTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListShowAllTrack ();
+ afx_msg void OnUpdateEventListShowAllTrackUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListOnlyCurEventKind ();
+ afx_msg void OnUpdateEventListOnlyCurEventKindUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListShowAllEventKind ();
+ afx_msg void OnUpdateEventListShowAllEventKindUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListAutoPageUpdate ();
+ afx_msg void OnUpdateEventListAutoPageUpdateUI (CCmdUI* pCmdUI);
+ afx_msg void OnEventListSaveAs ();
+ afx_msg void OnUpdateEventListSaveAsUI (CCmdUI* pCmdUI);
+
+ afx_msg void OnTrackComboSelEndOK ();
+ afx_msg void OnTrackListChkChange ();
+ afx_msg void OnTrackListSelChange ();
+
+ afx_msg void OnEventKindComboSelEndOK ();
+ afx_msg void OnEventKindListChkChange ();
+ afx_msg void OnEventKindListSelChange ();
+
+ afx_msg void OnPopupTrackVisibleOn ();
+ afx_msg void OnUpdatePopupTrackVisibleOnUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupTrackVisibleOff ();
+ afx_msg void OnUpdatePopupTrackVisibleOffUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupTrackVisibleAll ();
+ afx_msg void OnUpdatePopupTrackVisibleAllUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupEventKindVisibleOn ();
+ afx_msg void OnUpdatePopupEventKindVisibleOnUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupEventKindVisibleOff ();
+ afx_msg void OnUpdatePopupEventKindVisibleOffUI (CCmdUI* pCmdUI); // 20100429追加
+ afx_msg void OnPopupEventKindVisibleAll ();
+ afx_msg void OnUpdatePopupEventKindVisibleAllUI (CCmdUI* pCmdUI); // 20100429追加
+
+ DECLARE_MESSAGE_MAP()
+};
+
+#endif
+
diff --git a/src/mainframe.h b/src/mainframe.h
new file mode 100644
index 0000000..a8a9fe2
--- /dev/null
+++ b/src/mainframe.h
@@ -0,0 +1,97 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// MDI親フレームウィンドウクラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MAINFRAME_H_
+#define _MAINFRAME_H_
+
+class CMainFrame : public CMDIFrameWnd {
+ DECLARE_DYNAMIC (CMainFrame)
+
+ //--------------------------------------------------------------------------
+ // メンバ変数
+ //--------------------------------------------------------------------------
+public:
+ CString m_strWndClass; // ウィンドウクラス名
+ CString m_strTempFileName; // 一時的なファイル名格納場所
+
+ //--------------------------------------------------------------------------
+ // ツールバーとステータスバーとその内部のウィンドウ
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuStatusBar m_wndStatusBar; // ステータスバー
+ CSekaijuToolBar m_wndToolBar1; // ツールバー1
+ CSekaijuToolBar m_wndToolBar2; // ツールバー2
+ CEdit m_wndMillisecEdit; // 時:分:秒:ミリ秒用エディット(読み取り専用)
+ CEdit m_wndTimeEdit; // 小節:拍:ティックorフレーム:サブフレーム用エディット(読み取り専用)
+ CScrollBar m_wndPositionScroll; // 位置スクロールバー
+ CEdit m_wndMeasureEdit; // 拍子記号・調性記号用エディット(読み取り専用)
+ CEdit m_wndTempoEdit; // テンポ用エディット(読み取り専用)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CMainFrame (); // コンストラクタ
+ virtual ~CMainFrame(); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ void SetPositionScrollRange (long lStartTime, long lEndTime, BOOL bRedraw);
+ int SetWindowTextWhenDifferent (CWnd* pWnd, LPCTSTR lpszText);
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+public:
+ virtual CFrameWnd* GetActiveFrame ();
+protected:
+ virtual BOOL PreCreateWindow (CREATESTRUCT& cs);
+
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
+ afx_msg void OnDestroy ();
+ afx_msg void OnTimer (UINT nIDEvent);
+ afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnMouseWheel40 (UINT nFlags, CPoint point);
+ afx_msg void OnViewToolbar1 ();
+ afx_msg void OnUpdateViewToolbar1UI (CCmdUI* pCmdUI);
+ afx_msg void OnViewToolbar2 ();
+ afx_msg void OnUpdateViewToolbar2UI (CCmdUI* pCmdUI);
+ afx_msg void OnUpdateIndicatorInputVelocityUI (CCmdUI* pCmdUI);
+ afx_msg void OnUpdateIndicatorOutputVelocityUI (CCmdUI* pCmdUI);
+ afx_msg void OnUpdateIndicatorFormatUI (CCmdUI* pCmdUI);
+ afx_msg void OnUpdateIndicatorNumTracksUI (CCmdUI* pCmdUI);
+ afx_msg void OnUpdateIndicatorTimeBaseUI (CCmdUI* pCmdUI);
+
+ afx_msg long OnCommandWakeUp (WPARAM wParam, LPARAM lParam);
+ afx_msg long OnCommandReadShm (WPARAM wParam, LPARAM lParam);
+ afx_msg long OnCommandFileOpen (WPARAM wParam, LPARAM lParam);
+
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/mousewheel.h b/src/mousewheel.h
new file mode 100644
index 0000000..1e2dedc
--- /dev/null
+++ b/src/mousewheel.h
@@ -0,0 +1,38 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// マウスホイール対応ヘッダーファイル(VisualC++4.0用)
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _MOUSEWHEEL_H_
+#define _MOUSEWHEEL_H_
+
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x020A
+#endif
+
+#ifndef WHEELDELTA
+#define WHEELDELTA 120
+#endif
+
+#ifndef ON_WM_MOUSEWHEEL40
+#define ON_WM_MOUSEWHEEL40() \
+ { WM_MOUSEWHEEL, 0, 0, 0, AfxSig_vwp, \
+ (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))OnMouseWheel40 },
+#endif
+
+#endif
diff --git a/src/sekaijustatusbar.h b/src/sekaijustatusbar.h
new file mode 100644
index 0000000..dce0565
--- /dev/null
+++ b/src/sekaijustatusbar.h
@@ -0,0 +1,52 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ステータスバークラス
+// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _SEKAIJUSTATUSBAR_H_
+#define _SEKAIJUSTATUSBAR_H_
+
+
+class CSekaijuStatusBar : public CStatusBar {
+ DECLARE_DYNAMIC (CSekaijuStatusBar)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuStatusBar (); // コンストラクタ
+ virtual ~CSekaijuStatusBar (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ DECLARE_MESSAGE_MAP ()
+ afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
+};
+
+#endif
diff --git a/src/sekaijutoolbar.h b/src/sekaijutoolbar.h
new file mode 100644
index 0000000..69933f9
--- /dev/null
+++ b/src/sekaijutoolbar.h
@@ -0,0 +1,58 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// 世界樹ファイルダイアログクラス
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+#ifndef _SEKAIJUTOOLBAR_H_
+#define _SEKAIJUTOOLBAR_H_
+
+
+class CSekaijuToolBar : public CToolBar {
+ DECLARE_DYNAMIC (CSekaijuToolBar)
+
+ //--------------------------------------------------------------------------
+ // 構築と破壊
+ //--------------------------------------------------------------------------
+public:
+ CSekaijuToolBar (); // コンストラクタ
+ virtual ~CSekaijuToolBar (); // デストラクタ
+
+ //--------------------------------------------------------------------------
+ // オペレーション
+ //--------------------------------------------------------------------------
+public:
+ void DrawGripper (CDC* pDC, const CRect& rect);
+ void EraseNonClient ();
+
+ //--------------------------------------------------------------------------
+ // オーバーライド
+ //--------------------------------------------------------------------------
+protected:
+ virtual void DoPaint (CDC* pDC);
+
+ //--------------------------------------------------------------------------
+ // メッセージマップ
+ //--------------------------------------------------------------------------
+protected:
+ afx_msg void OnNcPaint ();
+ afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ DECLARE_MESSAGE_MAP ()
+
+};
+
+#endif
diff --git a/src/winver.h b/src/winver.h
new file mode 100644
index 0000000..606a202
--- /dev/null
+++ b/src/winver.h
@@ -0,0 +1,30 @@
+//******************************************************************************
+// MIDIシーケンサーソフト『世界樹』
+// Windowsヴァージョン定義ヘッダーファイル(VisualC++4.0用)
+// (C)2002-2010 おーぷんMIDIぷろじぇくと/くず
+//******************************************************************************
+
+/* 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 */
+
+
+#ifndef _WINVER_H_
+#define _WINVER_H_
+
+#define WINVER 0x0400 // Windows95 or later
+#define _WIN32_WINNT 0x0400
+#define _WIN32_WINDOWS 0x0400
+#define _WIN32_IE 0x0400
+
+#endif