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.

726 lines
25 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: Cmdhand.cpp
  4. // Created: Feb 1996
  5. // By: Martin Holladay (a-martih) and Ryan D. Marshall (a-ryanm)
  6. //
  7. // Project: MultiDesk - The NT Desktop Switcher
  8. //
  9. //
  10. //
  11. // Revision History:
  12. //
  13. // March 1997 - Add external icon capability
  14. //
  15. //
  16. /*--------------------------------------------------------------------*/
  17. /* Include Files */
  18. /*--------------------------------------------------------------------*/
  19. #include <windows.h>
  20. #include <assert.h>
  21. #include <stdio.h>
  22. #include <shellapi.h>
  23. #include <commctrl.h>
  24. #include "prsht.h"
  25. #include "DeskSpc.h"
  26. #include "Desktop.h"
  27. #include "Registry.h"
  28. #include "resource.h"
  29. #include "CmdHand.h"
  30. #include "Menu.h"
  31. #include "User.h"
  32. #include <saifer.h>
  33. /*--------------------------------------------------------------------*/
  34. /* Global Variables */
  35. /*--------------------------------------------------------------------*/
  36. extern APPVARS AppMember;
  37. extern DispatchFnType CreateDisplayFn;
  38. /*------------------------------------------------------------------------------*/
  39. /*------------------------------------------------------------------------------*/
  40. LRESULT CALLBACK TransparentMessageProc(
  41. HWND hWnd,
  42. UINT uMessage,
  43. WPARAM wParam,
  44. LPARAM lParam)
  45. {
  46. switch (uMessage)
  47. {
  48. case WM_PAINT:
  49. {
  50. HDC hDC;
  51. HFONT hFont;
  52. HBRUSH hBrush;
  53. PAINTSTRUCT ps;
  54. TCHAR szTitle[200];
  55. RECT rect;
  56. hDC = BeginPaint(hWnd, &ps);
  57. if (hDC != NULL)
  58. {
  59. GetWindowText(hWnd, szTitle, sizeof(szTitle) / sizeof(TCHAR));
  60. GetClientRect(hWnd, &rect);
  61. hBrush = CreateSolidBrush(TRANSPARENT_BACKCOLOR);
  62. if (hBrush != NULL)
  63. {
  64. FillRect(hDC, &rect, hBrush);
  65. hFont = CreateFont(rect.bottom, 0, 0, 0, FW_DONTCARE,
  66. TRUE, FALSE, FALSE, DEFAULT_CHARSET,
  67. OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  68. DEFAULT_QUALITY, DEFAULT_PITCH, TEXT("Arial"));
  69. if (hFont != NULL)
  70. {
  71. SetTextColor(hDC, TRANSPARENT_TEXTCOLOR);
  72. SetBkMode(hDC, TRANSPARENT);
  73. HFONT hOldFont = (HFONT) SelectObject(hDC, hFont);
  74. DrawText(hDC, szTitle, -1, &rect,
  75. DT_TOP | DT_RIGHT | DT_END_ELLIPSIS);
  76. SelectObject(hDC, hOldFont);
  77. DeleteObject(hFont);
  78. }
  79. DeleteObject(hBrush);
  80. }
  81. EndPaint(hWnd, &ps);
  82. }
  83. return FALSE;
  84. }
  85. default:
  86. return (DefWindowProc(hWnd, uMessage, wParam, lParam));
  87. break;
  88. }
  89. return (0L);
  90. }
  91. /*------------------------------------------------------------------------------*/
  92. /*------------------------------------------------------------------------------*/
  93. LRESULT CALLBACK MainMessageProc(
  94. HWND hWnd,
  95. UINT uMessage,
  96. WPARAM wParam,
  97. LPARAM lParam)
  98. {
  99. WINDOWPOS* pWP;
  100. UINT uCmdId;
  101. UINT uCmdType;
  102. UINT uCmdMsg;
  103. HWND hTargetWnd;
  104. static UINT s_uTaskbarRestart;
  105. switch (uMessage)
  106. {
  107. case WM_CREATE:
  108. s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
  109. RegisterHotKey(hWnd, 0x7654, MOD_ALT | MOD_CONTROL, 41); // CTRL+ALT+A
  110. PlaceOnTaskbar(hWnd);
  111. break;
  112. case WM_HOTKEY:
  113. if (wParam == 0x7654)
  114. {
  115. // keyboard hotkey invoked menu popup
  116. AppMember.nX = AppMember.nY = 0;
  117. SetWindowPos(hWnd, HWND_TOPMOST,
  118. AppMember.nX, AppMember.nY,
  119. AppMember.nWidth, AppMember.nHeight,
  120. 0);
  121. HideOrRevealUI(hWnd, FALSE);
  122. UpdateCurrentUI(hWnd);
  123. SetActiveWindow(hWnd);
  124. SetForegroundWindow(hWnd);
  125. break;
  126. }
  127. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  128. //case WM_CONTEXTMENU:
  129. //TODO
  130. case WM_CLOSE:
  131. if ((UINT) wParam == WM_NO_CLOSE)
  132. break;
  133. CloseRequestHandler(hWnd);
  134. break;
  135. case WM_ENDSESSION:
  136. AppMember.pDesktopControl->RegSaveSettings();
  137. ShowWindow(hWnd, SW_HIDE);
  138. RemoveFromTaskbar(hWnd);
  139. AppMember.pDesktopControl->RunDown();
  140. PostThreadMessage(GetCurrentThreadId(), WM_PUMP_TERMINATE, 0, 0);
  141. break;
  142. case WM_NOTIFY:
  143. {
  144. int idCtrl = (int) wParam;
  145. LPNMHDR lpNmhdr = (LPNMHDR) lParam;
  146. NMLVDISPINFO *pnmv = (NMLVDISPINFO*) lParam;
  147. if (lpNmhdr->code == LVN_GETDISPINFO &&
  148. lpNmhdr->idFrom == IDC_DESKTOPICONLIST)
  149. {
  150. //
  151. // This notification is called when the ListView needs
  152. // to obtain information about the item that it is displaying.
  153. //
  154. static int nextindex = 0;
  155. static CHAR desktopname[5][MAX_NAME_LENGTH];
  156. // return the name of this desktop.
  157. AppMember.pDesktopControl->GetDesktopName(pnmv->item.iItem,
  158. desktopname[nextindex], MAX_NAME_LENGTH);
  159. pnmv->item.pszText = desktopname[nextindex];
  160. pnmv->item.cchTextMax = MAX_NAME_LENGTH;
  161. pnmv->item.mask |= LVIF_TEXT;
  162. nextindex = (nextindex + 1) % 5;
  163. // return the state of this desktop (unused).
  164. pnmv->item.state = 0;
  165. pnmv->item.stateMask = 0;
  166. pnmv->item.mask |= LVIF_STATE;
  167. // return the icon of this desktop.
  168. pnmv->item.iImage = AppMember.pDesktopControl->GetDesktopIconID(pnmv->item.iItem);
  169. pnmv->item.mask |= LVIF_IMAGE;
  170. // return the ident attribute.
  171. #if (_WIN32_IE >= 0x0300)
  172. pnmv->item.iIndent = 0;
  173. pnmv->item.mask |= LVIF_INDENT;
  174. #endif
  175. break;
  176. }
  177. else if (lpNmhdr->code == LVN_ITEMACTIVATE &&
  178. lpNmhdr->idFrom == IDC_DESKTOPICONLIST)
  179. {
  180. //
  181. // This notification is called when the user has single-clicked
  182. // an item in the listview. We use this signal to switch desktops.
  183. //
  184. HideOrRevealUI(hWnd, TRUE);
  185. LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam;
  186. if (lpnmia->iItem >= 0)
  187. SwitchToDesktop(lpnmia->iItem);
  188. break;
  189. }
  190. else if (lpNmhdr->code == NM_RCLICK &&
  191. lpNmhdr->idFrom == IDC_DESKTOPICONLIST)
  192. {
  193. //
  194. // This notification is triggered when the user right-clicks
  195. // on a listview item or in the listview box.
  196. //
  197. LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam;
  198. HMENU hPopupMenu = CreateListviewPopupMenu();
  199. // display the popup
  200. if (hPopupMenu != NULL)
  201. {
  202. RECT rect;
  203. WORD wChoiceId;
  204. if (lpnmia->iItem < 0)
  205. {
  206. // clicked off of an item, so gray the item-specific options.
  207. EnableMenuItem(hPopupMenu, IDM_DELETE_DESKTOP, MF_BYCOMMAND | MF_GRAYED);
  208. EnableMenuItem(hPopupMenu, IDM_DESKTOP_PROPERTIES, MF_BYCOMMAND | MF_GRAYED);
  209. }
  210. else if (lpnmia->iItem == 0)
  211. {
  212. // clicked on the first Desktop, cannot delete it though.
  213. EnableMenuItem(hPopupMenu, IDM_DELETE_DESKTOP, MF_BYCOMMAND | MF_GRAYED);
  214. }
  215. // Display the popup and get the selected choice.
  216. GetWindowRect(lpNmhdr->hwndFrom, &rect);
  217. wChoiceId = (WORD) TrackPopupMenu(hPopupMenu,
  218. TPM_CENTERALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY,
  219. (rect.left + lpnmia->ptAction.x),
  220. (rect.top + lpnmia->ptAction.y), 0, hWnd, NULL);
  221. DestroyMenu(hPopupMenu);
  222. // Handle the choice that was selected.
  223. switch (wChoiceId)
  224. {
  225. case IDM_NEW_DESKTOP:
  226. CreateNewDesktop(hWnd);
  227. break;
  228. case IDM_DELETE_DESKTOP:
  229. if (lpnmia->iItem >= 0) {
  230. DeleteDesktop(hWnd, lpnmia->iItem);
  231. UpdateCurrentUI(hWnd);
  232. }
  233. break;
  234. case IDM_DESKTOP_PROPERTIES:
  235. if (lpnmia->iItem >= 0) {
  236. RenameDialog(hWnd, lpnmia->iItem);
  237. UpdateCurrentUI(hWnd);
  238. }
  239. break;
  240. }
  241. }
  242. break;
  243. }
  244. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  245. }
  246. case WM_THREAD_TERMINATE:
  247. DestroyWindow(hWnd);
  248. break;
  249. case WM_TASKBAR:
  250. uCmdId = (UINT) wParam;
  251. uCmdMsg = (UINT) lParam;
  252. if (uCmdId == IDI_TASKBAR_ICON &&
  253. (uCmdMsg == WM_RBUTTONUP || uCmdMsg == WM_LBUTTONUP) &&
  254. !IsWindowVisible(hWnd))
  255. {
  256. POINT tPoint;
  257. GetCursorPos(&tPoint);
  258. AppMember.nX = tPoint.x - AppMember.nWidth;
  259. AppMember.nY = tPoint.y - AppMember.nHeight;
  260. SetWindowPos(hWnd, HWND_TOPMOST,
  261. AppMember.nX, AppMember.nY,
  262. AppMember.nWidth, AppMember.nHeight,
  263. 0);
  264. HideOrRevealUI(hWnd, FALSE);
  265. UpdateCurrentUI(hWnd);
  266. SetActiveWindow(hWnd);
  267. SetForegroundWindow(hWnd);
  268. }
  269. break;
  270. case WM_ACTIVATEAPP:
  271. // We are losing focus, so hide ourself again.
  272. if (!wParam)
  273. HideOrRevealUI(hWnd, TRUE);
  274. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  275. case WM_SIZE:
  276. {
  277. RECT rect;
  278. GetWindowRect(hWnd, &rect);
  279. AppMember.nX = rect.left;
  280. AppMember.nY = rect.top;
  281. AppMember.nWidth = rect.right - rect.left;
  282. AppMember.nHeight = rect.bottom - rect.top;
  283. GetClientRect(hWnd, &rect);
  284. HWND hWndList = GetDlgItem(hWnd, IDC_DESKTOPICONLIST);
  285. SetWindowPos(hWndList, NULL,
  286. 0, 0, (rect.right - rect.left), (rect.bottom - rect.top),
  287. SWP_NOZORDER);
  288. }
  289. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  290. default:
  291. // If Explorer has just started or restarted, then be
  292. // sure to add ourself back to it so the user does not
  293. // lose the ability to invoke us.
  294. if(uMessage == s_uTaskbarRestart)
  295. PlaceOnTaskbar(hWnd);
  296. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  297. break;
  298. }
  299. return 0L;
  300. }
  301. /*------------------------------------------------------------------------------*/
  302. /*
  303. /* Create a new desktop
  304. /*
  305. /*------------------------------------------------------------------------------*/
  306. void CreateNewDesktop(HWND hWnd)
  307. {
  308. // Use the creation wizard - or create it the old fashioned way.
  309. if (AppMember.pDesktopControl->GetNumDesktops() < MAX_DESKTOPS)
  310. {
  311. UINT nDskTopNum = AppMember.pDesktopControl->GetNumDesktops();
  312. AppMember.pDesktopControl->SaveCurrentDesktopScheme();
  313. AppMember.pDesktopControl->AddDesktop(CreateDisplayFn, NULL);
  314. RenameDialog(hWnd, nDskTopNum);
  315. UpdateCurrentUI(hWnd);
  316. }
  317. else
  318. {
  319. Message(TEXT("Maximum number of desktops reached"));
  320. }
  321. }
  322. //------------------------------------------------------------------------------//
  323. //
  324. // Delete Desktop
  325. //
  326. //-----------------------------------------------------------------------------//
  327. BOOL DeleteDesktop(HWND hWnd, UINT nDesktop) // zero based
  328. {
  329. HWND hTargetWnd, hCurrentWnd;
  330. UINT nResult;
  331. assert(nDesktop >= 0 && nDesktop < AppMember.pDesktopControl->GetNumDesktops());
  332. if (nDesktop == 0)
  333. {
  334. return FALSE;
  335. }
  336. hTargetWnd = AppMember.pDesktopControl->GetWindowDesktop(nDesktop);
  337. nResult = AppMember.pDesktopControl->RemoveDesktop(nDesktop);
  338. if (nResult == SUCCESS_THREAD_TERMINATION)
  339. {
  340. if (hTargetWnd) PostMessage(hTargetWnd, WM_THREAD_TERMINATE, 0, 0);
  341. }
  342. //
  343. // Update the UI for the active desktop.
  344. //
  345. hCurrentWnd = AppMember.pDesktopControl->GetWindowDesktop(AppMember.pDesktopControl->GetActiveDesktop());
  346. UpdateCurrentUI(hCurrentWnd);
  347. return TRUE;
  348. }
  349. //------------------------------------------------------------------------------//
  350. //
  351. // Switch to desktop nDesktop Number
  352. //
  353. //-----------------------------------------------------------------------------//
  354. void SwitchToDesktop(UINT nDesktop) // zero based
  355. {
  356. HWND hTargetWnd;
  357. assert(nDesktop >= 0 && nDesktop < AppMember.pDesktopControl->GetNumDesktops());
  358. //
  359. // Switching to ourself - that is easy.
  360. //
  361. if (nDesktop == AppMember.pDesktopControl->GetActiveDesktop())
  362. {
  363. return;
  364. }
  365. hTargetWnd = AppMember.pDesktopControl->GetWindowDesktop(nDesktop);
  366. UpdateCurrentUI(hTargetWnd);
  367. AppMember.pDesktopControl->ActivateDesktop(nDesktop);
  368. }
  369. /*------------------------------------------------------------------------------*/
  370. /* */
  371. /* RenameDialogProc() - CallBack procedure for the Rename dialog within the */
  372. /* Properties property sheet and the Rename only property sheet */
  373. /* */
  374. /*------------------------------------------------------------------------------*/
  375. LRESULT CALLBACK
  376. RenameDialogProc(HWND hWnd,
  377. UINT nMessage,
  378. WPARAM wParam,
  379. LPARAM lParam)
  380. {
  381. static BOOL bInitialized;
  382. UINT nBtnIndex;
  383. CHAR szTemp[MAX_TITLELEN + 1];
  384. UINT i;
  385. HICON hIcon1;
  386. UINT nCurSel;
  387. UINT nResult;
  388. switch (nMessage)
  389. {
  390. case WM_INITDIALOG:
  391. {
  392. //
  393. // First position the property sheet in the center of the screen
  394. //
  395. HWND hParent = GetParent(hWnd);
  396. assert(hParent);
  397. RECT rc;
  398. if (GetWindowRect(hParent, &rc))
  399. {
  400. SetWindowPos(
  401. hParent,
  402. HWND_TOP,
  403. (GetSystemMetrics(SM_CXSCREEN) / 2) - ((rc.right - rc.left) / 2),
  404. (GetSystemMetrics(SM_CYSCREEN) / 2) - ((rc.bottom - rc.top) / 2),
  405. rc.right - rc.left,
  406. rc.bottom - rc.top,
  407. SWP_SHOWWINDOW);
  408. }
  409. //
  410. // Now initialize the controls
  411. //
  412. PRENAMEINFO pRenameInfo = ((PRENAMEINFO) ((PROPSHEETPAGE *) lParam)->lParam);
  413. nBtnIndex = pRenameInfo->nBtnIndex;
  414. SetWindowLong(hWnd, GWL_USERDATA, (LONG) nBtnIndex);
  415. AppMember.pDesktopControl->GetDesktopName(nBtnIndex, szTemp, MAX_TITLELEN);
  416. SetDlgItemText(hWnd, IDC_EDIT_NAME, szTemp);
  417. //
  418. // Initialize the SAIFER Authorization Object name too.
  419. // The first desktop cannot have a SAIFER object name associated with
  420. // it since its shell has already been launched by the time
  421. // Multidesk starts, so it always runs unmodified.
  422. //
  423. SendDlgItemMessage(hWnd, IDC_EDIT_SAIFER, CB_RESETCONTENT, 0, 0);
  424. SendDlgItemMessage(hWnd, IDC_EDIT_SAIFER, CB_ADDSTRING, 0, (LPARAM) TEXT("(No modification of trust)"));
  425. if (nBtnIndex != 0) {
  426. // all secondary desktops can be modified.
  427. AppMember.pDesktopControl->GetSaiferName(nBtnIndex, szTemp, MAX_TITLELEN);
  428. EnableWindow(GetDlgItem(hWnd, IDC_EDIT_SAIFER), TRUE);
  429. // Fetch the list of all object names.
  430. DWORD dwInfoBufferSize;
  431. LPTSTR InfoBuffer = NULL;
  432. if (!GetInformationCodeAuthzPolicy(AUTHZSCOPE_HKLM,
  433. CodeAuthzPol_ObjectList,
  434. 0, NULL, &dwInfoBufferSize) &&
  435. GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  436. {
  437. InfoBuffer = (LPTSTR) HeapAlloc(GetProcessHeap(), 0, dwInfoBufferSize);
  438. if (InfoBuffer != NULL)
  439. {
  440. if (!GetInformationCodeAuthzPolicy(AUTHZSCOPE_HKLM,
  441. CodeAuthzPol_ObjectList,
  442. dwInfoBufferSize, InfoBuffer, &dwInfoBufferSize))
  443. {
  444. HeapFree(GetProcessHeap(), 0, InfoBuffer);
  445. InfoBuffer = NULL;
  446. }
  447. }
  448. }
  449. // Iterate through and add all of the items.
  450. BOOL bFoundMatch = FALSE;
  451. if (InfoBuffer != NULL)
  452. {
  453. DWORD dwChoiceIndex = 1;
  454. LPCTSTR lpOneChoice = (LPCTSTR) InfoBuffer;
  455. while (*lpOneChoice != TEXT('\0')) {
  456. SendDlgItemMessage(hWnd, IDC_EDIT_SAIFER, CB_ADDSTRING, 0, (LPARAM) lpOneChoice);
  457. if (!bFoundMatch && strcmp(lpOneChoice, szTemp) == 0) {
  458. SendDlgItemMessage(hWnd, IDC_EDIT_SAIFER, CB_SETCURSEL, dwChoiceIndex, 0);
  459. bFoundMatch = TRUE;
  460. }
  461. while (*lpOneChoice++) {};
  462. dwChoiceIndex++;
  463. }
  464. HeapFree(GetProcessHeap(), 0, InfoBuffer);
  465. }
  466. if (!bFoundMatch)
  467. SendDlgItemMessage(hWnd, IDC_EDIT_SAIFER, CB_SETCURSEL, 0, 0);
  468. // Display a little warning if the desktop is already running.
  469. DESKTOP_NODE *pCurrentNode = AppMember.pDesktopControl->GetDesktopNode(nBtnIndex);
  470. if (pCurrentNode != NULL && pCurrentNode->bShellStarted)
  471. SetDlgItemText(hWnd, IDC_SAIFER_NOTETEXT,
  472. TEXT("(desktop shell already started. changes will take effect on next multidesk session)"));
  473. else
  474. SetDlgItemText(hWnd, IDC_SAIFER_NOTETEXT, TEXT(""));
  475. } else {
  476. // the first desktop cannot be modified.
  477. EnableWindow(GetDlgItem(hWnd, IDC_EDIT_SAIFER), FALSE);
  478. SetDlgItemText(hWnd, IDC_SAIFER_NOTETEXT,
  479. TEXT("(the primary desktop cannot run with a modified token)"));
  480. }
  481. //
  482. // Fill up the List Box with the loaded Icons - making the current Icon First (0)
  483. //
  484. HWND hListBox = GetDlgItem(hWnd, IDC_ICONLIST);
  485. SendMessage(hListBox, WM_SETREDRAW, FALSE, 0L);
  486. for (i = 0; i < NUM_BUILTIN_ICONS; i++)
  487. {
  488. SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM) AppMember.pDesktopControl->GetBuiltinIcon(i));
  489. }
  490. SendMessage(hListBox, LB_SETCURSEL,
  491. AppMember.pDesktopControl->GetDesktopIconID(nBtnIndex), 0 );
  492. SendMessage(hListBox, WM_SETREDRAW, TRUE, 0L);
  493. bInitialized = TRUE;
  494. break;
  495. }
  496. case WM_COMMAND:
  497. {
  498. if (HIWORD (wParam) == LBN_SELCHANGE && bInitialized) // Icon box
  499. {
  500. PropSheet_Changed(GetParent(hWnd), hWnd);
  501. InvalidateRect(GetDlgItem(hWnd, IDC_DEFICON), NULL, TRUE);
  502. }
  503. else if ((HIWORD(wParam) == EN_CHANGE) && bInitialized)
  504. {
  505. PropSheet_Changed(GetParent(hWnd), hWnd);
  506. }
  507. break;
  508. }
  509. case WM_MEASUREITEM:
  510. {
  511. //
  512. // Owner Draw List Box Control
  513. //
  514. MEASUREITEMSTRUCT *pMeasureItem = (MEASUREITEMSTRUCT *) lParam;
  515. pMeasureItem->itemWidth = GetSystemMetrics(SM_CXICON) + 12;
  516. pMeasureItem->itemHeight = GetSystemMetrics(SM_CYICON) + 4;
  517. break;
  518. }
  519. case WM_DRAWITEM: // Dlg controls need redrawing
  520. {
  521. HWND hListBox = GetDlgItem(hWnd, IDC_ICONLIST);
  522. DRAWITEMSTRUCT *pDrawItem = (DRAWITEMSTRUCT *) lParam;
  523. if (wParam == IDC_DEFICON ) // Display panel sample icon
  524. {
  525. nCurSel = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
  526. if (nCurSel == LB_ERR)
  527. {
  528. nCurSel = 0;
  529. }
  530. if (LB_ERR == SendMessage(hListBox, LB_GETTEXT, nCurSel, (LPARAM) &hIcon1))
  531. {
  532. nResult = GetLastError();
  533. hIcon1 = LoadIcon(AppMember.hInstance, MAKEINTRESOURCE(IDI_MULTIDESK_ICON));
  534. }
  535. DrawIcon(pDrawItem->hDC,
  536. pDrawItem->rcItem.left,
  537. pDrawItem->rcItem.top,
  538. (HICON) hIcon1);
  539. UpdateWindow(hWnd);
  540. break;
  541. }
  542. if (pDrawItem->itemState & ODS_SELECTED)
  543. {
  544. SetBkColor(pDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
  545. }
  546. else
  547. {
  548. SetBkColor(pDrawItem->hDC, GetSysColor(COLOR_WINDOW));
  549. }
  550. ExtTextOut(pDrawItem->hDC, 0, 0, ETO_OPAQUE, &pDrawItem->rcItem, NULL, 0, NULL);
  551. if ((int) pDrawItem->itemID >= 0)
  552. {
  553. DrawIcon(pDrawItem->hDC,
  554. (pDrawItem->rcItem.left + pDrawItem->rcItem.right - GetSystemMetrics(SM_CXICON)) /2,
  555. (pDrawItem->rcItem.bottom + pDrawItem->rcItem.top - GetSystemMetrics(SM_CYICON)) /2,
  556. (HICON) pDrawItem->itemData);
  557. }
  558. if (pDrawItem->itemState & ODS_FOCUS)
  559. {
  560. DrawFocusRect(pDrawItem->hDC, &pDrawItem->rcItem);
  561. }
  562. break;
  563. }
  564. case WM_DESTROY:
  565. bInitialized = FALSE;
  566. break;
  567. case WM_NOTIFY:
  568. {
  569. LPNMHDR lpNotifyMsg = (NMHDR FAR*) lParam;
  570. switch (lpNotifyMsg->code)
  571. {
  572. case PSN_APPLY:
  573. {
  574. //
  575. // OK or Apply button clicked, save the info -
  576. // Get the main dialog's hwnd and update the button's title
  577. HWND hParent = GetParent(GetParent(hWnd));
  578. assert(hParent);
  579. //// Get number of desktop ////
  580. nBtnIndex = (UINT) GetWindowLong(hWnd, GWL_USERDATA);
  581. //// Get desktop name and save it to Node ////
  582. GetDlgItemText(hWnd, IDC_EDIT_NAME, szTemp, MAX_TITLELEN);
  583. AppMember.pDesktopControl->SetDesktopName(nBtnIndex, szTemp);
  584. //// Get and save the Saifer object name ////
  585. GetDlgItemText(hWnd, IDC_EDIT_SAIFER, szTemp, MAX_TITLELEN);
  586. AppMember.pDesktopControl->SetSaiferName(nBtnIndex, szTemp);
  587. //// Get and save the icon for the desktop ////
  588. HWND hListBox = GetDlgItem(hWnd, IDC_ICONLIST);
  589. nCurSel = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
  590. if (nCurSel != LB_ERR)
  591. {
  592. AppMember.pDesktopControl->SetDesktopIconID(nBtnIndex, nCurSel);
  593. }
  594. //
  595. // Now update the UI
  596. //
  597. UpdateCurrentUI(hWnd);
  598. break;
  599. }
  600. default:
  601. break;
  602. }
  603. break;
  604. }
  605. default:
  606. break;
  607. }
  608. return 0L;
  609. }