winmm.dll
是 Windows 操作系统中一个重要的动态链接库(DLL)文件,全称为 Windows Multimedia Library(Windows 多媒体库)。它包含了一系列用于处理多媒体相关功能的函数,是 Windows 系统实现音频、视频等多媒体操作的核心组件之一。
核心函数:mciSendString
[DllImport("winmm.dll")]
private static extern long mciSendString(
string command, // 要执行的MCI命令(字符串)
StringBuilder returnValue, // 存储返回结果的缓冲区
int returnLength, // 缓冲区长度
IntPtr winHandle // 窗口句柄(通常传IntPtr.Zero)
);
常用 MCI 命令及用法
1. 打开媒体文件
// 格式:open "文件路径" type 类型 alias 别名
// 作用:加载媒体文件并给它起一个别名(方便后续操作)
SendMCICommand("open \"C:\\music.mp3\" type mpegvideo alias MediaFile");
type mpegvideo:指定媒体类型(音频通常用 mpegvideo 或 waveaudio)
alias MediaFile:给文件起个别名 “MediaFile”,后续命令用别名操作,无需重复写路径
2. 播放 / 暂停 / 继续 / 停止
// 播放(从当前位置开始)
SendMCICommand("play MediaFile");
// 暂停
SendMCICommand("pause MediaFile");
// 继续(从暂停处恢复)
SendMCICommand("resume MediaFile");
// 停止并回到开头
SendMCICommand("stop MediaFile");
SendMCICommand("seek MediaFile to start"); // 定位到开始位置
3. 调整音量
// 格式:setaudio 别名 volume to 音量值(范围0-1000)
SendMCICommand("setaudio MediaFile volume to 500"); // 50%音量
注意:MCI 音量范围是 0-1000,代码中通过 currentVolume * 10 转换(0-100 → 0-1000)
4. 获取媒体信息(需接收返回值)
// 获取当前播放位置(毫秒)
string position = GetMCIString("status MediaFile position");
// 获取媒体总长度(毫秒)
string length = GetMCIString("status MediaFile length");
// 获取播放状态(playing/paused/stopped)
string status = GetMCIString("status MediaFile mode");
5. 定位播放位置
// 格式:seek 别名 to 位置(毫秒)
SendMCICommand("seek MediaFile to 10000"); // 定位到10秒位置(10000毫秒)
6. 关闭媒体文件
// 关闭单个文件(通过别名)
SendMCICommand("close MediaFile");
// 关闭所有打开的媒体文件
SendMCICommand("close all");
完整代码
Form1.Designer.cs
namespace music
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.btnPlay = new System.Windows.Forms.Button();
this.btnPause = new System.Windows.Forms.Button();
this.btnStop = new System.Windows.Forms.Button();
this.btnAdd = new System.Windows.Forms.Button();
this.btnPrev = new System.Windows.Forms.Button();
this.btnNext = new System.Windows.Forms.Button();
this.listBoxMusic = new System.Windows.Forms.ListBox();
this.trackBarProgress = new System.Windows.Forms.TrackBar();
this.trackBarVolume = new System.Windows.Forms.TrackBar();
this.lblCurrentSong = new System.Windows.Forms.Label();
this.lblTime = new System.Windows.Forms.Label();
this.timerProgress = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// btnPlay
//
this.btnPlay.Location = new System.Drawing.Point(106, 347);
this.btnPlay.Name = "btnPlay";
this.btnPlay.Size = new System.Drawing.Size(75, 23);
this.btnPlay.TabIndex = 0;
this.btnPlay.Text = "播放";
this.btnPlay.UseVisualStyleBackColor = true;
//
// btnPause
//
this.btnPause.Location = new System.Drawing.Point(297, 347);
this.btnPause.Name = "btnPause";
this.btnPause.Size = new System.Drawing.Size(75, 23);
this.btnPause.TabIndex = 1;
this.btnPause.Text = "暂停";
this.btnPause.UseVisualStyleBackColor = true;
//
// btnStop
//
this.btnStop.Location = new System.Drawing.Point(500, 381);
this.btnStop.Name = "btnStop";
this.btnStop.Size = new System.Drawing.Size(75, 23);
this.btnStop.TabIndex = 2;
this.btnStop.Text = "停止";
this.btnStop.UseVisualStyleBackColor = true;
this.btnStop.Click += new System.EventHandler(this.button3_Click);
//
// btnAdd
//
this.btnAdd.Location = new System.Drawing.Point(679, 380);
this.btnAdd.Name = "btnAdd";
this.btnAdd.Size = new System.Drawing.Size(75, 23);
this.btnAdd.TabIndex = 3;
this.btnAdd.Text = "添加音乐";
this.btnAdd.UseVisualStyleBackColor = true;
//
// btnPrev
//
this.btnPrev.Location = new System.Drawing.Point(859, 380);
this.btnPrev.Name = "btnPrev";
this.btnPrev.Size = new System.Drawing.Size(75, 23);
this.btnPrev.TabIndex = 4;
this.btnPrev.Text = "上一首";
this.btnPrev.UseVisualStyleBackColor = true;
//
// btnNext
//
this.btnNext.Location = new System.Drawing.Point(1051, 393);
this.btnNext.Name = "btnNext";
this.btnNext.Size = new System.Drawing.Size(75, 23);
this.btnNext.TabIndex = 5;
this.btnNext.Text = "下一首";
this.btnNext.UseVisualStyleBackColor = true;
//
// listBoxMusic
//
this.listBoxMusic.FormattingEnabled = true;
this.listBoxMusic.ItemHeight = 15;
this.listBoxMusic.Location = new System.Drawing.Point(542, 115);
this.listBoxMusic.Name = "listBoxMusic";
this.listBoxMusic.Size = new System.Drawing.Size(510, 214);
this.listBoxMusic.TabIndex = 6;
//
// trackBarProgress
//
this.trackBarProgress.Location = new System.Drawing.Point(223, 48);
this.trackBarProgress.Name = "trackBarProgress";
this.trackBarProgress.Size = new System.Drawing.Size(427, 56);
this.trackBarProgress.TabIndex = 7;
//
// trackBarVolume
//
this.trackBarVolume.Location = new System.Drawing.Point(816, 48);
this.trackBarVolume.Name = "trackBarVolume";
this.trackBarVolume.Size = new System.Drawing.Size(276, 56);
this.trackBarVolume.TabIndex = 8;
//
// lblCurrentSong
//
this.lblCurrentSong.AutoSize = true;
this.lblCurrentSong.Location = new System.Drawing.Point(172, 199);
this.lblCurrentSong.Name = "lblCurrentSong";
this.lblCurrentSong.Size = new System.Drawing.Size(52, 15);
this.lblCurrentSong.TabIndex = 9;
this.lblCurrentSong.Text = "歌曲名";
//
// lblTime
//
this.lblTime.AutoSize = true;
this.lblTime.Location = new System.Drawing.Point(278, 264);
this.lblTime.Name = "lblTime";
this.lblTime.Size = new System.Drawing.Size(67, 15);
this.lblTime.TabIndex = 10;
this.lblTime.Text = "播放时间";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1274, 541);
this.Controls.Add(this.lblTime);
this.Controls.Add(this.lblCurrentSong);
this.Controls.Add(this.trackBarVolume);
this.Controls.Add(this.trackBarProgress);
this.Controls.Add(this.listBoxMusic);
this.Controls.Add(this.btnNext);
this.Controls.Add(this.btnPrev);
this.Controls.Add(this.btnAdd);
this.Controls.Add(this.btnStop);
this.Controls.Add(this.btnPause);
this.Controls.Add(this.btnPlay);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.trackBarProgress)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnPlay;
private System.Windows.Forms.Button btnPause;
private System.Windows.Forms.Button btnStop;
private System.Windows.Forms.Button btnAdd;
private System.Windows.Forms.Button btnPrev;
private System.Windows.Forms.Button btnNext;
private System.Windows.Forms.ListBox listBoxMusic;
private System.Windows.Forms.TrackBar trackBarProgress;
private System.Windows.Forms.TrackBar trackBarVolume;
private System.Windows.Forms.Label lblCurrentSong;
private System.Windows.Forms.Label lblTime;
private System.Windows.Forms.Timer timerProgress;
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace music
{
public partial class Form1 : Form
{
// MCI API 声明
[DllImport("winmm.dll")]
private static extern long mciSendString(string command, StringBuilder returnValue, int returnLength, IntPtr winHandle);
private List<string> playlist;
private int currentSongIndex = -1;
private bool isDragging = false;
private bool isPlaying = false;
private bool isPaused = false;
private int songLength = 0;
private int currentVolume = 50;
public Form1()
{
InitializeComponent();
playlist = new List<string>();
}
private void Form1_Load(object sender, EventArgs e)
{
// 初始化界面
trackBarVolume.Maximum = 100;
trackBarVolume.Minimum = 0;
trackBarVolume.Value = 50;
currentVolume = 50;
trackBarProgress.Maximum = 1000;
trackBarProgress.Minimum = 0;
trackBarProgress.Value = 0;
lblCurrentSong.Text = "未选择歌曲";
lblTime.Text = "00:00 / 00:00";
// 绑定事件
btnPlay.Click += BtnPlay_Click;
btnPause.Click += BtnPause_Click;
btnStop.Click += BtnStop_Click;
btnAdd.Click += BtnAdd_Click;
btnPrev.Click += BtnPrev_Click;
btnNext.Click += BtnNext_Click;
listBoxMusic.SelectedIndexChanged += ListBoxMusic_SelectedIndexChanged;
trackBarVolume.Scroll += TrackBarVolume_Scroll;
trackBarProgress.MouseDown += TrackBarProgress_MouseDown;
trackBarProgress.MouseUp += TrackBarProgress_MouseUp;
trackBarProgress.Scroll += TrackBarProgress_Scroll;
timerProgress.Interval = 1000;
timerProgress.Tick += TimerProgress_Tick;
timerProgress.Start();
}
// MCI 帮助方法
private void SendMCICommand(string command)
{
mciSendString(command, null, 0, IntPtr.Zero);
}
private string GetMCIString(string command)
{
StringBuilder buffer = new StringBuilder(128);
mciSendString(command, buffer, 128, IntPtr.Zero);
return buffer.ToString();
}
private void LoadSong(string filePath)
{
try
{
SendMCICommand("close all");
SendMCICommand($"open \"{filePath}\" type mpegvideo alias MediaFile");
// 获取歌曲长度
string lengthStr = GetMCIString("status MediaFile length");
if (int.TryParse(lengthStr, out songLength))
{
// MCI返回的时间单位是毫秒
songLength = songLength / 1000; // 转换为秒
}
// 设置音量
SendMCICommand($"setaudio MediaFile volume to {currentVolume * 10}");
}
catch (Exception ex)
{
MessageBox.Show($"加载音乐文件失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void BtnPlay_Click(object sender, EventArgs e)
{
if (currentSongIndex >= 0 && currentSongIndex < playlist.Count)
{
if (isPaused)
{
SendMCICommand("resume MediaFile");
isPaused = false;
isPlaying = true;
}
else if (!isPlaying)
{
LoadSong(playlist[currentSongIndex]);
SendMCICommand("play MediaFile");
isPlaying = true;
isPaused = false;
UpdateCurrentSongDisplay();
}
}
else if (playlist.Count > 0)
{
currentSongIndex = 0;
listBoxMusic.SelectedIndex = 0;
LoadSong(playlist[currentSongIndex]);
SendMCICommand("play MediaFile");
isPlaying = true;
isPaused = false;
UpdateCurrentSongDisplay();
}
}
private void BtnPause_Click(object sender, EventArgs e)
{
if (isPlaying && !isPaused)
{
SendMCICommand("pause MediaFile");
isPaused = true;
}
}
private void BtnStop_Click(object sender, EventArgs e)
{
SendMCICommand("stop MediaFile");
SendMCICommand("seek MediaFile to start");
isPlaying = false;
isPaused = false;
trackBarProgress.Value = 0;
lblTime.Text = "00:00 / 00:00";
}
private void BtnAdd_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "音乐文件|*.mp3;*.wav;*.wma;*.flac;*.m4a|所有文件|*.*";
openFileDialog.Multiselect = true;
openFileDialog.Title = "选择音乐文件";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
foreach (string fileName in openFileDialog.FileNames)
{
playlist.Add(fileName);
listBoxMusic.Items.Add(Path.GetFileNameWithoutExtension(fileName));
}
}
}
private void BtnPrev_Click(object sender, EventArgs e)
{
if (playlist.Count > 0)
{
currentSongIndex--;
if (currentSongIndex < 0)
currentSongIndex = playlist.Count - 1;
listBoxMusic.SelectedIndex = currentSongIndex;
LoadSong(playlist[currentSongIndex]);
SendMCICommand("play MediaFile");
isPlaying = true;
isPaused = false;
UpdateCurrentSongDisplay();
}
}
private void BtnNext_Click(object sender, EventArgs e)
{
if (playlist.Count > 0)
{
currentSongIndex++;
if (currentSongIndex >= playlist.Count)
currentSongIndex = 0;
listBoxMusic.SelectedIndex = currentSongIndex;
LoadSong(playlist[currentSongIndex]);
SendMCICommand("play MediaFile");
isPlaying = true;
isPaused = false;
UpdateCurrentSongDisplay();
}
}
private void ListBoxMusic_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBoxMusic.SelectedIndex >= 0)
{
currentSongIndex = listBoxMusic.SelectedIndex;
UpdateCurrentSongDisplay();
}
}
private void TrackBarVolume_Scroll(object sender, EventArgs e)
{
currentVolume = trackBarVolume.Value;
SendMCICommand($"setaudio MediaFile volume to {currentVolume * 10}");
}
private void TrackBarProgress_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
}
private void TrackBarProgress_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
if (isPlaying && songLength > 0)
{
int newPosition = (int)((double)trackBarProgress.Value / trackBarProgress.Maximum * songLength * 1000);
SendMCICommand($"seek MediaFile to {newPosition}");
if (!isPaused)
{
SendMCICommand("play MediaFile");
}
}
}
private void TrackBarProgress_Scroll(object sender, EventArgs e)
{
if (isDragging && songLength > 0)
{
double newPosition = (double)trackBarProgress.Value / trackBarProgress.Maximum * songLength;
UpdateTimeDisplay(newPosition, songLength);
}
}
private int GetCurrentPosition()
{
string positionStr = GetMCIString("status MediaFile position");
if (int.TryParse(positionStr, out int position))
{
return position / 1000; // 转换为秒
}
return 0;
}
private string GetPlayStatus()
{
return GetMCIString("status MediaFile mode");
}
private void TimerProgress_Tick(object sender, EventArgs e)
{
if (isPlaying && !isDragging)
{
string status = GetPlayStatus();
// 检查是否还在播放
if (status == "stopped" && isPlaying)
{
// 歌曲播放完成,自动播放下一首
if (playlist.Count > 1)
{
BtnNext_Click(sender, e);
return;
}
else
{
isPlaying = false;
isPaused = false;
trackBarProgress.Value = 0;
lblTime.Text = "00:00 / 00:00";
return;
}
}
if (status == "playing" || status == "paused")
{
int currentPosition = GetCurrentPosition();
if (songLength > 0)
{
int progress = (int)((double)currentPosition / songLength * trackBarProgress.Maximum);
trackBarProgress.Value = Math.Min(progress, trackBarProgress.Maximum);
}
UpdateTimeDisplay(currentPosition, songLength);
}
}
}
private void UpdateCurrentSongDisplay()
{
if (currentSongIndex >= 0 && currentSongIndex < playlist.Count)
{
string fileName = Path.GetFileNameWithoutExtension(playlist[currentSongIndex]);
lblCurrentSong.Text = fileName;
}
}
private void UpdateTimeDisplay(double currentPosition, double duration)
{
string currentTime = TimeSpan.FromSeconds(currentPosition).ToString(@"mm\:ss");
string totalTime = TimeSpan.FromSeconds(duration).ToString(@"mm\:ss");
lblTime.Text = $"{currentTime} / {totalTime}";
}
private void button3_Click(object sender, EventArgs e)
{
BtnStop_Click(sender, e);
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
// 清理MCI资源
SendMCICommand("close all");
base.OnFormClosing(e);
}
}
}
123