📄 voltagemeterdlg.cpp
字号:
// VoltageMeterDlg.cpp : implementation file
//
#include "stdafx.h"
#include "VoltageMeter.h"
#include "VoltageMeterDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "usb.h"
#define USBDEV_SHARED_VENDOR 0x16C0 /* VOTI */
#define USBDEV_SHARED_PRODUCT 0x05DC /* Obdev's free shared PID */
static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
{
char buffer[256];
int rval, i;
if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid, buffer, sizeof(buffer), 1000)) < 0)
return rval;
if(buffer[1] != USB_DT_STRING)
return 0;
if((unsigned char)buffer[0] < rval)
rval = (unsigned char)buffer[0];
rval /= 2;
/* lossy conversion to ISO Latin1 */
for(i=1;i<rval;i++)
{
if(i > buflen) /* destination buffer overflow */
break;
buf[i-1] = buffer[2 * i];
if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
buf[i-1] = '?';
}
buf[i-1] = 0;
return i-1;
}
#define PSCMD_ECHO 0
#define PSCMD_GET 1
#define PSCMD_ON 2
#define PSCMD_OFF 3
/* These are the vendor specific SETUP commands implemented by our USB device */
/* PowerSwitch uses the free shared default VID/PID. If you want to see an
* example device lookup where an individually reserved PID is used, see our
* RemoteSensor reference implementation.
*/
#define USB_ERROR_NOTFOUND 1
#define USB_ERROR_ACCESS 2
#define USB_ERROR_IO 3
static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle = NULL;
int errorCode = USB_ERROR_NOTFOUND;
static int didUsbInit = 0;
//Cstring msg;
if(!didUsbInit)
{
didUsbInit = 1;
usb_init();
}
usb_find_busses();
usb_find_devices();
for(bus=usb_get_busses(); bus; bus=bus->next)
{
for(dev=bus->devices; dev; dev=dev->next)
{
if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product)
{
char string[256];
int len;
handle = usb_open(dev); /* we need to open the device in order to query strings */
if(!handle)
{
errorCode = USB_ERROR_ACCESS;
//fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
//AfxMessageBox("Could not open USB device");
continue;
}
if(vendorName == NULL && productName == NULL) /* name does not matter */
{
break;
}
/* now check whether the names match: */
len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string));
if(len < 0)
{
errorCode = USB_ERROR_IO;
//fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
//AfxMessageBox("Could not read USB device manufacturer ");
}
else
{
errorCode = USB_ERROR_NOTFOUND;
/* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */
if(strcmp(string, vendorName) == 0)
{
len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string));
if(len < 0)
{
errorCode = USB_ERROR_IO;
//fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror());
}
else
{
errorCode = USB_ERROR_NOTFOUND;
/* fprintf(stderr, "seen product ->%s<-\n", string); */
if(strcmp(string, productName) == 0)
break;
}
}
}
usb_close(handle);
handle = NULL;
}
}
if(handle)
break;
}
if(handle != NULL)
{
errorCode = 0;
*device = handle;
}
return errorCode;
}
usb_dev_handle *handle = NULL;
unsigned char buffer[8]; //USB data buffer
/////////////////////////////////////////////////////////////////////////////
// CVoltageMeterDlg dialog
CVoltageMeterDlg::CVoltageMeterDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVoltageMeterDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CVoltageMeterDlg)
m_check_1 = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CVoltageMeterDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVoltageMeterDlg)
DDX_Control(pDX, IDC_LCD, m_lcd);
DDX_Check(pDX, IDC_CHECK1, m_check_1);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVoltageMeterDlg, CDialog)
//{{AFX_MSG_MAP(CVoltageMeterDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CHECK1, OnCheck1)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVoltageMeterDlg message handlers
BOOL CVoltageMeterDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_lcd.SetBkColor(RGB(120,130,255));
m_lcd.SetColor(RGB( 110, 120, 240 ),RGB( 20, 20, 20 ));
m_lcd.SetText("--.--");
SetTimer(1,1000,NULL); // detect device
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CVoltageMeterDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CVoltageMeterDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CVoltageMeterDlg::OnCheck1()
{
// TODO: Add your control notification handler code here
UpdateData(true);
if (m_check_1)
{
::SetWindowPos(this->m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); // top view
}
else
{
::SetWindowPos(this->m_hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); // normal view
}
}
void CVoltageMeterDlg::readUSB()
{
int nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
PSCMD_GET, 0, 0, (char *)buffer, sizeof(buffer), 5000);
if(nBytes < 2)
{
UsbErrMessage(nBytes);
KillTimer(2);
SetTimer(1,1000,NULL); // detect device
}
else
{
CString a;
int ad_data = (buffer[0] + buffer[1]*256);
float fOut = (float)((2.56 * ad_data)*10)/1024;
if (fOut < 10)
a.Format(" %2.2f", fOut);
else
a.Format("%2.2f", fOut);
m_lcd.SetText(a);
}
}
void CVoltageMeterDlg::UsbErrMessage(int e)
{
if (handle)
usb_close(handle);
m_lcd.SetText("--.--");
}
void CVoltageMeterDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (nIDEvent == 1)
{
if(usbOpenDevice(&handle, USBDEV_SHARED_VENDOR, "www.icbean.com", USBDEV_SHARED_PRODUCT, "VoltageMeter") != 0)
{
//UsbErrMessage(0);
}
else
{
KillTimer(1);
SetTimer(2,100,NULL);
readUSB();
}
}
else
{
readUSB();
}
CDialog::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -