diff options
Diffstat (limited to 'src/PianoRollPrintView.cpp')
-rw-r--r-- | src/PianoRollPrintView.cpp | 1075 |
1 files changed, 1075 insertions, 0 deletions
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) {
+}
+
+//------------------------------------------------------------------------------
+// メッセージマップ
+//------------------------------------------------------------------------------
+
|