基于Cy68013的USB设备在VC程序中热插拔的实现
2009-06-05 20:21
555 查看
开发基于Cy68013的USB设备已经有一段时间,虽然知道它可以支持即插即用,但是一直没有去设计相关的代码,只是在MFC中设计了一个名为“USB连接”的按钮来手动连接到USB设备(参考《USB应用开发技术大全》薛园园编著 人民邮电出版社,2007)。最近又去翻看Cy68013的帮助文档,发现了支持插即用的相关代码,于是试验了一下,基本解决了基于Cy68013的USB设备的PnP功能。
在CyAPI的帮助文件中,对于提供的USB设备类CCyUSBDevice有一段这样的解释:
CCyUSBDevice::CCyUSBDevice(HANDLE hnd = NULL, GUID guid = CYUSBDRV_GUID)
* This is the constructor for the CCyUSBDevice class.
* It registers the window of hnd to receive USB Plug and Play messages when devices are onnected or disconnected to/from the driver.
* The object created serves as the programming interface to the driver whose GUID is passed in the guid parameter.
可见,在构建类的对象时给定其HANDLE之后便可以支持USB即插即用。
在CyAPI的帮助文件中还给出了代码示例(虽然是c++ Builder的代码,但对VC程序还是有借鉴作用的)。代码如下:
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
USBDevice = new CCyUSBDevice(Handle);
CurrentEndPt = USBDevice->ControlEndPt;
}
// Overload MainForm's WndProc method to watch for PnP messages
// Requires #include <dbt.h>
void __fastcall TMainForm::WndProc(TMessage &Message)
{
if (Message.Msg == WM_DEVICECHANGE) {
// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (Message.WParam == DBT_DEVICEARRIVAL) {
bPnP_Arrival = true;
bPnP_DevNodeChange = false;
}
// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (Message.WParam == DBT_DEVNODES_CHANGED) {
bPnP_DevNodeChange = true;
bPnP_Removal = false;
}
if (Message.WParam == DBT_DEVICEREMOVECOMPLETE) {
bPnP_Removal = true;
PDEV_BROADCAST_HDR bcastHdr = (PDEV_BROADCAST_HDR) Message.LParam;
if (bcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE) {
PDEV_BROADCAST_HANDLE pDev = (PDEV_BROADCAST_HANDLE) Message.LParam;
if (pDev->dbch_handle == USBDevice->DeviceHandle())
USBDevice->Close();
}
}
// If DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (bPnP_Removal && bPnP_DevNodeChange) {
Sleep(10);
DisplayDevices();
bPnP_Removal = false;
bPnP_DevNodeChange = false;
}
// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (bPnP_DevNodeChange && bPnP_Arrival) {
DisplayDevices();
bPnP_Arrival = false;
bPnP_DevNodeChange = false;
}
}
TForm::WndProc(Message);
}
可以看出,程序通过重载WndProc来实现USB设备的相关通知(“Overload MainForm's WndProc method to watch for PnP messages ”), 而在VC下也是有这个函数的,仿照上述代码,可以编写代码如下:
LRESULT C**IDlg::WindowProc(UINT message,WPARAM wParam,LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
if (message == WM_DEVICECHANGE)
{
// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (wParam == DBT_DEVICEARRIVAL)
{
bPnP_Arrival = true;
bPnP_DevNodeChange = false;
}
// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (wParam == DBT_DEVNODES_CHANGED)
{
bPnP_DevNodeChange = true;
bPnP_Removal = false;
}
if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
bPnP_Removal = true;
// PDEV_BROADCAST_HDR bcastHdr = (PDEV_BROADCAST_HDR) lParam;
// if (bcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE)
{
// PDEV_BROADCAST_HANDLE pDev = (PDEV_BROADCAST_HANDLE) lParam;
// DEV_BROADCAST_HDR *stHDR;
// stHDR = (DEV_BROADCAST_HDR *)lParam;
//if (pDev->dbch_handle == USBDevice->DeviceHandle()) //判断设备类型
//if (stHDR->dbch_handle == USBDevice->DeviceHandle())
// USBDevice->Close();
}
}
// If DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (bPnP_Removal && bPnP_DevNodeChange)
{
Sleep(10);
DisplayDevices();
bPnP_Removal = false;
bPnP_DevNodeChange = false;
}
// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (bPnP_DevNodeChange && bPnP_Arrival)
{
DisplayDevices();
bPnP_Arrival = false;
bPnP_DevNodeChange = false;
}
}
return CDialog::WindowProc(message,wParam,lParam);
}
然而该段代码并没有指明产生USB消息的设备类型,因此任何USB设备的插拔都会引起程序的相应,为了准确识别到Cy68013的USB设备特别编写了代码中加粗的DisplayDevices(),代码如下:
void CECHWorkStationIIDlg::DisplayDevices()
{
if(USBDevice->IsOpen())
{
USBDevice->Open(0);
if(!USBDevice->IsOpen())
{
USBDevice->Close();
m_USBStatus = "未连接到仪器";
UpdateData(FALSE);
// MessageBox("USB设备移除。/n","USB connect",MB_OK|MB_ICONERROR);
}
}
else
{
USBDevice->Open(0);
if(USBDevice->IsOpen())
{
m_USBStatus = USBDevice->DeviceName;
UpdateData(FALSE);
if(USBDevice->DeviceCount()>1)
MessageBox("应用程序不支持多台仪器同时连接到电脑。/n请移除不必要的仪器!/n","出错",MB_OK|MB_ICONERROR);
}
}
}
这样就实现了CY68013设备的热插拔。
上述内容只是提供了一种解决CY68013 USB设备的一种方法。更多方法欢迎大家一起讨论!
在CyAPI的帮助文件中,对于提供的USB设备类CCyUSBDevice有一段这样的解释:
CCyUSBDevice::CCyUSBDevice(HANDLE hnd = NULL, GUID guid = CYUSBDRV_GUID)
* This is the constructor for the CCyUSBDevice class.
* It registers the window of hnd to receive USB Plug and Play messages when devices are onnected or disconnected to/from the driver.
* The object created serves as the programming interface to the driver whose GUID is passed in the guid parameter.
可见,在构建类的对象时给定其HANDLE之后便可以支持USB即插即用。
在CyAPI的帮助文件中还给出了代码示例(虽然是c++ Builder的代码,但对VC程序还是有借鉴作用的)。代码如下:
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
USBDevice = new CCyUSBDevice(Handle);
CurrentEndPt = USBDevice->ControlEndPt;
}
// Overload MainForm's WndProc method to watch for PnP messages
// Requires #include <dbt.h>
void __fastcall TMainForm::WndProc(TMessage &Message)
{
if (Message.Msg == WM_DEVICECHANGE) {
// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (Message.WParam == DBT_DEVICEARRIVAL) {
bPnP_Arrival = true;
bPnP_DevNodeChange = false;
}
// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (Message.WParam == DBT_DEVNODES_CHANGED) {
bPnP_DevNodeChange = true;
bPnP_Removal = false;
}
if (Message.WParam == DBT_DEVICEREMOVECOMPLETE) {
bPnP_Removal = true;
PDEV_BROADCAST_HDR bcastHdr = (PDEV_BROADCAST_HDR) Message.LParam;
if (bcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE) {
PDEV_BROADCAST_HANDLE pDev = (PDEV_BROADCAST_HANDLE) Message.LParam;
if (pDev->dbch_handle == USBDevice->DeviceHandle())
USBDevice->Close();
}
}
// If DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (bPnP_Removal && bPnP_DevNodeChange) {
Sleep(10);
DisplayDevices();
bPnP_Removal = false;
bPnP_DevNodeChange = false;
}
// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (bPnP_DevNodeChange && bPnP_Arrival) {
DisplayDevices();
bPnP_Arrival = false;
bPnP_DevNodeChange = false;
}
}
TForm::WndProc(Message);
}
可以看出,程序通过重载WndProc来实现USB设备的相关通知(“Overload MainForm's WndProc method to watch for PnP messages ”), 而在VC下也是有这个函数的,仿照上述代码,可以编写代码如下:
LRESULT C**IDlg::WindowProc(UINT message,WPARAM wParam,LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
if (message == WM_DEVICECHANGE)
{
// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (wParam == DBT_DEVICEARRIVAL)
{
bPnP_Arrival = true;
bPnP_DevNodeChange = false;
}
// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (wParam == DBT_DEVNODES_CHANGED)
{
bPnP_DevNodeChange = true;
bPnP_Removal = false;
}
if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
bPnP_Removal = true;
// PDEV_BROADCAST_HDR bcastHdr = (PDEV_BROADCAST_HDR) lParam;
// if (bcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE)
{
// PDEV_BROADCAST_HANDLE pDev = (PDEV_BROADCAST_HANDLE) lParam;
// DEV_BROADCAST_HDR *stHDR;
// stHDR = (DEV_BROADCAST_HDR *)lParam;
//if (pDev->dbch_handle == USBDevice->DeviceHandle()) //判断设备类型
//if (stHDR->dbch_handle == USBDevice->DeviceHandle())
// USBDevice->Close();
}
}
// If DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
if (bPnP_Removal && bPnP_DevNodeChange)
{
Sleep(10);
DisplayDevices();
bPnP_Removal = false;
bPnP_DevNodeChange = false;
}
// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
if (bPnP_DevNodeChange && bPnP_Arrival)
{
DisplayDevices();
bPnP_Arrival = false;
bPnP_DevNodeChange = false;
}
}
return CDialog::WindowProc(message,wParam,lParam);
}
然而该段代码并没有指明产生USB消息的设备类型,因此任何USB设备的插拔都会引起程序的相应,为了准确识别到Cy68013的USB设备特别编写了代码中加粗的DisplayDevices(),代码如下:
void CECHWorkStationIIDlg::DisplayDevices()
{
if(USBDevice->IsOpen())
{
USBDevice->Open(0);
if(!USBDevice->IsOpen())
{
USBDevice->Close();
m_USBStatus = "未连接到仪器";
UpdateData(FALSE);
// MessageBox("USB设备移除。/n","USB connect",MB_OK|MB_ICONERROR);
}
}
else
{
USBDevice->Open(0);
if(USBDevice->IsOpen())
{
m_USBStatus = USBDevice->DeviceName;
UpdateData(FALSE);
if(USBDevice->DeviceCount()>1)
MessageBox("应用程序不支持多台仪器同时连接到电脑。/n请移除不必要的仪器!/n","出错",MB_OK|MB_ICONERROR);
}
}
}
这样就实现了CY68013设备的热插拔。
上述内容只是提供了一种解决CY68013 USB设备的一种方法。更多方法欢迎大家一起讨论!
相关文章推荐
- VC++下实现2048总结(基于控制台和对话框两个程序)
- 基于STM32的USB程序开发笔记(四)——USB设备的枚举(上)
- VC编程实现与usb设备通信:计算机向单片机发送
- vc++实现控制USB设备启用与否
- vc++实现控制USB设备启用与否
- [精通WindowsSocket网络开发-基于VC++实现]第三章——WindowsSockets基础—TCP,UDP程序
- [精通WindowsSocket网络开发-基于VC++实现]第三章——WindowsSockets基础—TCP,UDP程序 .
- vc++实现控制USB设备启用与否
- 基于VC实现的网络监听功能程序实例
- 基于libUSB的USB设备固件更新程序(下载数据)(转)
- VC++实现USB 硬盘等硬件插拔检测
- vc++实现控制USB设备启用与否
- VC++基于Dx实现的截图程序示例代码
- 基于libUSB的USB设备固件更新程序(数据传输部分)
- USB--平台搭建--1--vc 6.0中开发驱动设备程序配置
- 基于VC++2010利用API函数MoveFileEx实现程序的隐藏、自启动与自删除
- [精通WindowsSocket网络开发-基于VC++实现]第三章——WindowsSockets基础—TCP,UDP程序
- 基于libUSB的USB设备固件更新程序(数据传输部分)
- VC实现基于Office 2007 MODI 12.0实现图形文字识别(OCR)的程序
- [精通WindowsSocket网络开发-基于VC++实现]第三章——WindowsSockets基础—TCP,UDP程序