//--------------------------------------------------------------------------- #pragma hdrstop #include "KeyBoard.h" //--------------------------------------------------------------------------- #pragma package(smart_init) __fastcall TKeyBoard::TKeyBoard(TComponent* Owner) : Vcl::Extctrls::TPanel(Owner) { Height = 145; Width = 430; Left = 150; Top = 500; m_pBmpWhiteDDown = new TBitmap(); m_pBmpWhiteDDown->LoadFromResourceName(int(HInstance), "KBWhiteDDown"); m_pBmpWhiteLDown = new TBitmap(); m_pBmpWhiteLDown->LoadFromResourceName(int(HInstance), "KBWhiteLDown"); m_pBmpWhiteRDown = new TBitmap(); m_pBmpWhiteRDown->LoadFromResourceName(int(HInstance), "KBWhiteRDown"); m_pBmpBlackDown = new TBitmap(); m_pBmpBlackDown->LoadFromResourceName(int(HInstance), "KBBlackDown"); m_nBlackWidth = m_pBmpBlackDown->Width; m_nBlackHeight = m_pBmpBlackDown->Height; m_nWhiteWidth = m_pBmpWhiteDDown->Width; m_nGroupWidth = m_nWhiteWidth * 7; m_aBlackHitTest[0].x1 = 12; m_aBlackHitTest[0].iKey = 1; m_aBlackHitTest[1].x1 = 32; m_aBlackHitTest[1].iKey = 3; m_aBlackHitTest[2].x1 = 72; m_aBlackHitTest[2].iKey = 6; m_aBlackHitTest[3].x1 = 92; m_aBlackHitTest[3].iKey = 8; m_aBlackHitTest[4].x1 = 112; m_aBlackHitTest[4].iKey = 10; for (int i = 0; i < 5; i++) m_aBlackHitTest[i].x2 = m_aBlackHitTest[i].x1 + m_pBmpBlackDown->Width; m_aKey[0].xPos = -1; m_aKey[0].pBmp = m_pBmpWhiteRDown; m_aKey[1].xPos = 12; m_aKey[1].pBmp = m_pBmpBlackDown; m_aKey[2].xPos = 19; m_aKey[2].pBmp = m_pBmpWhiteDDown; m_aKey[3].xPos = 32; m_aKey[3].pBmp = m_pBmpBlackDown; m_aKey[4].xPos = 39; m_aKey[4].pBmp = m_pBmpWhiteLDown; m_aKey[5].xPos = 59; m_aKey[5].pBmp = m_pBmpWhiteRDown; m_aKey[6].xPos = 72; m_aKey[6].pBmp = m_pBmpBlackDown; m_aKey[7].xPos = 79; m_aKey[7].pBmp = m_pBmpWhiteDDown; m_aKey[8].xPos = 92; m_aKey[8].pBmp = m_pBmpBlackDown; m_aKey[9].xPos = 99; m_aKey[9].pBmp = m_pBmpWhiteDDown; m_aKey[10].xPos = 112; m_aKey[10].pBmp = m_pBmpBlackDown; m_aKey[11].xPos = 119; m_aKey[11].pBmp = m_pBmpWhiteLDown; m_iPressGroup = m_iPressKey = -1; //背景 m_ImgBrk = new TPngImage(); m_ImgBrk->LoadFromResourceName(int(HInstance), "KeyBoard"); m_imgKeyboard = new TImage(this); m_imgKeyboard->Parent = this; m_imgKeyboard->Picture->Assign(m_ImgBrk); m_imgKeyboard->Left = 0; m_imgKeyboard->Top = 0; m_imgKeyboard->Width = Width; m_imgKeyboard->Height = Height; m_imgKeyboard->Visible = true; //PaintBox m_pbKeyboard = new TPaintBox(this); m_pbKeyboard->Parent = this; m_pbKeyboard->Left = 6; m_pbKeyboard->Top = 19; // Will be Change! m_pbKeyboard->Width = 420; m_pbKeyboard->Height = 121; m_pbKeyboard->OnPaint = KeyboardPaint; m_pbKeyboard->OnMouseDown = KeyboardMouseDown; m_pbKeyboard->OnMouseEnter = KeyboardMouseEnter; m_pbKeyboard->OnMouseLeave = KeyboardMouseLeave; m_pbKeyboard->OnMouseMove = KeyboardMouseMove; m_pbKeyboard->OnMouseUp = KeyboardMouseUp; m_pbKeyboard->Visible = true; //PNG Close m_ImgClose = new TPngImage(); m_ImgClose->LoadFromResourceName(int(HInstance), "imgClose"); m_PngClose = new TPNGButton(this); m_PngClose->Parent = this; m_PngClose->OnClick = CloseClick; m_PngClose->ImgStates = 3; m_PngClose->PngImg = m_ImgClose; m_PngClose->Top = 0; m_PngClose->Left = Width - 23; m_PngClose->Visible = true; } __fastcall TKeyBoard::~TKeyBoard() { delete m_PngClose; m_PngClose = NULL; delete m_imgKeyboard; m_imgKeyboard = NULL; delete m_pbKeyboard; m_pbKeyboard = NULL; delete m_pBmpWhiteDDown; m_pBmpWhiteDDown = NULL; delete m_pBmpWhiteLDown; m_pBmpWhiteLDown = NULL; delete m_pBmpWhiteRDown; m_pBmpWhiteRDown = NULL; delete m_pBmpBlackDown; m_pBmpBlackDown = NULL; delete m_imgFirst; m_imgFirst = NULL; delete m_imgSecond; m_imgSecond = NULL; delete m_imgThird; m_imgThird = NULL; delete m_imgForth; m_imgForth = NULL; delete m_ImgClose; //关闭 m_ImgClose = NULL; delete m_ImgBrk; //钢琴背景 m_ImgBrk = NULL; } // 模拟键盘相关 int TKeyBoard::KeyboardGetPressKey(int X, int Y) { short iPressKey = -1, iPressGroup = X / m_nGroupWidth; int xInGroup = X % m_nGroupWidth; int iWhite = xInGroup / m_nWhiteWidth; if (iWhite < 3) iPressKey = iWhite * 2; else iPressKey = iWhite * 2 - 1; if (Y < m_nBlackHeight) { for (int i = 0; i < 5; i++) { if (xInGroup >= m_aBlackHitTest[i].x1 && xInGroup < m_aBlackHitTest[i].x2) { iPressKey = m_aBlackHitTest[i].iKey; break; } } } return MAKELONG(iPressKey, iPressGroup); } void __fastcall TKeyBoard::KeyboardPaint(TObject *Sender) { // if (m_bKeyDown) { int xPos = m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos; m_pbKeyboard->Canvas->Draw(xPos, 0, m_aKey[m_iPressKey].pBmp); } } //--------------------------------------------------------------------------- void __fastcall TKeyBoard::KeyboardMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { //mouseup if (Button == mbLeft && m_bKeyDown) { m_bKeyDown = false; f_MM_RealTimeMIDINoteOff(m_iPressGroup*12 + m_iPressKey + 48); TRect rect; rect.init(m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 6, 19, m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 26, m_pbKeyboard->Height+19); m_iPressGroup = m_iPressKey = -1; InvalidateRect(m_pbKeyboard->Parent->Handle,&rect,true); // m_pbKeyboard->Invalidate(); } } //--------------------------------------------------------------------------- void __fastcall TKeyBoard::KeyboardMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (m_bKeyDown && X >= 0 && Y >= 0 && X < m_pbKeyboard->Width && Y < m_pbKeyboard->Height) { int iKey = KeyboardGetPressKey(X, Y); int iPressGroup = HIWORD(iKey); int iPressKey = LOWORD(iKey); if (iPressGroup != m_iPressGroup || iPressKey != m_iPressKey) { HRESULT hRet = f_MM_RealTimeMIDINoteOff(m_iPressGroup * 12 + m_iPressKey + 48); hRet = f_MM_RealTimeMIDINoteOn( iPressGroup * 12 + iPressKey + 48); TRect rect; //更新原来区域 rect.init(m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 6, 19, m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 26, m_pbKeyboard->Height+19); InvalidateRect(m_pbKeyboard->Parent->Handle,&rect,true); m_iPressGroup = iPressGroup; m_iPressKey = iPressKey; //更新新区域 rect.init(m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 6, 19, m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 26, m_pbKeyboard->Height+19); InvalidateRect(m_pbKeyboard->Parent->Handle,&rect,true); // m_pbKeyboard->Invalidate(); } } } //--------------------------------------------------------------------------- void __fastcall TKeyBoard::KeyboardMouseLeave(TObject *Sender) { // Screen->Cursor = crDefault; } //--------------------------------------------------------------------------- void __fastcall TKeyBoard::KeyboardMouseEnter(TObject *Sender) { // Screen->Cursor = crHandPoint; } //--------------------------------------------------------------------------- void __fastcall TKeyBoard::KeyboardMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { // TMouseButton Button, TShiftState Shift, int X, int Y) { if (Sender == m_pbKeyboard && Button == mbLeft) { m_bKeyDown = true; int iKey = KeyboardGetPressKey(X, Y); int iPressGroup = HIWORD(iKey); int iPressKey = LOWORD(iKey); if (iPressGroup != m_iPressGroup || iPressKey != m_iPressKey) { m_iPressGroup = iPressGroup; m_iPressKey = iPressKey; HRESULT hRet = f_MM_RealTimeMIDINoteOn(m_iPressGroup * 12 + m_iPressKey + 48); TRect rect; rect.init(m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 6, 19, m_iPressGroup * m_nGroupWidth + m_aKey[m_iPressKey].xPos + 26, m_pbKeyboard->Height+19); InvalidateRect(m_pbKeyboard->Parent->Handle,&rect,true); } } } //--------------------------------------------------------------------------- void __fastcall TKeyBoard::ShowKeyboard( bool bShow ) { if( bShow ){ // 创建模拟键盘设备 HRESULT hResult = f_MM_CreateRealTimeMIDIStream( false ); if (hResult != S_OK) { DebugPrint("Create realtime midi stream error.\n"); } else{ this->Show(); } } else if( !bShow ){ this->Hide(); // 释放模拟键盘设备 HRESULT hResult = f_MM_FreeRealTimeMIDIStream(); if (hResult != S_OK) { DebugPrint("Free realtime midi stream error.\n"); } } } void __fastcall TKeyBoard::CloseClick(System::TObject* Sender) { // ShowKeyboard( false ); Application->MainForm->Perform( UM_SHOW_KB, NULL, NULL ); }