DemoDlg.cpp
上传用户:fs3633
上传日期:2021-05-14
资源大小:909k
文件大小:11k
源码类别:

midi

开发平台:

Visual C++

  1. // DemoDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MIDIDevDemo v2.h"
  5. #include "DemoDlg.h"
  6. #include "ShortMsg.h"
  7. #include "midi.h"
  8. #include "MIDIDevsDlg.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CAboutDlg dialog used for App About
  16. class CAboutDlg : public CDialog
  17. {
  18. public:
  19. CAboutDlg();
  20. // Dialog Data
  21. //{{AFX_DATA(CAboutDlg)
  22. enum { IDD = IDD_ABOUTBOX };
  23. //}}AFX_DATA
  24. // ClassWizard generated virtual function overrides
  25. //{{AFX_VIRTUAL(CAboutDlg)
  26. protected:
  27. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  28. //}}AFX_VIRTUAL
  29. // Implementation
  30. protected:
  31. //{{AFX_MSG(CAboutDlg)
  32. //}}AFX_MSG
  33. DECLARE_MESSAGE_MAP()
  34. };
  35. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  36. {
  37. //{{AFX_DATA_INIT(CAboutDlg)
  38. //}}AFX_DATA_INIT
  39. }
  40. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  41. {
  42. CDialog::DoDataExchange(pDX);
  43. //{{AFX_DATA_MAP(CAboutDlg)
  44. //}}AFX_DATA_MAP
  45. }
  46. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  47. //{{AFX_MSG_MAP(CAboutDlg)
  48. // No message handlers
  49. //}}AFX_MSG_MAP
  50. END_MESSAGE_MAP()
  51. /////////////////////////////////////////////////////////////////////////////
  52. // CDemoDlg dialog
  53. CDemoDlg::CDemoDlg(CWnd* pParent /*=NULL*/)
  54. : CDialog(CDemoDlg::IDD, pParent)
  55. {
  56. //{{AFX_DATA_INIT(CDemoDlg)
  57. // NOTE: the ClassWizard will add member initialization here
  58. //}}AFX_DATA_INIT
  59. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  60. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  61. }
  62. CDemoDlg::~CDemoDlg()
  63. {
  64.     if(m_InDevice.IsOpen())
  65.     {
  66.         if(m_InDevice.IsRecording())
  67.         {
  68.             m_InDevice.StopRecording();
  69.         }   
  70.         m_InDevice.Close();
  71.     }
  72.     if(m_OutDevice.IsOpen())
  73.     {
  74.         m_OutDevice.Close();
  75.     }
  76. }
  77. // Note-on event notification 音符开启响应事件
  78. void CDemoDlg::OnNoteOn(CPianoCtrl &PianoCtrl, unsigned char NoteId)
  79. {
  80.     midi::CShortMsg ShortMsg(midi::NOTE_ON, 0, NoteId, 127, 0);
  81.     ShortMsg.SendMsg(m_OutDevice);
  82. }
  83. // Note-off event notification 音符关闭响应事件
  84. //如果沒有這個函數的話,一樣是沒有聲音的
  85. void CDemoDlg::OnNoteOff(CPianoCtrl &PianoCtrl, unsigned char NoteId)
  86. {
  87.     midi::CShortMsg ShortMsg(midi::NOTE_OFF, 0, NoteId, 0, 0);
  88.     ShortMsg.SendMsg(m_OutDevice);
  89. }
  90. // Receives MIDI short message 发送MIDI的短消息函数
  91. void CDemoDlg::ReceiveMsg(DWORD Msg, DWORD TimeStamp)
  92. {
  93.     midi::CShortMsg ShortMsg(Msg, TimeStamp);
  94.     unsigned char Command = ShortMsg.GetCommand();
  95.     CString Text;
  96.     // Display command value 显示命令的值
  97.     Text.Format("%d", ShortMsg.GetCommand());
  98.     m_Command.SetWindowText(Text);
  99.     // Display channel value 显示通道的值
  100.     Text.Format("%d", ShortMsg.GetChannel());
  101.     m_Channel.SetWindowText(Text);
  102.     // Display data byte 1 value 显示一个字节数据的值
  103.     Text.Format("%d", ShortMsg.GetData1());
  104.     m_Data1.SetWindowText(Text);
  105.     // Display data byte 2 value 显示两个字节数据的值
  106.     Text.Format("%d", ShortMsg.GetData2());
  107.     m_Data2.SetWindowText(Text);
  108.     
  109.     // 
  110.     // If this is a note-on or note-off event, notify piano control so
  111.     // that it can update its display
  112.     //如果有音符开启和关闭的事件,就通知钢琴控件并且把它显示出来
  113.     if(Command == midi::NOTE_ON && ShortMsg.GetData2() > 0)
  114.     {
  115.         unsigned char Note = ShortMsg.GetData1();
  116.         // Range checking 开始检查
  117.         if(Note >= m_Keys.GetLowNote() && 
  118.             Note <= m_Keys.GetHighNote())
  119.         {
  120.             m_Keys.NoteOn(Note);
  121.         }
  122.     }
  123.     else if(Command == midi::NOTE_OFF || (Command == midi::NOTE_ON && 
  124.         ShortMsg.GetData2() == 0))
  125.     {
  126.         unsigned char Note = ShortMsg.GetData1();
  127.         // Range checking 
  128.         if(Note >= m_Keys.GetLowNote() && 
  129.             Note <= m_Keys.GetHighNote())
  130.         {
  131.             m_Keys.NoteOff(Note);
  132.         }
  133.     }
  134.     
  135. }
  136. // Receives an erroneous short message 接受一个错误的消息
  137. void CDemoDlg::OnError(DWORD Msg, DWORD TimeStamp)
  138. {
  139.     MessageBox("An illegal MIDI short message was received.", "Error",
  140.         MB_ICONSTOP | MB_OK);
  141. }
  142. void CDemoDlg::DoDataExchange(CDataExchange* pDX)
  143. {
  144. CDialog::DoDataExchange(pDX);
  145. //{{AFX_DATA_MAP(CDemoDlg)
  146. DDX_Control(pDX, IDC_GM_LIST, m_GMCombo);
  147.         DDX_Control(pDX, IDC_COMMAND, m_Command);
  148.         DDX_Control(pDX, IDC_CHANNEL, m_Channel);
  149.         DDX_Control(pDX, IDC_DATA1, m_Data1);
  150.         DDX_Control(pDX, IDC_DATA2, m_Data2);
  151. //}}AFX_DATA_MAP
  152.     DDX_Control(pDX, IDC_MIDI_KEYS, m_Keys);
  153. }
  154. BEGIN_MESSAGE_MAP(CDemoDlg, CDialog)
  155. //{{AFX_MSG_MAP(CDemoDlg)
  156. ON_WM_SYSCOMMAND()
  157. ON_WM_PAINT()
  158. ON_WM_QUERYDRAGICON()
  159. ON_COMMAND(ID_PREF_NOTE_COLOR, OnPrefNoteColor)
  160. ON_COMMAND(ID_PREF_MIDIDEVICES, OnPrefMididevices)
  161. ON_COMMAND(ID_FILE_EXIT, OnFileExit)
  162.     ON_CBN_SELCHANGE(IDC_GM_LIST, OnSelchangeGmList)
  163. ON_COMMAND(ID_HELP_ABOUT, OnHelpAbout)
  164. //}}AFX_MSG_MAP
  165. END_MESSAGE_MAP()
  166. /////////////////////////////////////////////////////////////////////////////
  167. // CDemoDlg message handlers
  168. BOOL CDemoDlg::OnInitDialog()
  169. {
  170. CDialog::OnInitDialog();
  171. // Add "About..." menu item to system menu.
  172. // IDM_ABOUTBOX must be in the system command range.
  173. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  174. ASSERT(IDM_ABOUTBOX < 0xF000);
  175. CMenu* pSysMenu = GetSystemMenu(FALSE);
  176. if (pSysMenu != NULL)
  177. {
  178. CString strAboutMenu;
  179. strAboutMenu.LoadString(IDS_ABOUTBOX);
  180. if (!strAboutMenu.IsEmpty())
  181. {
  182. pSysMenu->AppendMenu(MF_SEPARATOR);
  183. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  184. }
  185. }
  186. // Set the icon for this dialog.  The framework does this automatically
  187. //  when the application's main window is not a dialog
  188. SetIcon(m_hIcon, TRUE); // Set big icon
  189. SetIcon(m_hIcon, FALSE); // Set small icon
  190.     // Initialize piano control
  191.     m_Keys.Initialize(CMIDIKeyboard::LOW_NOTE, CMIDIKeyboard::HIGH_NOTE);
  192.     // Attach ourselves to the piano control so that we will be notified
  193.     // when note-on and note-off events occur
  194.     m_Keys.AttachListener(*this);
  195.     // Initialize General MIDI combo box 初始化MIDI组合框
  196.     m_GMCombo.SetCurSel(0);
  197.     
  198.     // Attempt to open MIDI input and output devices
  199.     //尝试打开一个MIDI输入设备和输出设备
  200.     try
  201.     {
  202.         // If there are any MIDI output devices available, open one.
  203.         //如果有任何一个MIDI输出设备可以用的话,就打开它
  204.         if(midi::CMIDIOutDevice::GetNumDevs() > 0)
  205.         {
  206.             m_OutDevice.Open(0);
  207.         }
  208.         // Else there are no MIDI output devices available.
  209.         //否则就是没有
  210.         else
  211.         {
  212.             MessageBox("No MIDI output devices available.", "Warning", 
  213.                 MB_ICONWARNING | MB_OK);
  214.         }
  215.         // If there are any MIDI input devices available, open one and begin
  216.         // recording.
  217.         //如果有任何一个MIDI输入设备可用的话,打开并且开始录制
  218.         if(midi::CMIDIInDevice::GetNumDevs() > 0)
  219.         {
  220.             m_InDevice.SetReceiver(*this);
  221.             m_InDevice.Open(0);
  222.             // Start receiving MIDI events 开始接受MIDI事件
  223.             m_InDevice.StartRecording();           
  224.         }
  225.         // Else there are no MIDI input devices available.
  226.         //否则没有可用的输入设备
  227.         else
  228.         {
  229.             MessageBox("老大,你没有MIDI输入设备好不好.还不赶快去搞一个来?", "Warning", 
  230.                 MB_ICONWARNING | MB_OK);
  231.         }
  232.     }
  233.     catch(const std::exception &ex)
  234.     {
  235.         MessageBox(ex.what(), "Error", MB_ICONSTOP | MB_OK);
  236.     }
  237. return TRUE;  // return TRUE  unless you set the focus to a control
  238. }
  239. void CDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
  240. {
  241. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  242. {
  243. CAboutDlg dlgAbout;
  244. dlgAbout.DoModal();
  245. }
  246. else
  247. {
  248. CDialog::OnSysCommand(nID, lParam);
  249. }
  250.     
  251. }
  252. // If you add a minimize button to your dialog, you will need the code below
  253. //  to draw the icon.  For MFC applications using the document/view model,
  254. //  this is automatically done for you by the framework.
  255. void CDemoDlg::OnPaint() 
  256. {
  257. if (IsIconic())
  258. {
  259. CPaintDC dc(this); // device context for painting
  260. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  261. // Center icon in client rectangle
  262. int cxIcon = GetSystemMetrics(SM_CXICON);
  263. int cyIcon = GetSystemMetrics(SM_CYICON);
  264. CRect rect;
  265. GetClientRect(&rect);
  266. int x = (rect.Width() - cxIcon + 1) / 2;
  267. int y = (rect.Height() - cyIcon + 1) / 2;
  268. // Draw the icon
  269. dc.DrawIcon(x, y, m_hIcon);
  270. }
  271. else
  272. {
  273. CDialog::OnPaint();
  274. }
  275. }
  276. // The system calls this to obtain the cursor to display while the user drags
  277. //  the minimized window.
  278. HCURSOR CDemoDlg::OnQueryDragIcon()
  279. {
  280. return (HCURSOR) m_hIcon;
  281. }
  282. // Note color preference 选择音符颜色的函数
  283. void CDemoDlg::OnPrefNoteColor() 
  284. {
  285. CColorDialog Dlg(m_Keys.GetNoteOnColor());
  286.     if(Dlg.DoModal() == IDOK)
  287.     {
  288.         m_Keys.SetNoteOnColor(Dlg.GetColor());
  289.     }
  290. }
  291. // MIDI device preferences  MIDI设备参数
  292. void CDemoDlg::OnPrefMididevices() 
  293. {
  294.     try
  295.     {
  296.     CMIDIDevsDlg Dlg;
  297.         //
  298.         // Initialize MIDI device dialog box
  299.         //初始化MIDI设备DLG对话框
  300.         if(m_OutDevice.IsOpen())
  301.         {
  302.             Dlg.SetOutDevId(m_OutDevice.GetDevID());
  303.         }
  304.         if(m_InDevice.IsOpen())
  305.         {
  306.             Dlg.SetInDevId(m_InDevice.GetDevID());
  307.         }
  308.         // Run dialog box
  309.         if(Dlg.DoModal() == IDOK)
  310.         {
  311.             // If the client clicked OK and they chose to change the 
  312.             // MIDI output device
  313.             if(Dlg.IsOutDevChanged())
  314.             {
  315.                 m_OutDevice.Close();
  316.                 m_OutDevice.Open(Dlg.GetOutDevId());   
  317.                 OnSelchangeGmList();
  318.             }
  319.             // If the client clicked OK and they chose to change the 
  320.             // MIDI input device
  321.             if(Dlg.IsInDevChanged())
  322.             {
  323.                 if(m_InDevice.IsOpen())
  324.                 {
  325.                     if(m_InDevice.IsRecording())
  326.                     {
  327.                     // Stop receiving MIDI events 停止接受MIDI事件
  328.                         m_InDevice.StopRecording();   
  329.                     }
  330.                 
  331.                     m_InDevice.Close(); 
  332.                 }
  333.                 m_InDevice.Open(Dlg.GetInDevId());   
  334.                 
  335.                 // Start receiving MIDI events  开始接受MIDI事件
  336.                 m_InDevice.StartRecording(); 
  337.             }
  338.         }
  339.     }
  340.     catch(const std::exception &ex)
  341.     {
  342.         MessageBox(ex.what(), "Error", MB_ICONSTOP | MB_OK);
  343.     }
  344. }
  345. // Exit the program
  346. void CDemoDlg::OnFileExit() 
  347. {
  348. SendMessage(WM_CLOSE);
  349. }
  350. // Select a new General MIDI patch 搜尋一個新的普通的MIDI音符輪廓
  351. void CDemoDlg::OnSelchangeGmList() 
  352. {
  353. unsigned char Patch = m_GMCombo.GetCurSel();
  354.     // Construct and send program change message 构造发送程序变更消息
  355.     midi::CShortMsg Msg(midi::PROGRAM_CHANGE, 0, Patch, 0, 0);
  356.     Msg.SendMsg(m_OutDevice);
  357.     // Make sure the piano control regains focus when we are done with 
  358.     // the Genera MIDI combo box
  359.     m_Keys.SetFocus();
  360. }
  361. void CDemoDlg::OnHelpAbout() 
  362. {
  363. CAboutDlg Dlg;
  364.     Dlg.DoModal();
  365. }