(windowSDK及MFC在学校时学过,工作后接触太少,都忘了。)
一、对mixerAPI封装的一个DLL,实现获取系统声音变化通知时遇到的问题及相关思考
mixerOpen中传入HWND参数,当系统音量变化时,HWND参数对应的窗体会收到MM_MIXM_CONTROL_CHANGE消息。wParam为hMixer,通过它确定设备。lParam为dwControlID,通过它可以确定是音量控件发生变化。MSDN中有更详细描述,勿用饶舌。
通过windowSDK的CreateWindowEx建立了一个窗体,并设置其结构体参数WNDCLASSEX的lpszClassName,注册一个消息处理函数。使用ShowWindow设置SW_HIDE隐藏窗体。调用mixerAPI的一些函数,保存好输入、输出设备和各自音量控件的信息后,调用GetMessage获取消息。
由于GetMessage是阻塞函数,不能直接在DLL的接口函数中调用。所以只能在接口中另开线程了。而消息又是线程相关的,故从创建窗体的动作开始,就应该丢入新线程中处理。
伪代码如下。
接口() { 开启线程B 等待B发出的初始化结束信号量 函数返回 } 线程B() { 创建窗口 初始化mixer,保存好相关信息 发送初始化结束信号量 死循环GetMessage() }
关闭线程B及所创建的窗体的方法是:
1.通过HWND给窗体发送WM_CLOSE消息
2.在消息处理函数中处理WM_CLOSE,调用PostQuitMessage
GetMessage在收到PostQuitMessage发出的WM_QUIT消息后,返回FALSE,退出死循环,线程B也即结束了。
在上回的blog中说过,不同操作系统(也有可能是声卡的关系)所能拿到的控件不同。现在发现在不同操作系统中,所能获取到的消息也不同。我的同一段代码,在三台机器上测试,win7以及xp可以顺利获取到输入、输出音量设置的变化。但在2003的机器上只能获取到输出音量的变化。
我又去试了试QQ,它音视频设置面板中的输入音量在三台机器上都能随系统控制面板中的变化而变化,输出都不行。囧。不知是它产品设计就是这样还是功能不完善。
二、CFileDialog
http://msdn.microsoft.com/en-us/library/dk77e5e7(v=VS.80).aspx
在隐藏的窗体中,收到信令后,创建一个CFileDialog用于保存文件。前置CFileDialog窗体的方法。
1.设置CFileDialog的父窗体为桌面 CWnd::FromHandle(::GetDesktopWindow())//获取桌面的CWnd 2.设置前置,方法有两种 SetWindowPos SetForegroundWindow 还有一个设置焦点窗体的函数 SetActiveWindow
window与窗体相关的函数都比较有意思,一般有两套同名函数。一套为全局函数,需要你自己传入HWND,在Dialog类中调用的方法是加上::,如::SetWindowPos。另一套为Dialog类的成员函数,默认使用自己的HWND。