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.

432 lines
12 KiB

  1. // **************************************************************************
  2. //
  3. // RunOnce.Cpp
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1992-1993
  7. // All rights reserved
  8. //
  9. // RunOnce wrapper. This encapsulates all applications that would like
  10. // to run the first time we re-boot. It lists these apps for the user
  11. // and allows the user to launce the apps (like apple at ease).
  12. //
  13. // 5 June 1994 FelixA Started
  14. // 8 June Felix Defined registry strings and functionality.
  15. // Got small buttons displayed, but not working.
  16. // 9 June Felix Both big and small buttons. Nice UI.
  17. // Got single click app launching.
  18. //
  19. // 23 June Felix Moving it to a Chicago make thingy not Dolphin
  20. //
  21. // *************************************************************************/
  22. //
  23. #include "iernonce.h"
  24. #include "resource.h"
  25. #define CXBORDER 3
  26. // globals
  27. HDC g_hdcMem = NULL; // Run time can be set for big or small buttons.
  28. int g_cxSmIcon = 0; // Icon sizes.
  29. SIZE g_SizeTextExt; // Extent of text in buttons.
  30. HFONT g_hfont = NULL;
  31. HFONT g_hBoldFont = NULL;
  32. HBRUSH g_hbrBkGnd = NULL;
  33. ARGSINFO g_aiArgs;
  34. // prototypes
  35. BOOL CreateGlobals(HWND hwndCtl);
  36. BOOL RunOnceFill(HWND hWndLB);
  37. void ShrinkToFit(HWND hWnd, HWND hLb);
  38. DWORD RunAppsInList(LPVOID lp);
  39. LRESULT HandleLBMeasureItem(HWND hwndLB, MEASUREITEMSTRUCT *lpmi);
  40. LRESULT HandleLBDrawItem(HWND hwndLB, DRAWITEMSTRUCT *lpdi);
  41. void DestroyGlobals(void);
  42. INT_PTR CALLBACK DlgProcRunOnceEx(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  43. {
  44. static HANDLE s_hThread = NULL;
  45. DWORD dwThread;
  46. switch (uMsg)
  47. {
  48. case WM_INITDIALOG:
  49. g_aiArgs = *((ARGSINFO *) lParam);
  50. CreateGlobals(hWnd);
  51. SetWindowPos(hWnd, NULL, 32, 32, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  52. RunOnceFill(GetDlgItem(hWnd, IDC_LIST2));
  53. // Now calculate the size needed for the LB and resize LB and parent.
  54. ShrinkToFit(hWnd, GetDlgItem(hWnd, IDC_LIST2));
  55. if ((s_hThread = CreateThread(NULL, 0, RunAppsInList, (LPVOID) GetDlgItem(hWnd, IDC_LIST2), 0, &dwThread)) == NULL)
  56. PostMessage(hWnd, WM_FINISHED, 0, 0L);
  57. break;
  58. case WM_SETCURSOR:
  59. if (g_aiArgs.dwFlags & RRA_WAIT)
  60. SetCursor(LoadCursor(NULL, IDC_WAIT));
  61. return TRUE;
  62. case WM_MEASUREITEM:
  63. if (((MEASUREITEMSTRUCT *) lParam)->CtlType == ODT_LISTBOX)
  64. return HandleLBMeasureItem(hWnd, (MEASUREITEMSTRUCT *) lParam);
  65. else
  66. return FALSE;
  67. case WM_DRAWITEM:
  68. if (((DRAWITEMSTRUCT *) lParam)->CtlType == ODT_LISTBOX)
  69. return HandleLBDrawItem(hWnd, (DRAWITEMSTRUCT *) lParam);
  70. else
  71. return FALSE;
  72. case WM_CTLCOLORLISTBOX:
  73. SetTextColor((HDC) wParam, GetSysColor(COLOR_BTNTEXT));
  74. SetBkColor((HDC) wParam, GetSysColor(COLOR_BTNFACE));
  75. return (LRESULT) g_hbrBkGnd;
  76. case WM_FINISHED:
  77. if (s_hThread != NULL)
  78. {
  79. while (MsgWaitForMultipleObjects(1, &s_hThread, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
  80. {
  81. MSG msg;
  82. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  83. {
  84. TranslateMessage(&msg);
  85. DispatchMessage(&msg);
  86. }
  87. }
  88. CloseHandle(s_hThread);
  89. s_hThread = NULL;
  90. }
  91. DestroyGlobals();
  92. EndDialog(hWnd, 0);
  93. break;
  94. default:
  95. return FALSE;
  96. }
  97. return TRUE;
  98. }
  99. LPSTR MakeAnsiStrFromWide(LPWSTR pwsz)
  100. {
  101. LPSTR psz;
  102. int i;
  103. // arg checking.
  104. //
  105. if (!pwsz)
  106. return NULL;
  107. // compute the length
  108. //
  109. i = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, NULL, 0, NULL, NULL);
  110. if (i <= 0) return NULL;
  111. psz = (LPSTR) CoTaskMemAlloc(i * sizeof(CHAR));
  112. if (!psz) return NULL;
  113. WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, i, NULL, NULL);
  114. psz[i - 1] = 0;
  115. return psz;
  116. }
  117. BOOL CreateGlobals(HWND hwndCtl)
  118. {
  119. LOGFONT lf;
  120. HDC hdc;
  121. HFONT hfontOld;
  122. g_cxSmIcon = GetSystemMetrics(SM_CXSMICON);
  123. g_hbrBkGnd = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  124. if ((hfontOld = (HFONT) (WORD) SendMessage(hwndCtl, WM_GETFONT, 0, 0L)) != NULL)
  125. {
  126. if (GetObject(hfontOld, sizeof(LOGFONT), (LPSTR) &lf))
  127. {
  128. // The CreateFontIndirect calls in IESetup Wzd works correctly on
  129. // all platforms... and they convert the Font name to Ansi
  130. // Hence to solve the Thai NT/Thai Win9x problem, we also convert
  131. // the font name to Ansi before calling CreateFontIndirect.
  132. // #58923: Now the FaceName returned by GetObject is not UNICODE on all
  133. // platforms. On Win9x, it is Ansi and this screws up things when
  134. // we call MakeAnsiStrFromWide on it. Hence to avoid problems, check
  135. // if returned FaceName is Wide <asumming FaceName always has more
  136. // than 2 chars in it.>
  137. if (lf.lfFaceName[1] == '\0')
  138. {
  139. LPSTR pszAnsiName;
  140. pszAnsiName = MakeAnsiStrFromWide((unsigned short *)lf.lfFaceName);
  141. lstrcpy((char *)lf.lfFaceName, pszAnsiName);
  142. CoTaskMemFree((LPVOID)pszAnsiName);
  143. }
  144. lf.lfWeight = 400;
  145. g_hfont = CreateFontIndirect(&lf);
  146. lf.lfWeight = 700;
  147. g_hBoldFont = CreateFontIndirect(&lf);
  148. }
  149. }
  150. if (g_hfont)
  151. {
  152. TCHAR *szLotsaWs = TEXT("WWWWWWWWWW");
  153. // Calc sensible size for text in buttons.
  154. hdc = GetDC(NULL);
  155. hfontOld = (HFONT) SelectObject(hdc, g_hfont);
  156. GetTextExtentPoint(hdc, szLotsaWs, lstrlen(szLotsaWs), &g_SizeTextExt);
  157. SelectObject(hdc, hfontOld);
  158. ReleaseDC(NULL, hdc);
  159. return TRUE;
  160. }
  161. return FALSE;
  162. }
  163. //***************************************************************************
  164. //
  165. // RunOnceFill()
  166. // Fills the List box in the run-once dlg.
  167. //
  168. // ENTRY:
  169. // HWND of the thing to fill.
  170. //
  171. // EXIT:
  172. // <Params>
  173. //
  174. //***************************************************************************
  175. BOOL RunOnceFill(HWND hWndLB)
  176. {
  177. RunOnceExSection *pCurrentRunOnceExSection;
  178. int iSectionIndex;
  179. // if Title value is present, display it
  180. if (*g_szTitleString)
  181. SetWindowText(GetParent(hWndLB), g_szTitleString);
  182. for (iSectionIndex = 0; iSectionIndex < g_aiArgs.iNumberOfSections; iSectionIndex++)
  183. {
  184. pCurrentRunOnceExSection = (RunOnceExSection *) DPA_GetPtr(g_aiArgs.hdpaSections, iSectionIndex);
  185. if (*pCurrentRunOnceExSection->m_szDisplayName != TEXT('\0'))
  186. SendMessage(hWndLB, LB_ADDSTRING, 0, (LPARAM) pCurrentRunOnceExSection->m_szDisplayName);
  187. }
  188. return TRUE;
  189. }
  190. //***************************************************************************
  191. //
  192. // ShrinkToFit()
  193. // Makes the List box no bigger then it has to be
  194. // makes the parent window rsize to the LB size.
  195. //
  196. // ENTRY:
  197. // hwnd Parent
  198. // hwnd List box
  199. //
  200. // EXIT:
  201. //
  202. //***************************************************************************
  203. void ShrinkToFit(HWND hWnd, HWND hLb)
  204. {
  205. LONG lCount;
  206. LONG lNumItems;
  207. LONG lTotalHeight;
  208. LONG lHeight;
  209. RECT rWnd;
  210. LONG lChange;
  211. lTotalHeight = 0;
  212. lNumItems = (LONG)SendMessage(hLb, LB_GETCOUNT, 0, 0L);
  213. for (lCount = 0; lCount < lNumItems; lCount++)
  214. {
  215. lHeight = (LONG)SendMessage(hLb, LB_GETITEMHEIGHT, lCount, 0L);
  216. lTotalHeight += lHeight;
  217. }
  218. // Set the height of the ListBox to the number of items in it.
  219. GetWindowRect(hLb, &rWnd);
  220. SetWindowPos(hLb, hWnd, 0, 0, rWnd.right - rWnd.left - (CXBORDER * 2 + g_cxSmIcon), lTotalHeight, SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER);
  221. // Work out how much it changed in height
  222. lChange = lTotalHeight - (rWnd.bottom - rWnd.top);
  223. // Size the parent to fit around the child.
  224. GetWindowRect(hWnd, &rWnd);
  225. SetWindowPos(hWnd, 0, 0, 0, rWnd.right - rWnd.left, rWnd.bottom - rWnd.top + lChange, SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER);
  226. }
  227. //***************************************************************************
  228. //
  229. // RunAppsInList()
  230. // Enumerates all the items in the list box, spawning each in turn.
  231. //
  232. // ENTRY:
  233. // HWND of Parent.
  234. //
  235. // EXIT:
  236. // <Params>
  237. //
  238. //***************************************************************************
  239. DWORD RunAppsInList(LPVOID lp)
  240. {
  241. ProcessSections(g_aiArgs.hkeyParent, g_aiArgs.pszSubkey, g_aiArgs.dwFlags, g_aiArgs.hdpaSections, g_aiArgs.iNumberOfSections, (HWND) lp);
  242. // terminate the dialog box
  243. PostMessage(GetParent((HWND) lp), WM_FINISHED, 0, 0L);
  244. return 0;
  245. }
  246. LRESULT HandleLBMeasureItem(HWND hDlg, MEASUREITEMSTRUCT *lpmi)
  247. {
  248. RECT rWnd;
  249. int wWnd;
  250. HDC hDC;
  251. HFONT hfontOld;
  252. TCHAR szText[MAX_ENTRYNAME];
  253. // Get the Height and Width of the child window
  254. GetWindowRect(hDlg, &rWnd);
  255. wWnd = rWnd.right - rWnd.left;
  256. lpmi->itemWidth = wWnd;
  257. hDC = GetDC(NULL);
  258. if ((hfontOld = (HFONT) SelectObject(hDC, g_hBoldFont)) != 0)
  259. {
  260. rWnd.top = 0;
  261. rWnd.left = CXBORDER * 2 + g_cxSmIcon;
  262. rWnd.right = lpmi->itemWidth - rWnd.left - CXBORDER * 2 - g_cxSmIcon;
  263. rWnd.bottom = 0;
  264. *szText = TEXT('\0');
  265. SendMessage(GetDlgItem(hDlg, IDC_LIST2), LB_GETTEXT, (WPARAM) lpmi->itemID, (LPARAM) szText);
  266. DrawText(hDC, szText, lstrlen(szText), &rWnd, DT_CALCRECT | DT_WORDBREAK);
  267. SelectObject(hDC, hfontOld);
  268. }
  269. ReleaseDC(NULL, hDC);
  270. lpmi->itemHeight = rWnd.bottom + CXBORDER * 2;
  271. return TRUE;
  272. }
  273. //***************************************************************************
  274. //
  275. // HandleLBDrawItem()
  276. // Draws the Title, Text, and icon for an entry.
  277. //
  278. // ENTRY:
  279. // HWND and the Item to draw.
  280. //
  281. // EXIT:
  282. // <Params>
  283. //
  284. //***************************************************************************
  285. LRESULT HandleLBDrawItem(HWND hDlg, DRAWITEMSTRUCT *lpdi)
  286. {
  287. RECT rc;
  288. HFONT hfontOld;
  289. int xArrow,y;
  290. BITMAP bm;
  291. HGDIOBJ hbmArrow, hbmOld;
  292. TCHAR szText[MAX_ENTRYNAME];
  293. // Don't draw anything for an empty list.
  294. if ((int) lpdi->itemID < 0)
  295. return TRUE;
  296. if ((lpdi->itemAction & ODA_SELECT) || (lpdi->itemAction & ODA_DRAWENTIRE))
  297. {
  298. // Put in the Title text
  299. hfontOld = (HFONT) SelectObject(lpdi->hDC, (lpdi->itemState & ODS_SELECTED) ? g_hBoldFont : g_hfont);
  300. ExtTextOut(lpdi->hDC, lpdi->rcItem.left + CXBORDER * 2 + g_cxSmIcon, lpdi->rcItem.top + CXBORDER,
  301. ETO_OPAQUE, &lpdi->rcItem, NULL, 0, NULL);
  302. rc.top = lpdi->rcItem.top + CXBORDER;
  303. rc.left = lpdi->rcItem.left + CXBORDER * 2 + g_cxSmIcon;
  304. rc.right = lpdi->rcItem.right;
  305. rc.bottom = lpdi->rcItem.bottom;
  306. *szText = TEXT('\0');
  307. SendMessage(GetDlgItem(hDlg, IDC_LIST2), LB_GETTEXT, (WPARAM) lpdi->itemID, (LPARAM) szText);
  308. DrawText(lpdi->hDC, szText, lstrlen(szText), &rc, DT_WORDBREAK);
  309. SelectObject(lpdi->hDC, hfontOld);
  310. // Draw the little triangle thingies.
  311. if (lpdi->itemState & ODS_SELECTED)
  312. {
  313. if (!g_hdcMem)
  314. {
  315. g_hdcMem = CreateCompatibleDC(lpdi->hDC);
  316. }
  317. if (g_hdcMem)
  318. {
  319. hbmArrow = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_MNARROW));
  320. GetObject(hbmArrow, sizeof(bm), &bm);
  321. hbmOld = SelectObject(g_hdcMem, hbmArrow);
  322. xArrow = lpdi->rcItem.left + CXBORDER;
  323. y = ((g_SizeTextExt.cy - bm.bmHeight) / 2) + CXBORDER + lpdi->rcItem.top;
  324. BitBlt(lpdi->hDC, xArrow, y, bm.bmWidth, bm.bmHeight, g_hdcMem, 0, 0, SRCAND);
  325. SelectObject(g_hdcMem, hbmOld);
  326. DeleteObject(hbmArrow);
  327. }
  328. }
  329. }
  330. return TRUE;
  331. }
  332. void DestroyGlobals(void)
  333. {
  334. if (g_hfont)
  335. {
  336. DeleteObject(g_hfont);
  337. g_hfont = NULL;
  338. }
  339. if (g_hBoldFont)
  340. {
  341. DeleteObject(g_hBoldFont);
  342. g_hBoldFont = NULL;
  343. }
  344. if (g_hbrBkGnd)
  345. {
  346. DeleteObject(g_hbrBkGnd);
  347. g_hbrBkGnd = NULL;
  348. }
  349. }