// usb_toolsDlg.cpp: 实现文件 // #include "pch.h" #include "framework.h" #include "usb_tools.h" #include "usb_toolsDlg.h" #include "afxdialogex.h" #include "DlgScanner.h" #ifdef _DEBUG #define new DEBUG_NEW #endif #include #include #include #include "../../../code_device/hgdriver/hgdev/usb_manager.h" // CusbtoolsDlg 对话框 #pragma warning(disable: 4996) namespace usb { void enum_endpoints(libusb_device* device, std::vector& eps) { libusb_device_descriptor desc; libusb_config_descriptor* conf = NULL; int ret = libusb_get_device_descriptor(device, &desc); if (ret != 0) { return; } for (int i = 0; i < (int)desc.bNumConfigurations; ++i) { ret = libusb_get_config_descriptor(device, i, &conf); if (ret != 0) { continue; } for (int j = 0; j < conf->bNumInterfaces; ++j) { for (int k = 0; k < conf->interface[j].num_altsetting; ++k) { for (int l = 0; l < conf->interface[j].altsetting[k].bNumEndpoints; ++l) { USBEP ep; ep.iface = j; ep.type = conf->interface[j].altsetting[k].endpoint[l].bmAttributes; ep.addr = conf->interface[j].altsetting[k].endpoint[l].bEndpointAddress; ep.packet = conf->interface[j].altsetting[k].endpoint[l].wMaxPacketSize; eps.push_back(std::move(ep)); } } } libusb_free_config_descriptor(conf); } } struct { BYTE type; const wchar_t* str; }g_ep_type[] = { {LIBUSB_TRANSFER_TYPE_BULK, L"Bulk"} , {LIBUSB_TRANSFER_TYPE_BULK_STREAM, L"Bulk Stream"} , {LIBUSB_TRANSFER_TYPE_CONTROL, L"Control"} , {LIBUSB_TRANSFER_TYPE_INTERRUPT, L"Interrupt"} , {LIBUSB_TRANSFER_TYPE_ISOCHRONOUS, L"Isochronous"} }; const wchar_t* ep_type(BYTE type) { for (auto& v : g_ep_type) { if (v.type == type) return v.str; } return L"Unknown type"; } BYTE ep_type(const wchar_t* str) { for (auto& v : g_ep_type) { if (wcsicmp(v.str, str) == 0) return v.type; } return -1; } BYTE from_hex_str(const wchar_t* str, bool* ok) { BYTE v = 0, cnt = 0; if (ok) *ok = false; while (*str && cnt < 2) { if (*str >= L'0' && *str <= L'9') { v <<= 4; v += *str - L'0'; } else if (*str >= L'a' && *str <= L'f') { v <<= 4; v += *str - L'a' + 10; } else if (*str >= L'A' && *str <= L'F') { v <<= 4; v += *str - L'A' + 10; } else { break; } cnt++; str++; } if (ok) *ok = cnt == 2; return v; } static int LIBUSB_CALL usb_pnp(libusb_context* ctx, libusb_device* device, libusb_hotplug_event event, void* user_data) { ONLNSCANNER *pnp = new ONLNSCANNER; HWND owner = (HWND)user_data; libusb_device_descriptor desc; pnp->dev = libusb_ref_device(device); libusb_get_device_descriptor(pnp->dev, &desc); pnp->vid = desc.idVendor; pnp->pid = desc.idProduct; pnp->addr = 0; pnp->scanner = NULL; pnp->family = pnp->display_name = ""; if (!PostMessage(owner, WM_USB_PNP, event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, (LPARAM)pnp)) { libusb_unref_device(pnp->dev); delete pnp; } return 0; } static void custom_usb_event_handler(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry/*whether */, void* user) { ONLNSCANNER* pnp = new ONLNSCANNER; HWND owner = (HWND)user; pnp->dev = libusb_ref_device(device); pnp->vid = vid; pnp->pid = pid; pnp->scanner = NULL; pnp->family = pnp->display_name = ""; if (!PostMessage(owner, WM_USB_PNP, ev == USB_EVENT_DEVICE_ARRIVED, (LPARAM)pnp)) { utils::to_log(LOG_LEVEL_WARNING, "Lost device PNP: %04X:%04X %s\r\n", vid, pid, ev == USB_EVENT_DEVICE_ARRIVED ? "arrival" : "left"); libusb_unref_device(pnp->dev); delete pnp; } } static int transfer(libusb_device_handle* h, BYTE type, BYTE addr, unsigned char* buf, int *len, const wchar_t** desc = NULL, DWORD to = -1) { int ret = -1; const wchar_t* tmp = NULL; if (!desc) desc = &tmp; if (type == LIBUSB_TRANSFER_TYPE_BULK) { *desc = L"Bulk"; ret = libusb_bulk_transfer(h, addr, buf, *len, len, to); } else if (type == LIBUSB_TRANSFER_TYPE_CONTROL) { // ret = libusb_control_transfer() } else if (type == LIBUSB_TRANSFER_TYPE_INTERRUPT) { *desc = L"Interrupt"; ret = libusb_interrupt_transfer(h, addr, buf, *len, len, to); } return ret; } std::wstring now(void) { std::string cur(std::move(chronograph::now())); return std::move(a2u(cur.c_str())); //wchar_t buf[40] = { 0 }; //time_t t = time(NULL); //tm* lt = localtime(&t); //swprintf_s(buf, _countof(buf) - 1, L"%04d-%02d-%02d %02d:%02d:%02d", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec); //return buf; } const wchar_t* error_name(int err, wchar_t* unk) { #define RETURN_IF(e) \ if(err == e) \ return L###e; RETURN_IF(LIBUSB_SUCCESS); RETURN_IF(LIBUSB_ERROR_IO); RETURN_IF(LIBUSB_ERROR_INVALID_PARAM); RETURN_IF(LIBUSB_ERROR_ACCESS); RETURN_IF(LIBUSB_ERROR_NO_DEVICE); RETURN_IF(LIBUSB_ERROR_NOT_FOUND); RETURN_IF(LIBUSB_ERROR_BUSY); RETURN_IF(LIBUSB_ERROR_TIMEOUT); RETURN_IF(LIBUSB_ERROR_OVERFLOW); RETURN_IF(LIBUSB_ERROR_PIPE); RETURN_IF(LIBUSB_ERROR_INTERRUPTED); RETURN_IF(LIBUSB_ERROR_NO_MEM); RETURN_IF(LIBUSB_ERROR_NOT_SUPPORTED); RETURN_IF(LIBUSB_ERROR_OTHER); //RETURN_IF(LIBUSB_ERROR_TRY_AGAIN); if (unk) { swprintf(unk, L"%d", err); return unk; } wchar_t buf[20] = { 0 }; swprintf_s(buf, _countof(buf) - 1, L"%d", err); return buf; } INTER_MODULE_CALLBACK(got_wstr) { *((std::wstring*)param) += std::wstring((const wchar_t*)data, len / 2); return inter_module_data::SET_RESULT_CONTINUE; } INTER_MODULE_CALLBACK(got_str) { *((std::string*)param) += std::string(data, len); return inter_module_data::SET_RESULT_CONTINUE; } std::wstring a2u(const char* ansi) { std::wstring u(L""); coding_util::ansi_2_unicode(ansi, got_wstr, &u); return std::move(u); } std::string u2a(const wchar_t* unic) { std::string a(""); coding_util::unicode_2_ansi(unic, got_str, &a); return std::move(a); } bool get_file_time(const char* file, LPSYSTEMTIME pcreate, LPSYSTEMTIME pmodify, LPSYSTEMTIME paccess) { bool ret = false; HANDLE h = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); while (h != INVALID_HANDLE_VALUE) { FILETIME c = { 0 }, m = { 0 }, a = { 0 }, l = { 0 }; if (GetFileTime(h, &c, &a, &m)) { if (pcreate) { if (FileTimeToLocalFileTime(&c, &l)) { ret = FileTimeToSystemTime(&l, pcreate) == TRUE; if (!ret) break; } } if (pmodify) { if (FileTimeToLocalFileTime(&m, &l)) { ret = FileTimeToSystemTime(&l, pmodify) == TRUE; if (!ret) break; } } if (paccess) { if (FileTimeToLocalFileTime(&a, &l)) { ret = FileTimeToSystemTime(&l, paccess) == TRUE; if (!ret) break; } } } CloseHandle(h); break; } return ret; } static void register_tray(HWND owner, HICON icon, bool reg) { if(reg) win_util::add_tray_icon(WM_TRAY_MSG, owner, WM_TRAY_MSG, L"Operate on USB device", icon); else win_util::remove_tray_icon(WM_TRAY_MSG, owner); } } CusbtoolsDlg::CusbtoolsDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_USB_TOOLS_DIALOG, pParent) { log_file_ = utils::init_log(LOG_TYPE_FILE); utils::to_log(LOG_LEVEL_DEBUG, "System info: page = %u, mapping-size = %u, disk-cluster-size = %u\r\n", global_info::page_size, global_info::page_map_size, global_info::cluster_size); { //FILE* dst = fopen("D:\\boxroom\\usb-tx-file\\tx\\test.txt", "wb"); //int pos = 0; // //fwrite("T", 1, 100, dst); //pos = ftell(dst); //pos = fseek(dst, 0, SEEK_SET); //pos = fseek(dst, 1024, SEEK_SET); //fclose(dst); } m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } CusbtoolsDlg::~CusbtoolsDlg() { usb_manager::instance()->register_hotplug(NULL, NULL); usb_manager::clear(); remove_pnp_que(); utils::uninit(); } void CusbtoolsDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST_DEVICES, devl_); } BEGIN_MESSAGE_MAP(CusbtoolsDlg, CDialogEx) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_CHECK_AUTO_MON, &CusbtoolsDlg::OnBnClickedCheckAutoMon) ON_MESSAGE(WM_USB_PNP, &CusbtoolsDlg::OnUsbPnp) ON_MESSAGE(WM_RCV_MSG, &CusbtoolsDlg::OnRcvMsg) ON_MESSAGE(WM_OPENNING_DLG_CLOSED, &CusbtoolsDlg::OnDevDlgClosed) ON_MESSAGE(WM_TRAY_MSG, &CusbtoolsDlg::OnTray) ON_NOTIFY(NM_DBLCLK, IDC_LIST_DEVICES, &CusbtoolsDlg::OnNMDblclkListDevices) ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CusbtoolsDlg::OnBnClickedButtonClear) ON_WM_SYSCOMMAND() ON_COMMAND(ID_TRAY_EXIT, &CusbtoolsDlg::OnTrayExit) ON_COMMAND_RANGE(ID_TRAY_EXIT + 1, ID_TRAY_EXIT + 100, &CusbtoolsDlg::OnTrayDevice) ON_BN_CLICKED(IDOK, &CusbtoolsDlg::OnBnClickedOk) ON_WM_SIZE() END_MESSAGE_MAP() // CusbtoolsDlg 消息处理程序 bool show_balloon(int tray_id, HWND main_wnd, const wchar_t* tips, const wchar_t* title, DWORD dwTimeout, HICON hIcon, DWORD dwInfoFlag) { NOTIFYICONDATAW nid = { 0 }; nid.cbSize = NOTIFYICONDATA_V2_SIZE; // KEY parameter to show balloon message! //nid.uVersion = NOTIFYICON_VERSION; nid.hWnd = main_wnd; nid.uID = tray_id; nid.uFlags = /*NIF_INFO |*/ NIF_TIP; wcscpy_s(nid.szTip, _countof(nid.szTip) - 1, tips); wcscpy_s(nid.szInfoTitle, _countof(nid.szInfoTitle) - 1, title); nid.hIcon = hIcon ? hIcon : (HICON)SendMessageW(main_wnd, WM_GETICON, ICON_SMALL, 0); nid.uTimeout = dwTimeout; nid.dwInfoFlags = dwInfoFlag; return Shell_NotifyIconW(NIM_MODIFY, &nid) == TRUE; } BOOL CusbtoolsDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 int ind = 0; devl_.InsertColumn(ind++, TEXT("No."), 0, 51); devl_.InsertColumn(ind++, TEXT("VID"), 0, 75); devl_.InsertColumn(ind++, TEXT("PID"), 0, 75); devl_.SetExtendedStyle(devl_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP); //SetDlgItemInt(IDC_EDIT_TYPE, 0x40); //SetDlgItemInt(IDC_EDIT_REQ, 0x64); //SetDlgItemInt(IDC_EDIT_VALUE, 16); //SetDlgItemInt(IDC_EDIT_INDEX, 0); //SetDlgItemInt(IDC_EDIT_LEN, 20); OnBnClickedCheckAutoMon(); tray_ = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1)); desktop_ = ::FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); usb::register_tray(m_hWnd, m_hIcon, true); SetPropW(m_hWnd, L"task_usb", m_hWnd); ::SetDlgItemTextA(m_hWnd, IDC_EDIT_LOG_FILE, log_file_.c_str()); usb_manager::instance()->register_hotplug(&usb::custom_usb_event_handler, (void*)m_hWnd); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CusbtoolsDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 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; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CusbtoolsDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } void CusbtoolsDlg::enable_io_ui(bool enable) { GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(enable); GetDlgItem(IDC_CHECK_AUTO)->EnableWindow(enable); enable &= ((CButton*)GetDlgItem(IDC_CHECK_AUTO))->GetCheck() != BST_CHECKED; GetDlgItem(IDC_BUTTON_RECEIVE)->EnableWindow(enable); //GetDlgItem(IDC_COMBO_EP2)->EnableWindow(enable); //OnCbnSelchangeComboEp(); //GetDlgItem(IDC_EDIT_TYPE)->EnableWindow(enable); //GetDlgItem(IDC_EDIT_REQ)->EnableWindow(enable); //GetDlgItem(IDC_EDIT_VALUE)->EnableWindow(enable); //GetDlgItem(IDC_EDIT_INDEX)->EnableWindow(enable); //GetDlgItem(IDC_EDIT_LEN)->EnableWindow(enable); } void CusbtoolsDlg::add_pnp_que(ONLNSCANNER* pnp) { int vid = pnp->vid, pid = pnp->pid; bool add = true; for (auto& v : pnp_que_) { if (v.usb.dev == pnp->dev) { libusb_unref_device(pnp->dev); if (v.dlg) { open_usb(v, false); } add = false; break; } } if (add) { SCANNER scnr; scnr.usb = *pnp; scnr.dlg = NULL; scnr.id = InterlockedIncrement(&id_); pnp_que_.push_back(scnr); // add to UI ... int item = devl_.InsertItem(devl_.GetItemCount(), std::to_wstring(devl_.GetItemCount() + 1).c_str()); TCHAR text[40] = { 0 }; _stprintf(text, TEXT("%04X"), pnp->vid); devl_.SetItemText(item, 1, text); _stprintf(text, TEXT("%04X"), pnp->pid); devl_.SetItemText(item, 2, text); devl_.SetItemData(item, (DWORD_PTR)scnr.id); } if (!IsWindowVisible()) { wchar_t tips[128] = { 0 }; swprintf_s(tips, _countof(tips) - 1, L"%04X:%04X arrived", vid, pid); show_balloon(WM_TRAY_MSG, m_hWnd, tips, L"USB", 1000, m_hIcon, NIF_TIP); } } void CusbtoolsDlg::remove_pnp_que(ONLNSCANNER* pnp) { for (size_t i = 0; i < pnp_que_.size(); ++i) { if (!pnp || (pnp_que_[i].usb.dev == pnp->dev)) { if (IsWindow(devl_.m_hWnd)) { for (int j = 0; j < devl_.GetItemCount(); ++j) { if (!pnp || devl_.GetItemData(j) == (DWORD_PTR)pnp_que_[i].id) { //if (devl_.GetItemState(j, LVIS_SELECTED)) // enable_io_ui(false); if (pnp_que_[i].dlg == NULL) { devl_.SetItemData(j, 0); devl_.DeleteItem(j); for (; pnp && j < devl_.GetItemCount(); ++j) devl_.SetItemText(j, 0, std::to_wstring(j + 1).c_str()); } if (pnp) break; } } } if (pnp_que_[i].dlg && IsWindow(pnp_que_[i].dlg->m_hWnd)) { pnp_que_[i].dlg->set_device(NULL); //if(!pnp) //{ // pnp_que_[i].dlg->DestroyWindow(); // delete pnp_que_[i].dlg; // pnp_que_[i].dlg = NULL; //} } libusb_unref_device(pnp_que_[i].usb.dev); close_device(pnp_que_[i]); if (pnp) { if(pnp_que_[i].dlg == NULL) pnp_que_.erase(pnp_que_.begin() + i); break; } else { if (pnp_que_[i].dlg) { delete pnp_que_[i].dlg; pnp_que_[i].dlg = NULL; } } } } if (IsWindow(m_hWnd) && !IsWindowVisible() && pnp) { wchar_t tips[128] = { 0 }; swprintf_s(tips, _countof(tips) - 1, L"%04X:%04X left", pnp->vid, pnp->pid); show_balloon(WM_TRAY_MSG, m_hWnd, tips, L"USB", 1000, m_hIcon, NIF_TIP); } } void CusbtoolsDlg::append_log(const wchar_t* log, UINT id) { if (!IsWindow(m_hWnd)) return; int len = ::GetWindowTextLength(GetDlgItem(id)->m_hWnd); wchar_t* buf = new wchar_t[len + 128]; libusb_device_descriptor desc; ::GetDlgItemTextW(m_hWnd, id, buf, len + 20); ::SetDlgItemTextW(m_hWnd, id, (std::wstring(buf) + log).c_str()); while (::SendMessage(GetDlgItem(id)->m_hWnd, EM_SCROLL, SB_PAGEDOWN, 0)); delete[] buf; } void CusbtoolsDlg::log_pnp(ONLNSCANNER* pnp, bool arrive) { wchar_t buf[128] = { 0 }; swprintf_s(buf + lstrlenW(buf), _countof(buf) - 1, L"%s: %04X:%04X %s\r\n", usb::now().c_str(), pnp->vid, pnp->pid, arrive ? L"Arrive" : L"Left"); append_log(buf, IDC_EDIT_PNP_MSG); utils::to_log(LOG_LEVEL_ALL, "%04X:%04X %s\r\n", pnp->vid, pnp->pid, arrive ? "Arrived" : "Left"); } bool CusbtoolsDlg::endpoint_from_combo_text(wchar_t* text, BYTE& type, BYTE& addr) { wchar_t* ptr = wcsstr(text, L" "); bool ret = false; if (ptr) { *ptr++ = 0; type = usb::ep_type(text); if (type != -1) { ptr = wcsstr(ptr, L"-"); if (ptr++) { while (*ptr == L' ') ptr++; addr = usb::from_hex_str(ptr, &ret); } } } return ret; } void CusbtoolsDlg::close_device(SCANNER& pnp) { wchar_t msg[128] = { 0 }; swprintf_s(msg, _countof(msg) - 1, L"%s: %04X:%04X closed.\r\n", usb::now().c_str(), pnp.usb.vid, pnp.usb.pid); append_log(msg, IDC_EDIT_PNP_MSG); } ONLNSCANNER* CusbtoolsDlg::get_cur_device(void) { for (int i = 0; i < devl_.GetItemCount(); ++i) { if (devl_.GetItemState(i, LVIS_SELECTED)) return (ONLNSCANNER*)devl_.GetItemData(i); } return NULL; } void CusbtoolsDlg::open_usb(SCANNER& pnp, bool from_list) { wchar_t msg[256] = { 0 }, errb[40] = { 0 }; int face = -1, ret = 0; //* if (pnp.dlg == NULL) { pnp.dlg = new CDlgScanner(this); // new CDlgOpenning(this); pnp.dlg->Create(IDD_SCANNER); // (IDD_OPENNING); } pnp.usb.addr = libusb_get_device_address(pnp.usb.dev); pnp.dlg->set_device(&pnp.usb); pnp.dlg->ShowWindow(SW_SHOW); if (!msg[0]) swprintf_s(msg, _countof(msg) - 1, L"%s: open %04X:%04X success\r\n", usb::now().c_str(), pnp.usb.vid, pnp.usb.pid); else if (!from_list) ::MessageBoxW(m_hWnd, msg, L"Failed", MB_OK | MB_ICONERROR); append_log(msg, IDC_EDIT_PNP_MSG); } LRESULT CusbtoolsDlg::OnUsbPnp(WPARAM wp, LPARAM lp) { ONLNSCANNER *pnp = (ONLNSCANNER*)lp; log_pnp(pnp, wp); if (pnp->pid == 0 && pnp->vid == 0) { libusb_unref_device(pnp->dev); delete pnp; return 0; } if (wp) { ////for (auto& v : pnp_que_) ////{ //// if (v->ctx == pnp->ctx && v->device == pnp->device) //// { //// libusb_unref_device(pnp->device); //// v->arrive = true; //// delete pnp; //// pnp = NULL; //// break; //// } ////} //if (pnp) add_pnp_que(pnp); } else { remove_pnp_que(pnp); // libusb_unref_device(pnp->device); } delete pnp; return 0; } LRESULT CusbtoolsDlg::OnRcvMsg(WPARAM wp, LPARAM lp) { std::wstring* msg = (std::wstring*)lp; //append_log(msg->c_str(), IDC_EDIT_REPLY); delete msg; return 0; } LRESULT CusbtoolsDlg::OnDevDlgClosed(WPARAM wp, LPARAM lp) { CDlgScanner* dlg = (CDlgScanner*)lp; //CDlgOpenning* dlg = (CDlgOpenning*)lp; for (int i = 0; i < pnp_que_.size(); ++i) { if (pnp_que_[i].dlg == dlg) { bool online = dlg->is_online(); pnp_que_[i].dlg = NULL; close_device(pnp_que_[i]); if (!online) { remove_pnp_que(&pnp_que_[i].usb); } break; } } dlg->DestroyWindow(); delete dlg; return 0; } LRESULT CusbtoolsDlg::OnTray(WPARAM wp, LPARAM lp) { UINT msg = (UINT)lp; if (msg == WM_LBUTTONDBLCLK) { ShowWindow(SW_RESTORE); SetForegroundWindow(); if (MAKELPARAM(MAKEWORD('P', 'O'), MAKEWORD('P', 'M')) == wp) { HWND taskwnd = ::FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); if (desktop_ != taskwnd && IsWindow(taskwnd)) { usb::register_tray(m_hWnd, m_hIcon, true); desktop_ = taskwnd; } } } else if (msg == WM_RBUTTONDOWN) { // exit ... POINT pt = { 0 }; HMENU hm = GetSubMenu(tray_, 0); MENUITEMINFOW mi = { 0 }; mi.cbSize = sizeof(mi); mi.fMask = MIIM_DATA; while (GetMenuItemInfoW(hm, 0, TRUE, &mi) && mi.dwItemData) DeleteMenu(hm, 0, MF_BYPOSITION); for (int i = 0; i < devl_.GetItemCount(); ++i) { int tid = (int)devl_.GetItemData(i), vid = 0, pid = 0; wchar_t id[40] = { 0 }; bool openned = false; for (auto& v : pnp_que_) { if (v.id == tid) { vid = v.usb.vid; pid = v.usb.pid; openned = v.dlg != NULL; break; } } swprintf_s(id, _countof(id) - 1, L"%04X:%04X", vid, pid); InsertMenuW(hm, i, MF_BYPOSITION, ID_TRAY_EXIT + 1 + i, id); mi.dwItemData = (LONG)tid; SetMenuItemInfoW(hm, i, TRUE, &mi); if (openned) CheckMenuItem(hm, i, MF_CHECKED | MF_BYPOSITION); } GetCursorPos(&pt); TrackPopupMenu(hm, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL); } return 0; } void CusbtoolsDlg::OnBnClickedCheckAutoMon() { // TODO: 在此添加控件通知处理程序代码 static libusb_hotplug_callback_handle handle = NULL; //if (ctx_) //{ // libusb_context* cp = ctx_; // mon_ = false; // ctx_ = NULL; // if (mon_thrd_.get() && mon_thrd_->joinable()) // mon_thrd_->join(); // mon_thrd_.reset(); // libusb_hotplug_deregister_callback(cp, handle); // libusb_exit(cp); // handle = NULL; //} //else //{ // libusb_init(&ctx_); // int ret = libusb_hotplug_register_callback(ctx_, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), // (libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE, // LIBUSB_HOTPLUG_MATCH_ANY,//LIBUSB_HOTPLUG_MATCH_ANY // LIBUSB_HOTPLUG_MATCH_ANY,//LIBUSB_HOTPLUG_MATCH_ANY, // LIBUSB_HOTPLUG_MATCH_ANY, // &usb::usb_pnp, // m_hWnd, // &handle); // mon_ = true; // mon_thrd_.reset(new std::thread(&CusbtoolsDlg::usb_monitor_thread, this)); //} } void CusbtoolsDlg::OnNMDblclkListDevices(NMHDR* pNMHDR, LRESULT* pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); // TODO: 在此添加控件通知处理程序代码 *pResult = 0; if (pNMItemActivate->iItem < 0 || pNMItemActivate->iItem >= devl_.GetItemCount()) return; wchar_t msg[256] = { 0 }, unk[40] = { 0 }; int tid = (int)devl_.GetItemData(pNMItemActivate->iItem); int face = -1, ret = 0; SCANNER* pnp = NULL; for (auto& v : pnp_que_) { if (v.id == tid) { pnp = &v; break; } } if (!pnp) return; if (!pnp->dlg) { open_usb(*pnp); } else { RECT r = { 0 }; pnp->dlg->GetWindowRect(&r); ::SetWindowPos(pnp->dlg->m_hWnd, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOSENDCHANGING | SWP_SHOWWINDOW); ::SetTimer(pnp->dlg->m_hWnd, WM_TIMER_CANCEL_TOPMOST, 1000, NULL); } } void CusbtoolsDlg::OnBnClickedButtonClear() { // TODO: 在此添加控件通知处理程序代码 SetDlgItemText(IDC_EDIT_PNP_MSG, TEXT("")); } void CusbtoolsDlg::OnSysCommand(UINT nID, LPARAM lParam) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (nID == SC_CLOSE) { ShowWindow(SW_MINIMIZE); ShowWindow(SW_HIDE); return; } CDialogEx::OnSysCommand(nID, lParam); } void CusbtoolsDlg::OnTrayExit() { // TODO: 在此添加命令处理程序代码 usb::register_tray(m_hWnd, m_hIcon, false); PostQuitMessage(0); } void CusbtoolsDlg::OnTrayDevice(UINT id) { // TODO: 在此添加命令处理程序代码 HMENU hm = GetSubMenu(tray_, 0); MENUITEMINFOW mi = { 0 }; mi.cbSize = sizeof(mi); mi.fMask = MIIM_DATA | MIIM_STATE; GetMenuItemInfoW(hm, id, FALSE, &mi); if (mi.dwItemData) { SCANNER* pnp = NULL; for (auto& v : pnp_que_) { if (v.id == (int)mi.dwItemData) { pnp = &v; break; } } if (!pnp) return; if (pnp->dlg) pnp->dlg->OnBnClickedOk(); else open_usb(*pnp, false); } } void CusbtoolsDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 OnTrayExit(); CDialogEx::OnOK(); } void CusbtoolsDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); // TODO: 在此处添加消息处理程序代码 //if (cx == 0 && cy == 0 && ::IsWindow(devl_.m_hWnd)) //{ // for (int i = 0; i < devl_.GetItemCount(); ++i) // { // ONLNSCANNER* pnp = (ONLNSCANNER*)devl_.GetItemData(i); // if (pnp && pnp->dlg) // pnp->dlg->ShowWindow(SW_SHOW); // } //} }