Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

575 lines
14 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1993-1995
  4. * TITLE: BNDWIDTH.CPP
  5. * VERSION: 1.0
  6. * AUTHOR: jsenior
  7. * DATE: 10/28/1998
  8. *
  9. ********************************************************************************
  10. *
  11. * CHANGE LOG:
  12. *
  13. * DATE REV DESCRIPTION
  14. * ---------- ------- ----------------------------------------------------------
  15. * 10/28/1998 jsenior Original implementation.
  16. *
  17. *******************************************************************************/
  18. #include "resource.h"
  19. #include "itemfind.h"
  20. #include "debug.h"
  21. #include "powrpage.h"
  22. #include "bandpage.h"
  23. #include "usbapp.h"
  24. #include <cpl.h>
  25. #include <dbt.h>
  26. #define WINDOWSCALEFACTOR 15
  27. UINT CALLBACK
  28. UsbApplet::StaticDialogCallback(HWND Hwnd,
  29. UINT Msg,
  30. LPPROPSHEETPAGE Page)
  31. {
  32. /* UsbApplet *that;
  33. switch (Msg) {
  34. case PSPCB_CREATE:
  35. return TRUE; // return TRUE to continue with creation of page
  36. case PSPCB_RELEASE:
  37. that = (UsbPopup*) Page->lParam;
  38. DeleteChunk(that);
  39. delete that;
  40. return 0; // return value ignored
  41. default:
  42. break;
  43. }
  44. */
  45. return TRUE;
  46. }
  47. BOOL
  48. UsbApplet::CustomDialog()
  49. {
  50. InitCommonControls();
  51. if (NULL == (hSplitCursor = LoadCursor(gHInst, MAKEINTRESOURCE(IDC_SPLIT)))) {
  52. return FALSE;
  53. }
  54. if (-1 == DialogBoxParam(gHInst,
  55. MAKEINTRESOURCE(IDD_CPL_USB),
  56. NULL,
  57. StaticDialogProc,
  58. (LPARAM) this)) {
  59. return FALSE;
  60. }
  61. return TRUE;
  62. }
  63. USBINT_PTR APIENTRY UsbApplet::StaticDialogProc(IN HWND hDlg,
  64. IN UINT uMessage,
  65. IN WPARAM wParam,
  66. IN LPARAM lParam)
  67. {
  68. UsbApplet *that;
  69. that = (UsbApplet *) UsbGetWindowLongPtr(hDlg, USBDWLP_USER);
  70. if (!that && uMessage != WM_INITDIALOG)
  71. return FALSE; //DefDlgProc(hDlg, uMessage, wParam, lParam);
  72. switch (uMessage) {
  73. HANDLE_MSG(hDlg, WM_SIZE, that->OnSize);
  74. HANDLE_MSG(hDlg, WM_LBUTTONDOWN, that->OnLButtonDown);
  75. HANDLE_MSG(hDlg, WM_LBUTTONUP, that->OnLButtonUp);
  76. HANDLE_MSG(hDlg, WM_MOUSEMOVE, that->OnMouseMove);
  77. HANDLE_MSG(hDlg, WM_CLOSE, that->OnClose);
  78. HANDLE_MSG(hDlg, WM_NOTIFY, that->OnNotify);
  79. case WM_DEVICECHANGE:
  80. return that->OnDeviceChange(hDlg, (UINT)wParam, (DWORD)wParam);
  81. case WM_COMMAND:
  82. return that->OnCommand(HIWORD(wParam),
  83. LOWORD(wParam),
  84. (HWND) lParam);
  85. case USBWM_NOTIFYREFRESH:
  86. return that->Refresh();
  87. case WM_INITDIALOG:
  88. that = (UsbApplet *) lParam;
  89. UsbSetWindowLongPtr(hDlg, USBDWLP_USER, (USBLONG_PTR) that);
  90. that->hMainWnd = hDlg;
  91. return that->OnInitDialog(hDlg);
  92. default:
  93. break;
  94. }
  95. return that->ActualDialogProc(hDlg, uMessage, wParam, lParam);
  96. }
  97. LRESULT
  98. UsbApplet::OnDeviceChange(HWND hWnd, UINT wParam, DWORD lParam)
  99. {
  100. if ((wParam == DBT_DEVICEARRIVAL) ||
  101. (wParam == DBT_DEVICEREMOVECOMPLETE)) {
  102. Refresh();
  103. }
  104. return TRUE;
  105. }
  106. BOOL
  107. UsbApplet::OnCommand(INT wNotifyCode,
  108. INT wID,
  109. HWND hCtl)
  110. {
  111. /* switch (wID) {
  112. case IDOK:
  113. EndDialog(hWnd, wID);
  114. return TRUE;
  115. }*/
  116. return FALSE;
  117. }
  118. BOOL
  119. UsbApplet::OnInitDialog(HWND HWnd)
  120. {
  121. hMainWnd = HWnd;
  122. RECT rc;
  123. HICON hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_USB));
  124. if (hIcon) {
  125. SendMessage(HWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
  126. SendMessage(HWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
  127. }
  128. //
  129. // Get a persistent handle to the tree view control
  130. //
  131. if (NULL == (hTreeDevices = GetDlgItem(HWnd, IDC_TREE_USB)) ||
  132. NULL == (hEditControl = GetDlgItem(HWnd, IDC_EDIT1))) {
  133. return FALSE;
  134. }
  135. TreeView_SetImageList(hTreeDevices, ImageList.ImageList(), TVSIL_NORMAL);
  136. GetWindowRect(HWnd, &rc);
  137. barLocation = (rc.right - rc.left) / 3;
  138. ResizeWindows(HWnd, FALSE, 0);
  139. if (!Refresh()) {
  140. return FALSE;
  141. }
  142. //
  143. // Everything seems to be working fine; let's register for device change
  144. // notification
  145. //
  146. return RegisterForDeviceNotification(HWnd);
  147. }
  148. BOOL
  149. UsbApplet::RegisterForDeviceNotification(HWND hWnd)
  150. {
  151. DEV_BROADCAST_DEVICEINTERFACE dbc;
  152. memset(&dbc, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
  153. dbc.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
  154. dbc.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  155. dbc.dbcc_classguid = GUID_CLASS_USBHUB;
  156. hDevNotify = RegisterDeviceNotification(hWnd,
  157. &dbc,
  158. DEVICE_NOTIFY_WINDOW_HANDLE);
  159. if (!hDevNotify) {
  160. return FALSE;
  161. }
  162. return TRUE;
  163. }
  164. HTREEITEM
  165. UsbApplet::InsertRoot(LPTV_INSERTSTRUCT item,
  166. UsbItem *firstController)
  167. {
  168. HTREEITEM hItem;
  169. ZeroMemory(item, sizeof(TV_INSERTSTRUCT));
  170. // Get the image index
  171. item->hParent = NULL;
  172. item->hInsertAfter = TVI_LAST;
  173. item->item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; // TVIF_CHILDREN
  174. // item->itemex.state = TVIS_BOLD;
  175. item->itemex.state |= TVIS_EXPANDED;
  176. item->itemex.stateMask = (UINT)~(TVIS_STATEIMAGEMASK | TVIS_OVERLAYMASK);
  177. item->itemex.pszText = TEXT("My Computer");
  178. item->itemex.cchTextMax = _tcsclen(TEXT("My Computer"));
  179. item->itemex.iImage = 0;
  180. item->itemex.iSelectedImage = 0;
  181. if (firstController) {
  182. item->itemex.cChildren = 1;
  183. }
  184. //
  185. // We will be able to recognize this from usbitems because we assign it the
  186. // lParam value INVALID_HANDLE_VALUE instead of the address of a valid
  187. // usbItem. Cunning, no? Ok, not really...
  188. //
  189. item->itemex.lParam = (LPARAM) INVALID_HANDLE_VALUE;
  190. if (NULL == (hItem = (HTREEITEM)
  191. SendMessage(hTreeDevices,
  192. TVM_INSERTITEM,
  193. 0,
  194. (LPARAM)(LPTV_INSERTSTRUCT)item))) {
  195. int i = GetLastError();
  196. }
  197. return hItem;
  198. }
  199. BOOL
  200. UsbApplet::Refresh()
  201. {
  202. TV_INSERTSTRUCT item;
  203. UsbItem deviceItem;
  204. HTREEITEM hTreeRoot = NULL;
  205. // CWaitCursor wait;
  206. //
  207. // Clear all UI components, and then recreate the rootItem
  208. //
  209. TreeView_DeleteAllItems(hTreeDevices);
  210. if (rootItem) {
  211. DeleteChunk(rootItem);
  212. delete rootItem;
  213. }
  214. rootItem = new UsbItem;
  215. AddChunk(rootItem);
  216. if (!rootItem->EnumerateAll(&ImageList)) {
  217. goto UsbAppletRefreshError;
  218. }
  219. hTreeRoot = InsertRoot(&item, rootItem->child);
  220. if (rootItem->child) {
  221. return UsbItem::InsertTreeItem (hTreeDevices,
  222. rootItem->child,
  223. hTreeRoot,
  224. &item,
  225. IsValid,
  226. IsBold,
  227. IsExpanded);
  228. }
  229. return TRUE;
  230. UsbAppletRefreshError:
  231. return FALSE;
  232. }
  233. VOID
  234. UsbApplet::OnSize (HWND hWnd,
  235. UINT state,
  236. int cx,
  237. int cy)
  238. {
  239. ResizeWindows(hWnd, FALSE, 0);
  240. }
  241. //*****************************************************************************
  242. //
  243. // ResizeWindows()
  244. //
  245. // Handles resizing the two child windows of the main window. If
  246. // bSizeBar is true, then the sizing is happening because the user is
  247. // moving the bar. If bSizeBar is false, the sizing is happening
  248. // because of the WM_SIZE or something like that.
  249. //
  250. //*****************************************************************************
  251. VOID
  252. UsbApplet::ResizeWindows (HWND hWnd,
  253. BOOL bSizeBar,
  254. int BarLocation)
  255. {
  256. RECT MainClientRect;
  257. RECT MainWindowRect;
  258. RECT TreeWindowRect;
  259. // RECT StatusWindowRect;
  260. int right;
  261. // Is the user moving the bar?
  262. //
  263. if (!bSizeBar)
  264. {
  265. BarLocation = barLocation;
  266. }
  267. GetClientRect(hWnd, &MainClientRect);
  268. // GetWindowRect(ghStatusWnd, &StatusWindowRect);
  269. // Make sure the bar is in a OK location
  270. //
  271. if (bSizeBar)
  272. {
  273. if (BarLocation <
  274. GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR)
  275. {
  276. return;
  277. }
  278. if ((MainClientRect.right - BarLocation) <
  279. GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR)
  280. {
  281. return;
  282. }
  283. }
  284. // Save the bar location
  285. //
  286. barLocation = BarLocation;
  287. // Move the tree window
  288. //
  289. MoveWindow(hTreeDevices,
  290. 0,
  291. 0,
  292. BarLocation,
  293. MainClientRect.bottom,// - StatusWindowRect.bottom + StatusWindowRect.top,
  294. TRUE);
  295. // Get the size of the window (in case move window failed
  296. //
  297. GetWindowRect(hTreeDevices, &TreeWindowRect);
  298. GetWindowRect(hWnd, &MainWindowRect);
  299. right = TreeWindowRect.right - MainWindowRect.left;
  300. // Move the edit window with respect to the tree window
  301. //
  302. MoveWindow(hEditControl,
  303. right,
  304. 0,
  305. MainClientRect.right-(right),
  306. MainClientRect.bottom, // - StatusWindowRect.bottom + StatusWindowRect.top,
  307. TRUE);
  308. if (propPage) {
  309. propPage->SizeWindow(right,
  310. 0,
  311. MainClientRect.right-(right),
  312. MainClientRect.bottom);
  313. }
  314. // Move the Status window with respect to the tree window
  315. //
  316. /* MoveWindow(ghStatusWnd,
  317. 0,
  318. MainClientRect.bottom - StatusWindowRect.bottom + StatusWindowRect.top,
  319. MainClientRect.right,
  320. StatusWindowRect.bottom - StatusWindowRect.top,
  321. TRUE);*/
  322. }
  323. VOID
  324. UsbApplet::OnMouseMove (HWND hWnd,
  325. int x,
  326. int y,
  327. UINT keyFlags)
  328. {
  329. SetCursor(hSplitCursor);
  330. if (bButtonDown)
  331. {
  332. ResizeWindows(hMainWnd, TRUE, x);
  333. }
  334. }
  335. VOID
  336. UsbApplet::OnLButtonDown (
  337. HWND hWnd,
  338. BOOL fDoubleClick,
  339. int x,
  340. int y,
  341. UINT keyFlags
  342. )
  343. {
  344. bButtonDown = TRUE;
  345. SetCapture(hMainWnd);
  346. }
  347. VOID
  348. UsbApplet::OnLButtonUp (
  349. HWND hWnd,
  350. int x,
  351. int y,
  352. UINT keyFlags
  353. )
  354. {
  355. bButtonDown = FALSE;
  356. ReleaseCapture();
  357. }
  358. VOID
  359. UsbApplet::OnClose (HWND hWnd)
  360. {
  361. // DestroyTree();
  362. if (hDevNotify) {
  363. UnregisterDeviceNotification(hDevNotify);
  364. hDevNotify = NULL;
  365. }
  366. PostQuitMessage(0);
  367. EndDialog(hMainWnd, 0);
  368. }
  369. LRESULT
  370. UsbApplet::OnNotify (
  371. HWND hWnd,
  372. int DlgItem,
  373. LPNMHDR lpNMHdr
  374. )
  375. {
  376. switch(lpNMHdr->code){
  377. case TVN_SELCHANGED: {
  378. UsbItem *usbItem;
  379. // HTREEITEM hTreeItem;
  380. // hTreeItem = ((NM_TREEVIEW *)lpNMHdr)->itemNew.hItem;
  381. usbItem = (UsbItem*) ((NM_TREEVIEW *)lpNMHdr)->itemNew.lParam;
  382. if (usbItem)
  383. {
  384. UpdateEditControl((UsbItem *) usbItem);
  385. }
  386. SetActiveWindow(hTreeDevices);
  387. }
  388. case LVN_KEYDOWN: {
  389. LPNMLVKEYDOWN pKey = (LPNMLVKEYDOWN) lpNMHdr;
  390. if (VK_F5 == pKey->wVKey) {
  391. return Refresh();
  392. }
  393. }
  394. case TVN_KEYDOWN: {
  395. LPNMTVKEYDOWN pKey = (LPNMTVKEYDOWN) lpNMHdr;
  396. if (VK_F5 == pKey->wVKey) {
  397. return Refresh();
  398. }
  399. }
  400. /* case NM_KEYDOWN: {
  401. LPNMKEY pKey = (LPNMKEY) lpNMHdr;
  402. if (VK_F5 == pKey->nVKey) {
  403. return Refresh();
  404. }
  405. }*/
  406. /* if (DlgItem == IDC_TREE_USB &&
  407. lpNMHdr->code == NM_RCLICK)
  408. {
  409. HMENU hMenu
  410. CreateMenu();
  411. return TRUE;
  412. }
  413. */
  414. }
  415. return 0;
  416. }
  417. VOID
  418. UsbApplet::UpdateEditControl(UsbItem *usbItem)
  419. {
  420. if (propPage) {
  421. if (propPage->DestroyChild()) {
  422. delete propPage;
  423. propPage = NULL;
  424. }
  425. }
  426. if (usbItem == INVALID_HANDLE_VALUE) {
  427. propPage = new RootPage(usbItem);
  428. } else if (usbItem->IsHub()) {
  429. propPage = new PowerPage(usbItem);
  430. } else if (usbItem->IsController()) {
  431. propPage = new BandwidthPage(usbItem);
  432. } else {
  433. propPage = new GenericPage(usbItem);
  434. }
  435. if (propPage) {
  436. propPage->CreateAsChild(hMainWnd, hEditControl, usbItem);
  437. }
  438. }
  439. BOOL
  440. UsbApplet::IsBold(UsbItem *Item)
  441. {
  442. return FALSE;
  443. }
  444. BOOL
  445. UsbApplet::IsValid(UsbItem *Item)
  446. {
  447. return !Item->IsUnusedPort();
  448. }
  449. BOOL
  450. UsbApplet::IsExpanded(UsbItem *Item)
  451. {
  452. if (Item->IsHub() || Item->IsController()) {
  453. return TRUE;
  454. }
  455. return FALSE;
  456. }
  457. extern "C" {
  458. LONG APIENTRY
  459. CPlApplet(HWND hwndCPl,
  460. UINT uMsg,
  461. LPARAM lParam1,
  462. LPARAM lParam2)
  463. {
  464. UsbApplet *applet;
  465. applet = (UsbApplet*) lParam2;
  466. switch (uMsg) {
  467. case CPL_EXIT:
  468. return 0;
  469. case CPL_INQUIRE:
  470. {
  471. CPLINFO *info = (CPLINFO *) lParam2;
  472. assert(lParam1 == 0);
  473. applet = new UsbApplet();
  474. info->idIcon = IDI_USB;
  475. info->idName = IDS_USB;
  476. info->idInfo = IDS_USB;
  477. info->lData = (USBLONG_PTR) applet;
  478. return 0;
  479. }
  480. case CPL_GETCOUNT:
  481. return 1;
  482. case CPL_INIT:
  483. return TRUE;
  484. case CPL_DBLCLK:
  485. assert(lParam1 == 0);
  486. if (applet->CustomDialog()) {
  487. return 0;
  488. }
  489. return 1;
  490. case CPL_STOP:
  491. assert(lParam1 == 0);
  492. applet->OnClose(hwndCPl);
  493. delete applet;
  494. return 0;
  495. }
  496. return 0;
  497. }
  498. }