CPianoCtrl - 一个显示钢琴控件






4.80/5 (39投票s)
关于使用 CPianoCtrl 类的文章

引言
几个月前,我写了一篇 Code Project 文章,介绍了我为低级 Windows MIDI API 创建的一个类包装库 class wrapper library。为了演示我的库,我创建了一个简单的应用程序,其中包含一个钢琴显示器,可以通过鼠标播放音符。事实证明,钢琴控件本身引起了一些兴趣。不幸的是,由于各种原因,我在那个项目中创建的钢琴控件不适合通用使用,所以我决定从头开始完全重写这个控件,以便它可以在许多不同的上下文中进行使用。
CPianoCtrl 和 CPianoCtrlListener 类
CPianoCtrl
类代表一个键盘钢琴显示。它是一个自定义控件,派生自 MFC 的 CWnd
类。它显示一个交互式键盘,允许您使用鼠标播放音符。控件本身不产生任何声音。由您连接 CPianoCtrl
对象到声音源。这是通过 CPianoCtrlListener
类完成的。
CPianoCtrlListener
是一个抽象类。派生类可以附加到 CPianoCtrl
对象。当一个音符被按下或释放时,CPianoCtrl
对象会通知其所有侦听器,已经发生了音符事件。例如,一个 CPianoCtrlListener
派生类可以通过播放与 CPianoCtrl
对象注册的音符相对应的 MIDI 音符来响应事件。
可以通过调用 NoteOn
和 NoteOff
函数直接激活 CPianoCtrl
对象上的按键。当您想通过鼠标以外的其他方式打开和关闭键盘上的音符时,这很有用。例如,您可以解析 MIDI 文件,并让键盘上的音符播放文件中的音符。此外,由于您可以更改正在播放的按键的颜色,因此每个 MIDI 轨道都可以拥有自己的颜色。
音符范围和特性
CPianoCtrl
类最多可以有 128 个按键(0 - 127)。范围通过 Initialize
方法或 SetNoteRange
方法设置。您指定范围的最低音符和最高音符。最低音符必须小于最高音符,并且最低音符和最高音符都必须是自然音。这是一个重要的点,值得重复:键盘上的最低音符和最高音符必须是自然音。这个限制是为了避免出现黑键作为最低或最高音符的情况。在这种情况下,会留下一个白键的碎片。这并非不可能处理。但是,简单地避免这种情况会让事情更轻松、更清晰。
音符由整数值表示。数字 0 被认为是 C 音。当您从 0 开始向上时,您就是在按照半音阶上升。因此,0 等于 C,1 等于 C#,2 等于 D,依此类推。当您到达 B 音(第一个 B 音是数字 11)后,音阶将从 C 开始重新循环。
CPianoCtrl
可以有三种显示方式:垂直左、垂直右和水平。垂直左将控件垂直显示,按键朝右;垂直右将控件垂直显示,按键朝左;水平将控件水平显示。通过将一个常量传递给控件的构造函数来确定显示模式。这些常量是 VERTICAL_LEFT
、VERTICAL_RIGHT
和 HORIZONTAL
。
使用 CPianoCtrl 类
要在基于对话框的应用程序中使用 CPianoCtrl
类,请执行以下步骤:
- 在资源编辑器中,将一个自定义控件放置到对话框上。
- 在自定义控件的属性框中,将类名设置为与
CPianoCtrl
的类名匹配。 - 向对话框类添加一个
CPianoCtrl
实例变量。 - 在对话框类的
DoDataExchange
方法中添加一个DDX_Control
调用。例如,如果您的对话框类名为CPianoDlg
,CPianoCtrl
变量名为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); }
- 在对话框类的
OnInitDialog
函数中,通过调用其initialize
函数来初始化CPianoCtrl
对象。在这里,您将传入所需的音符范围,以及可选的音符开启颜色。
要在对话框或窗口中动态使用该控件,请执行以下步骤:
- 向您的类添加一个
CPianoCtrl
实例变量。这可以是指向CPianoCtrl
对象的指针,但如果是这样,在使用之前您需要为其分配内存,并在使用完毕后释放其内存。 - 调用
CPianoCtrl
对象的Create
函数。在这里,您将传递父窗口、CPianoCtrl
的位置和大小、其 ID,以及可选的窗口样式。 - 调用
CPianoCtrl
对象的Initialize
函数。在这里,您将传递所需的音符范围,以及可选的音符开启颜色。
演示项目
VC++ 演示项目允许您与三个 CPianoCtrl
控件进行交互。您可以动态更改它们的范围。此外,您还可以更改用于指示音符正在播放的颜色。您会注意到,当您点击按键时不会听到任何声音。这是因为控件本身不产生声音。它必须连接到声音源。如果您想看一个例子,请查看我更新的 MIDI 包装器文章。在该演示应用程序中,我从 CPianoCtrl
类派生了一个专门用于与我的 MIDI 库配合使用并播放 MIDI 音符的类。
希望您觉得这个控件有用。如果您有任何建议、错误报告,或者只是想告诉我您是如何使用这个控件的,请告诉我。保重!
历史
- 2003 年 3 月 1 日 - 增加了垂直显示控件的功能
- 2008 年 3 月 14 日 - 更新了源代码和演示项目,将许可证更改为 MIT