tqsheng

go.....
随笔 - 366, 文章 - 18, 评论 - 101, 引用 - 0
数据加载中……

用Media Player设计个性化媒体播放器

  摘要:本文主要介绍了对Windows Media Player控件的使用方法,并在此基础上完成个性化媒体播放程序的设计实现。

  关键字:ActiveX控件;多媒体;窗体半透明;热键

  引言

  多媒体播放软件现在几乎成为每一台家用计算机的装机必备软件,比较流行的有RealOne Player、Windows Media Player以及国产软件金山影霸等等,通过这些软件能够播放RM、RMVB、MP3、MPEG、DAT等多种格式的多媒体文件。虽然这些商业软件在功能上已经做的相当完备,但由于其产品开发是面向大多数普通消费者的,正所谓众口难调,这类软件很难做到符合每一个消费者的口味。而作为一名程序员,完全可以利用自身的技术优势来对其进行改造,以设计出为自己量身订做的媒体播放软件,改造后的软件在使用时将更符合自己的使用习惯。本文即以Windows Media Player 9.0为例讲述如何将其改造为个性化的媒体播放软件。

  对Windows Media Player控件的基本控制

  在安装了Windows Media Player 9.0后,一个Windows Media Player ActiveX控件也同时被安装到系统并完成注册。该控件为开发人员提供了Windows Media Player 9.0具备的绝大部分功能,能够通过该控件比较轻松的实现对Windows Media Player 9.0的二次开发。

  为使用该控件,首先要将其添加到工程。点击“Project”下“Add to Project”弹出的“Components and Controls…”子菜单,并从弹出对话框中进入“Registered ActiveX Controls”目录查找并添加Windows Media Player控件到工程。这时以CWMP开头的17个类将被添加到工程。在资源视图中将控件拖动到用来播放多媒体的对话框上并通过ClassWizard将控件与CWMPPlayer4类对象建立关联。CWMPPlayer4类提供了与Windows Media Player控件进行交互的基本方法,而且部分成员函数还能够进一步获取得到其他相关类对象的实例。其中,SetUrl()和close()方法将能够打开和关闭指定的媒体文件。在打开文件之后,能够通过控件上的自带按钮控制媒体的播放、暂停、停止以及对音量的控制等。如果需要在程序中控制媒体的播放,可使用GetControls()函数返回CWMPControls类对象,并进一步调用该对象的play()、stop()、pause()、fastForward()、fastReverse()等方法来完成播放、停止、暂停、快进、快退等相应动作;如果需要在程序中对控件属性进行设置和更改,可在GetSettings()方法返回一个CWMPSettings类的对象后通过其成员函数来完成相应的设置,例如,下面这段代码将把播放音量设置到最大:

m_Setting = m_WMPPlayer.GetSettings();
m_Setting.SetVolume(100);

  目前只是在窗口模式下播放媒体,大部分媒体播放软件都提供有全屏播放功能,Windows Media Player也不例外,只需以TRUE为参数调用CWMPPlayer4类成员函数 SetFullScreen()即可,在全屏模式下可以通过点击鼠标左键或是从右键弹出菜单退回到窗口播放模式。通过对CWMPPlayer4、CWMPSettings和CWMPControls等几个类的使用可以实现Windows Media Player的大部分常规功能,如果需要做进一步的控制,可以在用下面这些函数返回相关类对象后调用相关成员函数来加以实现:

  GetCurrentMedia() 返回CWMPMedia类对象

  GetMediaCollection() 返回CWMPMediaCollection类对象

  GetPlaylistCollection() 返回CWMPPlaylistCollection类对象

  GetNetwork() 返回CWMPNetwork类对象

  GetCurrentPlaylist() 返回CWMPPlaylist类对象

  GetCdromCollection() 返回CWMPCdromCollection类对象

  GetClosedCaption() 返回CWMPClosedCaption类对象

  GetError() 返回CWMPError类对象

  GetDvd() 返回CWMPDVD类对象

  GetPlayerApplication() 返回CWMPPlayerApplication类对象

热键隐藏与呼出

  前面介绍的各种常规功能在Windows Media Player中都已经具备,为了使设计的程序在使用方式上更适合自己,可以根据自己的需求添加一些Windows Media Player原本并不具备的个性化功能。例如,本程序下面将要添加的热键迅速隐藏、呼出功能和可调半透明播放功能都是Windows Media Player所不具备的,而且就笔者这段时间的试用,感觉这两种功能都还是相当实用的。当然,这里要添加的既然是“个性化”功能,那么就应当视读者的个人喜好而决定到底要添加什么功能。笔者此处介绍的目的仅在于抛砖引玉。

  无论是金山影霸还是RealOne Player、Windows Media Player等主流媒体播放软件都没有提供彻底隐藏的功能,通常只能简单的最小化至多不过缩小成任务区中的一个小图标,这样其实根本达不到隐藏的效果,如果暂时离开计算机,他人可以很容易打开当前正在执行的媒体播放程序。这里将要实现的目标是:程序主窗体的隐藏、在任务栏上的隐藏、在Alt+Tab键在程序间切换时的隐藏。这样,程序在实施隐藏后他人将意识不到程序的执行,可以达到非常好的隐身效果。由于隐藏后没有任何窗口供用户交互之用,因此需要添加热键以在程序隐藏后能够将其从后台呼出。

  首先要在程序中注册一个热键,无论该程序在前台还是后台运行,只要用户按下这个热键,程序将立即执行在前、后台间的切换。下面这段代码在程序初始运行时执行,通过对RegisterHotKey()的调用登记用于程序隐藏的热键Ctrl + P(或Ctrl + p)和用于程序呼出的热键Ctrl + Shift + A(或Ctrl + Shift + a):

// 登记热键
HWND hWnd = GetSafeHwnd();
RegisterHotKey(hWnd, 1001, MOD_CONTROL | MOD_SHIFT, 'A');
RegisterHotKey(hWnd, 1002, MOD_CONTROL | MOD_SHIFT, 'a');
RegisterHotKey(hWnd, 1003, MOD_CONTROL, 'P');
RegisterHotKey(hWnd, 1004, MOD_CONTROL, 'p');

  其中,1001、1002等参数是这些热键对应的ID。在程序捕获到热键消息WM_HOTKEY后将通过这些ID来确认按下的是哪个键。ClassWizard并没有对消息WM_HOTKEY进行封装,需要手工添加对该消息的映射及处理。消息处理函数的wParam参数包含有按键的ID,下面是这部分实现代码:

switch(wParam) {
 case 1001:
 case 1002:
 {
  // 呼出程序
  HWND hWnd = GetSafeHwnd();
  LONG lStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
  lStyle &= ~WS_POPUP;
  ::SetWindowLong(m_hWnd, GWL_STYLE, lStyle);
  ::ShowWindow(m_hWnd, SW_SHOW);
  CWnd::SetForegroundWindow();
  m_Control.play(); // 继续
  break;
 }
 case 1003:
 case 1004:
 {
  // 隐藏程序
  // 隐藏程序
  HWND hWnd = GetSafeHwnd();
  LONG lStyle = ::GetWindowLong(m_hWnd, GWL_STYLE);
  lStyle |= WS_POPUP;
  ::SetWindowLong(m_hWnd, GWL_STYLE, lStyle);
  ::ShowWindow(m_hWnd, SW_HIDE);
  m_Control.pause(); // 暂停
  break;
 }
}

  在进行窗体隐藏处理时,首先通过GetWindowLong()得到当前窗口风格,在此基础上追加WS_POPUP风格并由SetWindowLong()设置,修改后的窗体将具备工具条一样的风格,即不会在任务栏显示窗体,在用Alt+Tab切换窗体时也不会出现。最后再以SW_HIDE调用ShowWindow()函数隐藏程序主窗口即达到彻底隐藏的目的。窗体呼出过程正与之相反:在GetWindowLong()函数得到当前窗口风格后,从中剔除WS_POPUP风格并由SetWindowLong()设置,恢复程序原有的风格,最后再以SW_SHOW调用ShowWindow()函数显示程序主窗体。最后由CWnd类成员函数SetForegroundWindow()将呼出的程序显示到前台。

  需要注意的是,在程序退出前一定要将先前注册的热键注销,由UnregisterHotKey()函数完成:

HWND hWnd = GetSafeHwnd();
UnregisterHotKey(hWnd, 1001);
UnregisterHotKey(hWnd, 1002);


窗体半透明效果实现

  窗体半透明这一功能实际是为了满足“一心二用”的目的而特别添加的。笔者通常在播放媒体文件时阅读电子图书,将播放软件设置为最前后总是占据不小的屏幕面积并遮挡了不少文字,使阅读变的非常不便。因此才有了将播放软件界面设置为半透明这一想法。

  传统的Windows应用程序想实现半透明效果,一般来说需要处理自己的窗口的WM_Paint消息窗口,比较麻烦。在Windows 2000以上版本的操作系统中提供有一个新的API函数SetLayeredWindowAttributes(),它能很方便的将窗体设置为半透明效果,其函数声明如下:

BOOL SetLayeredWindowAttributes(
 HWND hwnd, // handle to the layered window
 COLORREF crKey, // specifies the color key
 BYTE bAlpha, // value for the blend function
 DWORD dwFlags // action
);

  其中dwFlags有LWA_ALPHA和LWA_COLORKEY两种设置,如果LWA_ALPHA被设置的话,通过bAlpha决定透明度;如果LWA_COLORKEY被设置的话,则指定被透明掉的颜色为crKey,其他颜色则正常显示。为了能够使用该函数,还必须在之前添加预定义语句:

#define WS_EX_LAYERED 0x00080000

  在用GetModuleHandle()装载USER32.DLL模块并调用GetProcAddress()得到函数 SetLayeredWindowAttributes()在User32.dll中的指针后就可以通过SetLayeredWindowAttributes()函数将窗体设置为半透明了:

// 全局变量
typedef BOOL (WINAPI *lpfn) (HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags);
lpfn g_pSetLayeredWindowAttributes;
……
// 获取函数 SetLayeredWindowAttributes 在User32.dll中的指针
HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL"));
g_pSetLayeredWindowAttributes = (lpfn)GetProcAddress(hUser32, "SetLayeredWindowAttributes");
if (g_pSetLayeredWindowAttributes == NULL)
 ::PostQuitMessage(0);
 ……
 // 半透明
 HWND hWnd = GetSafeHwnd();
 LONG lWindowLong = GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED;
 ::SetWindowLong(hWnd, GWL_EXSTYLE, lWindowLong);
 g_pSetLayeredWindowAttributes(hWnd, 0, (BYTE)m_sldAlpha.GetPos(), 2);
 ::RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);

  为了方便控制窗体的透明程度,可添加滑动条控件对其进行控制。经过这样的处理,就可以在播放媒体时不受打扰地继续阅读被其遮挡的文字了。

  小结

  本文通过对Windows Media Player控件的使用实现了Windows Media Player 9.0媒体播放软件所具备的一般功能,并以热键隐藏、呼出窗体和窗体半透明设置为例介绍了个性化编程的一般方法。读者可以根据需要以类似的方式通过对其他软件提供的控件如Realplayer等的使用编写支持其他格式媒体的个性化媒体播放程序。本文所述程序在Windows 2000 Professional 下由Microsoft Visaul C++ 6.0编译调试通过,程序运行环境需要预先安装Windows Media Player 9.0。

http://www.chinabyte.net/SoftChannel/72342371928702976/20040922/1856774.shtml

posted on 2006-01-17 11:16 tqsheng 阅读(501) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理