Leaked source code of windows server 2003
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.

753 lines
16 KiB

  1. #include "pch.h"
  2. HWND
  3. SoftPCI_CreateTabCtrlPane(
  4. IN HWND Wnd
  5. );
  6. HWND
  7. SoftPCI_CreateTreeViewPane(
  8. IN HWND Wnd
  9. );
  10. BOOL
  11. SoftPCI_OnCreate(
  12. HWND hWnd,
  13. LPCREATESTRUCT lpCreateStruct
  14. );
  15. VOID
  16. SoftPCI_OnCommand(
  17. IN HWND hWnd,
  18. IN INT DlgItem,
  19. IN HWND hControlWnd,
  20. IN UINT NotificationCode
  21. );
  22. VOID
  23. SoftPCI_OnDestroy(
  24. IN HWND hWnd
  25. );
  26. SoftPCI_OnNotify(
  27. IN HWND Wnd,
  28. IN INT DlgItem,
  29. IN LPNMHDR PNMHdr
  30. );
  31. VOID
  32. WINAPI
  33. SoftPCI_OnLButtonDown(
  34. HWND hWnd,
  35. BOOL fDoubleClick,
  36. int nX,
  37. int nY,
  38. UINT uKeyFlags
  39. );
  40. VOID
  41. SoftPCI_OnSize(
  42. HWND Wnd,
  43. UINT State,
  44. INT Cx,
  45. INT Cy
  46. );
  47. VOID
  48. SoftPCI_ResizeWindow(
  49. HWND Wnd,
  50. UINT ResizeFrom
  51. );
  52. #define RESIZEFROM_OTHER 0
  53. #define RESIZEFROM_SPLIT 1
  54. //
  55. // Since we do not have a status bar this array does practically nothing for us.
  56. // If we ever implement a status bar across the bottom we will need this.
  57. //
  58. const int g_EffectiveClientRectData[] = {
  59. 1, 0, // For the menu bar, but is unused
  60. 0, 0 // First zero marks end of data
  61. };
  62. INT g_PixelsPerInch = 0;
  63. INT g_PaneSplit = 0;
  64. BOOL g_TimerSet = FALSE;
  65. HCURSOR g_OldCursor;
  66. #define TREETIMER 0xABAB
  67. HWND
  68. SoftPCI_CreateMainWnd(VOID)
  69. /*++
  70. Routine Description:
  71. Creates an instance of the SoftPCI Main View window.
  72. Arguments:
  73. none
  74. Return Value:
  75. The Device View HWND (or NULL on error).
  76. --*/
  77. {
  78. BOOL result;
  79. HWND mainWnd;
  80. HDC hdc;
  81. WCHAR title[MAX_PATH];
  82. SOFTPCI_WNDVIEW wndView;
  83. hdc = GetDC(NULL);
  84. g_PixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSX);
  85. ReleaseDC(NULL, hdc);
  86. result = SoftPCI_QueryWindowSettings(&wndView);
  87. //
  88. // Default to a pane split of 4 inches unless we have a registry over-ride
  89. //
  90. g_PaneSplit = (result ? wndView.PaneSplit : (g_PixelsPerInch * 4));
  91. LoadString(g_Instance, IDS_APPTITLE, title, (sizeof(title) / sizeof(title[0])));
  92. mainWnd = CreateWindowEx(
  93. WS_EX_WINDOWEDGE | WS_EX_ACCEPTFILES,
  94. g_SoftPCIMainClassName,
  95. title,
  96. WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_THICKFRAME |
  97. WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CLIPCHILDREN,
  98. CW_USEDEFAULT,
  99. CW_USEDEFAULT,
  100. CW_USEDEFAULT,
  101. CW_USEDEFAULT,
  102. NULL,
  103. NULL,
  104. g_Instance,
  105. NULL
  106. );
  107. if (result) {
  108. wndView.WindowPlacement.length = sizeof(wndView.WindowPlacement);
  109. if (wndView.WindowPlacement.showCmd == SW_SHOWMINIMIZED){
  110. wndView.WindowPlacement.showCmd = SW_SHOWDEFAULT;
  111. }
  112. SetWindowPlacement(mainWnd, &wndView.WindowPlacement);
  113. }else{
  114. ShowWindow(mainWnd, SW_SHOWDEFAULT);
  115. }
  116. return mainWnd;
  117. }
  118. HWND
  119. SoftPCI_CreateTreeViewPane(
  120. IN HWND Wnd
  121. )
  122. {
  123. g_TreeViewWnd = CreateWindowEx(
  124. WS_EX_CLIENTEDGE,
  125. WC_TREEVIEW,
  126. NULL,
  127. WS_CHILD | WS_VISIBLE | WS_TABSTOP | TVS_HASBUTTONS |
  128. TVS_LINESATROOT | TVS_HASLINES, //| WS_SIZEBOX,
  129. 0, 0, 0, 0, Wnd,
  130. (HMENU) IDC_TREEVIEW,
  131. g_Instance,
  132. NULL);
  133. return g_TreeViewWnd;
  134. }
  135. LRESULT
  136. WINAPI
  137. SoftPCI_MainWndProc(
  138. IN HWND Wnd,
  139. IN UINT Message,
  140. IN WPARAM wParam,
  141. IN LPARAM lParam
  142. )
  143. /*++
  144. Routine Description:
  145. Windows message processing
  146. Arguments:
  147. hWnd - Window handle
  148. Message - Message to process
  149. wParam - Message param
  150. lParam - Message param
  151. Return Value:
  152. return value depends on message handled.
  153. --*/
  154. {
  155. HMENU rmenu;
  156. PWCHAR filePath;
  157. UINT filePathSize;
  158. UINT_PTR timerSet;
  159. // SoftPCI_Debug(SoftPciAlways, L"message - %x\n", Message);
  160. switch (Message) {
  161. //
  162. // ISSUE: Should handle WM_CREATE better since it is
  163. // critical to everything working properly. If it fails
  164. // then we should complain and exit.
  165. //
  166. HANDLE_MSG(Wnd, WM_CREATE, SoftPCI_OnCreate);
  167. HANDLE_MSG(Wnd, WM_COMMAND, SoftPCI_OnCommand);
  168. HANDLE_MSG(Wnd, WM_DESTROY, SoftPCI_OnDestroy);
  169. HANDLE_MSG(Wnd, WM_NOTIFY, SoftPCI_OnNotify);
  170. HANDLE_MSG(Wnd, WM_LBUTTONDOWN, SoftPCI_OnLButtonDown);
  171. HANDLE_MSG(Wnd, WM_SIZE, SoftPCI_OnSize);
  172. case WM_ACTIVATE:
  173. if (wParam != WA_INACTIVE) {
  174. SetFocus(g_TreeViewWnd);
  175. }
  176. break;
  177. case WM_DEVICECHANGE:
  178. if (wParam == DBT_DEVNODES_CHANGED) {
  179. //
  180. // Refresh the tree if it isnt locked.
  181. //
  182. if (g_TreeLocked){
  183. g_PendingRefresh = TRUE;
  184. break;
  185. }
  186. if (!g_TimerSet){
  187. //
  188. // Set a timer for 5 seconds so that we dont
  189. // repaint the tree like a freaking epeleptic
  190. //
  191. SoftPCI_CreateTreeView();
  192. timerSet = SetTimer(
  193. Wnd,
  194. TREETIMER,
  195. 5 * 1000,
  196. NULL
  197. );
  198. if (timerSet != 0) {
  199. g_TimerSet = TRUE;
  200. }
  201. }else{
  202. g_PendingRefresh = TRUE;
  203. }
  204. }
  205. break;
  206. case WM_TIMER:
  207. if (wParam == TREETIMER) {
  208. //
  209. // Our timer fired, kill it and rebuild the tree
  210. //
  211. if (g_PendingRefresh){
  212. g_PendingRefresh = FALSE;
  213. SoftPCI_CreateTreeView();
  214. }
  215. KillTimer(Wnd, TREETIMER);
  216. g_TimerSet = FALSE;
  217. }
  218. break;
  219. case WM_INITMENU:{
  220. HMENU menu = GetMenu(g_SoftPCIMainWnd);
  221. if (g_DriverHandle) {
  222. SoftPCI_DisableMenuItem(menu, ID_OPTIONS_INSTALL);
  223. }
  224. }
  225. break;
  226. case WM_DROPFILES:
  227. if (g_DriverHandle != NULL) {
  228. filePathSize = DragQueryFile(
  229. (HDROP)wParam,
  230. 0,
  231. NULL,
  232. 0
  233. );
  234. filePath = calloc(sizeof(WCHAR), filePathSize + 1);
  235. if (filePath) {
  236. DragQueryFile(
  237. (HDROP)wParam,
  238. 0,
  239. filePath,
  240. filePathSize + 1
  241. );
  242. if (SoftPCI_BuildDeviceInstallList(filePath)){
  243. SoftPCI_InstallScriptDevices();
  244. }else{
  245. SoftPCI_MessageBox(L"Error Parsing Script File!",
  246. L"%s\n",
  247. g_ScriptError
  248. );
  249. }
  250. free(filePath);
  251. }
  252. }else{
  253. MessageBox(g_SoftPCIMainWnd,
  254. L"Cannot process script file! SoftPCI support not installed!",
  255. L"Script Error",
  256. MB_OK
  257. );
  258. }
  259. DragFinish((HDROP)wParam);
  260. break;
  261. default:
  262. return DefWindowProc(Wnd, Message, wParam, lParam);
  263. }
  264. return 0;
  265. }
  266. VOID
  267. SoftPCI_OnCommand(
  268. IN HWND Wnd,
  269. IN INT ItemID,
  270. IN HWND ControlWnd,
  271. IN UINT NotificationCode
  272. )
  273. /*++
  274. Routine Description:
  275. Windows message processing
  276. Arguments:
  277. hWnd - Window handle
  278. DlgItem -
  279. hControlWnd -
  280. NotificationCode -
  281. Return Value:
  282. None
  283. --*/
  284. {
  285. HMENU menu = GetMenu(Wnd);
  286. BOOL result = FALSE;
  287. switch (ItemID) {
  288. case ID_EXIT:
  289. PostMessage(Wnd, WM_CLOSE, 0, 0);
  290. break;
  291. case ID_OPTIONS_INSTALL:
  292. result = MessageBox(g_SoftPCIMainWnd,
  293. L"SoftPCI Support will now be installed....",
  294. L"INSTALL",
  295. MB_OKCANCEL | MB_DEFBUTTON2
  296. );
  297. if (result == IDOK) {
  298. if (!SoftPCI_InstallDriver()) {
  299. MessageBox(g_SoftPCIMainWnd,
  300. L"Failed to Install SoftPCI Support",
  301. NULL,
  302. MB_OK | MB_ICONEXCLAMATION);
  303. }
  304. }
  305. break;
  306. case ID_IMPORTDEVICES:
  307. SoftPCI_HandleImportDevices();
  308. break;
  309. default:
  310. break;
  311. }
  312. }
  313. BOOL
  314. SoftPCI_OnCreate(
  315. IN HWND Wnd,
  316. IN LPCREATESTRUCT CreateStruct
  317. )
  318. /*++
  319. Routine Description:
  320. Creates our other subwindows (tree view)
  321. Arguments:
  322. Wnd - Parent window handle
  323. CreateStruct -
  324. Return Value:
  325. None
  326. --*/
  327. {
  328. if (SoftPCI_CreateTreeViewPane(Wnd) == NULL ||
  329. SoftPCI_CreateTabCtrlPane(Wnd) == NULL) {
  330. return FALSE;
  331. }
  332. //
  333. // Subclass our tree view window proc
  334. //
  335. g_DefTreeWndProc = GetWindowLongPtr(g_TreeViewWnd, GWLP_WNDPROC);
  336. if (!SetWindowLongPtr(g_TreeViewWnd,
  337. GWLP_WNDPROC,
  338. ((LONG_PTR)SoftPCI_TreeWndProc))){
  339. SOFTPCI_ASSERT(FALSE);
  340. return FALSE;
  341. }
  342. SoftPCI_CreateTreeView();
  343. SetFocus(g_TreeViewWnd);
  344. return TRUE;
  345. }
  346. VOID
  347. SoftPCI_OnDestroy(
  348. IN HWND Wnd
  349. )
  350. {
  351. SoftPCI_SaveWindowSettings();
  352. if (g_TreeCreated) {
  353. SoftPCI_DestroyTree(g_PciTree);
  354. }
  355. if (g_LastSelection) {
  356. free(g_LastSelection);
  357. }
  358. //
  359. // This keeps us from doing funky repainting when the tree is destroyed.
  360. //
  361. //TreeView_SelectItem(g_TreeViewWnd, NULL);
  362. PostQuitMessage(0);
  363. }
  364. SoftPCI_OnNotify(
  365. IN HWND Wnd,
  366. IN INT DlgItem,
  367. IN LPNMHDR PNMHdr
  368. )
  369. {
  370. switch (DlgItem) {
  371. case IDC_TABCTL:
  372. switch (PNMHdr->code) {
  373. case TCN_SELCHANGE:
  374. SoftPCI_OnTabCtrlSelectionChange();
  375. break;
  376. }
  377. break;
  378. case IDC_TREEVIEW:
  379. switch (PNMHdr->code) {
  380. case TVN_SELCHANGED:
  381. SoftPCI_OnTreeSelectionChange(Wnd);
  382. break;
  383. }
  384. default:
  385. break;
  386. }
  387. return 0;
  388. }
  389. VOID
  390. WINAPI
  391. SoftPCI_OnLButtonDown(
  392. HWND hWnd,
  393. BOOL fDoubleClick,
  394. int nX,
  395. int nY,
  396. UINT uKeyFlags
  397. )
  398. {
  399. LONG lStyle;
  400. RECT clientRect;
  401. int nCxIcon;
  402. int nDx;
  403. int nDy;
  404. HDC hDC;
  405. MSG msg;
  406. int nXLow;
  407. int nXHigh;
  408. HBRUSH hDitherBrush;
  409. HBRUSH hPrevBrush;
  410. if (!IsIconic(hWnd)){
  411. lStyle = GetWindowLong(hWnd, GWL_STYLE);
  412. SetWindowLong(hWnd, GWL_STYLE, lStyle & (~WS_CLIPCHILDREN));
  413. GetEffectiveClientRect(hWnd, &clientRect, (LPINT)g_EffectiveClientRectData);
  414. nCxIcon = GetSystemMetrics(SM_CXICON);
  415. clientRect.left += nCxIcon;
  416. clientRect.right -= nCxIcon;
  417. nDx = GetSystemMetrics(SM_CXSIZEFRAME);
  418. nY = GetSystemMetrics(SM_CYEDGE);
  419. nDy = clientRect.bottom - clientRect.top - nY * 2;
  420. hDC = GetDC(hWnd);
  421. hDitherBrush = SoftPCI_CreateDitheredBrush();
  422. if (hDitherBrush != NULL) {
  423. hPrevBrush = SelectBrush(hDC, hDitherBrush);
  424. }
  425. PatBlt(hDC, nX - nDx / 2, nY, nDx, nDy, PATINVERT);
  426. SetCapture(hWnd);
  427. while (GetMessage(&msg, NULL, 0, 0)) {
  428. if (msg.message == WM_KEYDOWN ||
  429. msg.message == WM_SYSKEYDOWN ||
  430. (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)) {
  431. if (msg.message == WM_LBUTTONUP ||
  432. msg.message == WM_LBUTTONDOWN ||
  433. msg.message == WM_RBUTTONDOWN) {
  434. break;
  435. }
  436. if (msg.message == WM_KEYDOWN) {
  437. if (msg.wParam == VK_LEFT) {
  438. msg.message = WM_MOUSEMOVE;
  439. msg.pt.x -= 2;
  440. } else if (msg.wParam == VK_RIGHT) {
  441. msg.message = WM_MOUSEMOVE;
  442. msg.pt.x += 2;
  443. } else if (msg.wParam == VK_RETURN || msg.wParam == VK_ESCAPE) {
  444. break;
  445. }
  446. if (msg.pt.x > clientRect.right) {
  447. msg.pt.x = clientRect.right;
  448. } else if (msg.pt.x < clientRect.left) {
  449. msg.pt.x = clientRect.left;
  450. }
  451. SetCursorPos(msg.pt.x, msg.pt.y);
  452. }
  453. if (msg.message == WM_MOUSEMOVE) {
  454. ScreenToClient(hWnd, &msg.pt);
  455. if (msg.pt.x > clientRect.right) {
  456. msg.pt.x = clientRect.right;
  457. } else if (msg.pt.x < clientRect.left) {
  458. msg.pt.x = clientRect.left;
  459. }
  460. if (nX < msg.pt.x) {
  461. nXLow = nX;
  462. nXHigh = msg.pt.x;
  463. } else {
  464. nXLow = msg.pt.x;
  465. nXHigh = nX;
  466. }
  467. nXLow -= nDx / 2;
  468. nXHigh -= nDx / 2;
  469. if (nXHigh < nXLow + nDx) {
  470. ExcludeClipRect(hDC, nXHigh, nY, nXLow + nDx, nY + nDy);
  471. } else {
  472. ExcludeClipRect(hDC, nXLow + nDx, nY, nXHigh, nY + nDy);
  473. }
  474. PatBlt(hDC, nXLow, nY, nXHigh - nXLow + nDx, nDy, PATINVERT);
  475. SelectClipRgn(hDC, NULL);
  476. nX = msg.pt.x;
  477. }
  478. } else {
  479. DispatchMessage(&msg);
  480. }
  481. }
  482. ReleaseCapture();
  483. PatBlt(hDC, nX - nDx / 2, nY, nDx, nDy, PATINVERT);
  484. if (hDitherBrush != NULL) {
  485. DeleteObject(SelectBrush(hDC, hPrevBrush));
  486. }
  487. ReleaseDC(hWnd, hDC);
  488. SetWindowLong(hWnd, GWL_STYLE, lStyle);
  489. g_PaneSplit = nX - nDx / 2;
  490. SoftPCI_ResizeWindow(hWnd, RESIZEFROM_SPLIT);
  491. }
  492. }
  493. VOID
  494. SoftPCI_OnSize(
  495. HWND Wnd,
  496. UINT State,
  497. INT Cx,
  498. INT Cy
  499. )
  500. {
  501. SoftPCI_ResizeWindow(Wnd, RESIZEFROM_OTHER);
  502. }
  503. VOID
  504. SoftPCI_ResizeWindow(
  505. HWND Wnd,
  506. UINT ResizeFrom
  507. )
  508. {
  509. RECT clientRect;
  510. INT x, y, height, width;
  511. HDWP hdwp;
  512. //
  513. // Currently we do not use the ResizeFrom argument but should we ever
  514. // decide to implement a status bar we will need it.
  515. //
  516. if ((hdwp = BeginDeferWindowPos(3)) != NULL){
  517. GetClientRect(Wnd, &clientRect);
  518. x = 0;
  519. y = 0;
  520. height = (clientRect.bottom - clientRect.top);
  521. width = g_PaneSplit;
  522. DeferWindowPos(hdwp,
  523. g_TreeViewWnd,
  524. NULL,
  525. x,
  526. y,
  527. width + GetSystemMetrics(SM_CXSIZEFRAME),
  528. height,
  529. SWP_NOZORDER | SWP_NOACTIVATE
  530. );
  531. x += width + GetSystemMetrics(SM_CXSIZEFRAME);
  532. width = (clientRect.right - clientRect.left) - x;
  533. DeferWindowPos(hdwp,
  534. g_TabCtrlWnd,
  535. NULL,
  536. x,
  537. y,
  538. width,
  539. height,
  540. SWP_NOZORDER | SWP_NOACTIVATE
  541. );
  542. SetRect(&clientRect, x, y, width, height);
  543. TabCtrl_AdjustRect(g_TabCtrlWnd, FALSE, &clientRect) ;
  544. height = (clientRect.bottom - clientRect.top) + GetSystemMetrics(SM_CXSIZEFRAME);
  545. width -= GetSystemMetrics(SM_CXSIZEFRAME);
  546. DeferWindowPos(hdwp,
  547. g_EditWnd,
  548. HWND_TOP,
  549. clientRect.left + 3,
  550. clientRect.top + 3,
  551. width - 3,
  552. height - 3,
  553. SWP_NOACTIVATE
  554. );
  555. EndDeferWindowPos(hdwp);
  556. }
  557. }