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.

536 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. wnd.c
  5. Abstract:
  6. Utilities for window management
  7. Author:
  8. Jim Schmidt (jimschm) 01-Feb-2000
  9. Revision History:
  10. --*/
  11. //
  12. // Includes
  13. //
  14. #include "pch.h"
  15. #define DBG_WND "Wnd"
  16. //
  17. // Strings
  18. //
  19. // None
  20. //
  21. // Constants
  22. //
  23. // None
  24. //
  25. // Macros
  26. //
  27. // None
  28. //
  29. // Types
  30. //
  31. typedef struct {
  32. PCSTR WindowTitle;
  33. DWORD ProcessId;
  34. HWND Match;
  35. } FINDWINDOW_STRUCTA, *PFINDWINDOW_STRUCTA;
  36. typedef struct {
  37. PCWSTR WindowTitle;
  38. DWORD ProcessId;
  39. HWND Match;
  40. } FINDWINDOW_STRUCTW, *PFINDWINDOW_STRUCTW;
  41. //
  42. // Globals
  43. //
  44. static INT g_CursorRefCount = 0;
  45. static HCURSOR g_OldCursor = NULL;
  46. //
  47. // Macro expansion list
  48. //
  49. // None
  50. //
  51. // Private function prototypes
  52. //
  53. // None
  54. //
  55. // Macro expansion definition
  56. //
  57. // None
  58. //
  59. // Code
  60. //
  61. BOOL
  62. CALLBACK
  63. pEnumWndProcA (
  64. HWND hwnd,
  65. LPARAM lParam
  66. )
  67. /*++
  68. Routine Description:
  69. A callback that is called for every top level window on the system. It is
  70. used with pFindParentWindow to locate a specific window.
  71. Arguments:
  72. hwnd - Specifies the handle of the current enumerated window
  73. lParam - Specifies a pointer to a FINDWINDOW_STRUCTA variable that
  74. holds WindowTitle and ProcessId, and receives the
  75. handle if a match is found.
  76. Return Value:
  77. The handle to the matching window, or NULL if no window has the
  78. specified title and process ID.
  79. --*/
  80. {
  81. CHAR title[MAX_MBCHAR_PATH];
  82. DWORD processId;
  83. PFINDWINDOW_STRUCTA p;
  84. BOOL match = FALSE;
  85. p = (PFINDWINDOW_STRUCTA) lParam;
  86. if (!GetWindowThreadProcessId (hwnd, &processId)) {
  87. DEBUGMSG ((DBG_WND, "Enumerated hwnd no longer valid"));
  88. return TRUE;
  89. }
  90. if (processId == p->ProcessId) {
  91. match = TRUE;
  92. }
  93. if (p->WindowTitle) {
  94. GetWindowTextA (hwnd, title, ARRAYSIZE(title));
  95. DEBUGMSGA ((
  96. DBG_NAUSEA,
  97. "Testing window: %s, ID=%08Xh against %s, %08Xh",
  98. title,
  99. processId,
  100. p->WindowTitle,
  101. p->ProcessId
  102. ));
  103. match = match && StringMatchA (title, p->WindowTitle);
  104. }
  105. ELSE_DEBUGMSGA ((
  106. DBG_NAUSEA,
  107. "Testing window: Process ID=%08Xh against %08Xh",
  108. processId,
  109. p->ProcessId
  110. ));
  111. if (match) {
  112. p->Match = hwnd;
  113. #ifdef DEBUG
  114. //
  115. // Get the window title for the following debug message
  116. //
  117. GetWindowTextA (hwnd, title, ARRAYSIZE(title));
  118. DEBUGMSGA ((
  119. DBG_NAUSEA,
  120. "Window found: %s, ID=%u",
  121. title,
  122. processId
  123. ));
  124. #endif
  125. return FALSE; // stop enum
  126. }
  127. return TRUE; // continue enum
  128. }
  129. BOOL
  130. CALLBACK
  131. pEnumWndProcW (
  132. HWND hwnd,
  133. LPARAM lParam
  134. )
  135. {
  136. WCHAR title[MAX_MBCHAR_PATH];
  137. DWORD processId;
  138. PFINDWINDOW_STRUCTW p;
  139. BOOL match = FALSE;
  140. p = (PFINDWINDOW_STRUCTW) lParam;
  141. if (!GetWindowThreadProcessId (hwnd, &processId)) {
  142. DEBUGMSG ((DBG_WND, "Enumerated hwnd no longer valid"));
  143. return TRUE;
  144. }
  145. if (processId == p->ProcessId) {
  146. match = TRUE;
  147. }
  148. if (p->WindowTitle) {
  149. GetWindowTextW (hwnd, title, ARRAYSIZE(title));
  150. DEBUGMSGW ((
  151. DBG_NAUSEA,
  152. "Testing window: %s, ID=%08Xh against %s, %08Xh",
  153. title,
  154. processId,
  155. p->WindowTitle,
  156. p->ProcessId
  157. ));
  158. match = match && StringMatchW (title, p->WindowTitle);
  159. }
  160. ELSE_DEBUGMSGW ((
  161. DBG_NAUSEA,
  162. "Testing window: Process ID=%08Xh against %08Xh",
  163. processId,
  164. p->ProcessId
  165. ));
  166. if (match) {
  167. p->Match = hwnd;
  168. #ifdef DEBUG
  169. //
  170. // Get the window title for the following debug message
  171. //
  172. GetWindowTextW (hwnd, title, ARRAYSIZE(title));
  173. DEBUGMSGA ((
  174. DBG_NAUSEA,
  175. "Window found: %s, ID=%u",
  176. title,
  177. processId
  178. ));
  179. #endif
  180. return FALSE; // stop enum
  181. }
  182. return TRUE; // continue enum
  183. }
  184. HWND
  185. WndFindWindowInProcessA (
  186. IN DWORD ProcessId,
  187. IN PCSTR WindowTitle OPTIONAL
  188. )
  189. /*++
  190. Routine Description:
  191. Finds a window by enumerating all top-level windows, and checking the
  192. process id. The first one to match the optionally supplied title is used.
  193. Arguments:
  194. ProcessId - Specifies the ID of the process who owns the window. If
  195. zero is specified, NULL is returned.
  196. WindowTitle - Specifies the name of the window to find.
  197. Return Value:
  198. The handle to the matching window, or NULL if no window has the
  199. specified title and process ID.
  200. --*/
  201. {
  202. FINDWINDOW_STRUCTA findWndStruct;
  203. //
  204. // If no process ID, we cannot have a match
  205. //
  206. if (!ProcessId) {
  207. DEBUGMSG ((DBG_WND, "ProcessId == 0"));
  208. return NULL;
  209. }
  210. ZeroMemory (&findWndStruct, sizeof (findWndStruct));
  211. findWndStruct.WindowTitle = WindowTitle;
  212. findWndStruct.ProcessId = ProcessId;
  213. EnumWindows (pEnumWndProcA, (LPARAM) &findWndStruct);
  214. return findWndStruct.Match;
  215. }
  216. HWND
  217. WndFindWindowInProcessW (
  218. IN DWORD ProcessId,
  219. IN PCWSTR WindowTitle OPTIONAL
  220. )
  221. {
  222. FINDWINDOW_STRUCTW findWndStruct;
  223. //
  224. // If no process ID, we cannot have a match
  225. //
  226. if (!ProcessId) {
  227. DEBUGMSG ((DBG_WND, "ProcessId == 0"));
  228. return NULL;
  229. }
  230. ZeroMemory (&findWndStruct, sizeof (findWndStruct));
  231. findWndStruct.WindowTitle = WindowTitle;
  232. findWndStruct.ProcessId = ProcessId;
  233. EnumWindows (pEnumWndProcW, (LPARAM) &findWndStruct);
  234. return findWndStruct.Match;
  235. }
  236. #define WIDTH(rect) (rect.right - rect.left)
  237. #define HEIGHT(rect) (rect.bottom - rect.top)
  238. VOID
  239. WndCenterWindow (
  240. IN HWND hwnd,
  241. IN HWND Parent OPTIONAL
  242. )
  243. {
  244. RECT WndRect, ParentRect;
  245. int x, y;
  246. if (!Parent) {
  247. ParentRect.left = 0;
  248. ParentRect.top = 0;
  249. ParentRect.right = GetSystemMetrics (SM_CXFULLSCREEN);
  250. ParentRect.bottom = GetSystemMetrics (SM_CYFULLSCREEN);
  251. } else {
  252. GetWindowRect (Parent, &ParentRect);
  253. }
  254. MYASSERT (IsWindow (hwnd));
  255. GetWindowRect (hwnd, &WndRect);
  256. x = ParentRect.left + (WIDTH(ParentRect) - WIDTH(WndRect)) / 2;
  257. y = ParentRect.top + (HEIGHT(ParentRect) - HEIGHT(WndRect)) / 2;
  258. SetWindowPos (hwnd, NULL, x, y, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
  259. }
  260. VOID
  261. WndTurnOnWaitCursor (
  262. VOID
  263. )
  264. /*++
  265. Routine Description:
  266. WndTurnOnWaitCursor sets the cursor to IDC_WAIT. It maintains a use
  267. counter, so code requring the wait cursor can be nested.
  268. Arguments:
  269. none
  270. Return Value:
  271. none
  272. --*/
  273. {
  274. if (g_CursorRefCount == 0) {
  275. g_OldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  276. }
  277. g_CursorRefCount++;
  278. }
  279. VOID
  280. WndTurnOffWaitCursor (
  281. VOID
  282. )
  283. /*++
  284. Routine Description:
  285. WndTurnOffWaitCursor decrements the wait cursor counter, and if it reaches
  286. zero the cursor is restored.
  287. Arguments:
  288. none
  289. Return Value:
  290. none
  291. --*/
  292. {
  293. if (!g_CursorRefCount) {
  294. DEBUGMSG ((DBG_WHOOPS, "TurnOffWaitCursor called too many times"));
  295. } else {
  296. g_CursorRefCount--;
  297. if (!g_CursorRefCount) {
  298. SetCursor (g_OldCursor);
  299. }
  300. }
  301. }
  302. VOID
  303. WndSetWizardButtonsA (
  304. IN HWND PageHandle,
  305. IN DWORD EnableButtons,
  306. IN DWORD DisableButtons,
  307. IN PCSTR AlternateFinishText OPTIONAL
  308. )
  309. {
  310. DWORD flags = 0;
  311. HWND wizardHandle;
  312. wizardHandle = GetParent (PageHandle);
  313. if (EnableButtons & FINISH_BUTTON) {
  314. MYASSERT (!(EnableButtons & CANCEL_BUTTON));
  315. MYASSERT (!(EnableButtons & NEXT_BUTTON));
  316. MYASSERT (!(DisableButtons & CANCEL_BUTTON));
  317. MYASSERT (!(DisableButtons & NEXT_BUTTON));
  318. MYASSERT (!(DisableButtons & FINISH_BUTTON));
  319. EnableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
  320. DisableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
  321. flags |= PSWIZB_FINISH;
  322. }
  323. if (DisableButtons & FINISH_BUTTON) {
  324. MYASSERT (!(EnableButtons & CANCEL_BUTTON));
  325. MYASSERT (!(EnableButtons & NEXT_BUTTON));
  326. MYASSERT (!(DisableButtons & CANCEL_BUTTON));
  327. MYASSERT (!(DisableButtons & NEXT_BUTTON));
  328. EnableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
  329. DisableButtons &= ~(CANCEL_BUTTON|NEXT_BUTTON);
  330. flags |= PSWIZB_DISABLEDFINISH;
  331. }
  332. if (EnableButtons & NEXT_BUTTON) {
  333. MYASSERT (!(DisableButtons & NEXT_BUTTON));
  334. flags |= PSWIZB_NEXT;
  335. }
  336. if (EnableButtons & BACK_BUTTON) {
  337. MYASSERT (!(DisableButtons & BACK_BUTTON));
  338. flags |= PSWIZB_BACK;
  339. }
  340. if (DisableButtons & NEXT_BUTTON) {
  341. flags &= ~PSWIZB_NEXT;
  342. }
  343. if (DisableButtons & BACK_BUTTON) {
  344. flags &= ~PSWIZB_BACK;
  345. }
  346. PropSheet_SetWizButtons (wizardHandle, flags);
  347. if (EnableButtons & CANCEL_BUTTON) {
  348. EnableWindow (GetDlgItem (wizardHandle, IDCANCEL), TRUE);
  349. }
  350. if (DisableButtons & CANCEL_BUTTON) {
  351. EnableWindow (GetDlgItem (wizardHandle, IDCANCEL), FALSE);
  352. }
  353. if (AlternateFinishText) {
  354. if (flags & PSWIZB_FINISH) {
  355. SendMessage (
  356. wizardHandle,
  357. PSM_SETFINISHTEXT,
  358. 0,
  359. (LPARAM) AlternateFinishText
  360. );
  361. }
  362. }
  363. }
  364. VOID
  365. WndSetWizardButtonsW (
  366. IN HWND PageHandle,
  367. IN DWORD EnableButtons,
  368. IN DWORD DisableButtons,
  369. IN PCWSTR AlternateFinishText OPTIONAL
  370. )
  371. {
  372. PCSTR ansiText;
  373. if (AlternateFinishText) {
  374. ansiText = ConvertWtoA (AlternateFinishText);
  375. WndSetWizardButtonsA (PageHandle, EnableButtons, DisableButtons, ansiText);
  376. FreeConvertedStr (ansiText);
  377. } else {
  378. WndSetWizardButtonsA (PageHandle, EnableButtons, DisableButtons, NULL);
  379. }
  380. }