65.9K
CodeProject 正在变化。 阅读更多。
Home

CPianoCtrl - 一个显示钢琴控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (39投票s)

2002年12月31日

MIT

5分钟阅读

viewsIcon

217520

downloadIcon

5160

关于使用 CPianoCtrl 类的文章

引言

几个月前,我写了一篇 Code Project 文章,介绍了我为低级 Windows MIDI API 创建的一个类包装库 class wrapper library。为了演示我的库,我创建了一个简单的应用程序,其中包含一个钢琴显示器,可以通过鼠标播放音符。事实证明,钢琴控件本身引起了一些兴趣。不幸的是,由于各种原因,我在那个项目中创建的钢琴控件不适合通用使用,所以我决定从头开始完全重写这个控件,以便它可以在许多不同的上下文中进行使用。

CPianoCtrl 和 CPianoCtrlListener 类

CPianoCtrl 类代表一个键盘钢琴显示。它是一个自定义控件,派生自 MFC 的 CWnd 类。它显示一个交互式键盘,允许您使用鼠标播放音符。控件本身不产生任何声音。由您连接 CPianoCtrl 对象到声音源。这是通过 CPianoCtrlListener 类完成的。

CPianoCtrlListener 是一个抽象类。派生类可以附加到 CPianoCtrl 对象。当一个音符被按下或释放时,CPianoCtrl 对象会通知其所有侦听器,已经发生了音符事件。例如,一个 CPianoCtrlListener 派生类可以通过播放与 CPianoCtrl 对象注册的音符相对应的 MIDI 音符来响应事件。

可以通过调用 NoteOnNoteOff 函数直接激活 CPianoCtrl 对象上的按键。当您想通过鼠标以外的其他方式打开和关闭键盘上的音符时,这很有用。例如,您可以解析 MIDI 文件,并让键盘上的音符播放文件中的音符。此外,由于您可以更改正在播放的按键的颜色,因此每个 MIDI 轨道都可以拥有自己的颜色。

音符范围和特性

CPianoCtrl 类最多可以有 128 个按键(0 - 127)。范围通过 Initialize 方法或 SetNoteRange 方法设置。您指定范围的最低音符和最高音符。最低音符必须小于最高音符,并且最低音符和最高音符都必须是自然音。这是一个重要的点,值得重复:键盘上的最低音符和最高音符必须是自然音。这个限制是为了避免出现黑键作为最低或最高音符的情况。在这种情况下,会留下一个白键的碎片。这并非不可能处理。但是,简单地避免这种情况会让事情更轻松、更清晰。

音符由整数值表示。数字 0 被认为是 C 音。当您从 0 开始向上时,您就是在按照半音阶上升。因此,0 等于 C,1 等于 C#,2 等于 D,依此类推。当您到达 B 音(第一个 B 音是数字 11)后,音阶将从 C 开始重新循环。

CPianoCtrl 可以有三种显示方式:垂直左、垂直右和水平。垂直左将控件垂直显示,按键朝右;垂直右将控件垂直显示,按键朝左;水平将控件水平显示。通过将一个常量传递给控件的构造函数来确定显示模式。这些常量是 VERTICAL_LEFTVERTICAL_RIGHTHORIZONTAL

使用 CPianoCtrl 类

要在基于对话框的应用程序中使用 CPianoCtrl 类,请执行以下步骤:

  1. 在资源编辑器中,将一个自定义控件放置到对话框上。
  2. 在自定义控件的属性框中,将类名设置为与 CPianoCtrl 的类名匹配。
  3. 向对话框类添加一个 CPianoCtrl 实例变量。
  4. 在对话框类的 DoDataExchange 方法中添加一个 DDX_Control 调用。例如,如果您的对话框类名为 CPianoDlgCPianoCtrl 变量名为 m_PianoCtrl,控件的 ID 为 IDC_PIANOCTRL,那么您将在对话框类的 DoDataExchange 函数中放置以下内容:

    void CPianoDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CPianoDlg)
            // NOTE: the ClassWizard will add DDX and DDV calls here
        //}}AFX_DATA_MAP
        DDX_Control(pDX, IDC_PIANOCTRL, m_PianoCtrl);
    }
  5. 在对话框类的 OnInitDialog 函数中,通过调用其 initialize 函数来初始化 CPianoCtrl 对象。在这里,您将传入所需的音符范围,以及可选的音符开启颜色。

要在对话框或窗口中动态使用该控件,请执行以下步骤:

  1. 向您的类添加一个 CPianoCtrl 实例变量。这可以是指向 CPianoCtrl 对象的指针,但如果是这样,在使用之前您需要为其分配内存,并在使用完毕后释放其内存。
  2. 调用 CPianoCtrl 对象的 Create 函数。在这里,您将传递父窗口、CPianoCtrl 的位置和大小、其 ID,以及可选的窗口样式。
  3. 调用 CPianoCtrl 对象的 Initialize 函数。在这里,您将传递所需的音符范围,以及可选的音符开启颜色。

演示项目

VC++ 演示项目允许您与三个 CPianoCtrl 控件进行交互。您可以动态更改它们的范围。此外,您还可以更改用于指示音符正在播放的颜色。您会注意到,当您点击按键时不会听到任何声音。这是因为控件本身不产生声音。它必须连接到声音源。如果您想看一个例子,请查看我更新的 MIDI 包装器文章。在该演示应用程序中,我从 CPianoCtrl 类派生了一个专门用于与我的 MIDI 库配合使用并播放 MIDI 音符的类。

希望您觉得这个控件有用。如果您有任何建议、错误报告,或者只是想告诉我您是如何使用这个控件的,请告诉我。保重!

历史

  • 2003 年 3 月 1 日 - 增加了垂直显示控件的功能
  • 2008 年 3 月 14 日 - 更新了源代码和演示项目,将许可证更改为 MIT
© . All rights reserved.