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.

810 lines
19 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // nbox.c - notify box functions
  24. ////
  25. #include "winlocal.h"
  26. #include <stdlib.h>
  27. #include "nbox.h"
  28. #include "escbutt.h"
  29. #include "gfx.h"
  30. #include "mem.h"
  31. #include "str.h"
  32. #include "trace.h"
  33. #include "wnd.h"
  34. ////
  35. // private definitions
  36. ////
  37. #define NBOXCLASS TEXT("NBoxClass")
  38. #define NBOXMAXCOLUMNS 60
  39. #define NBOXMAXROWS 20
  40. // nbox control struct
  41. //
  42. typedef struct NBOX
  43. {
  44. DWORD dwVersion;
  45. HINSTANCE hInst;
  46. HTASK hTask;
  47. LPTSTR lpszText;
  48. DWORD dwFlags;
  49. HWND hwndNBox;
  50. BOOL fVisible;
  51. HWND hwndCancel;
  52. BOOL fCancelled;
  53. HWND hwndFocusOld;
  54. HCURSOR hCursorOld;
  55. } NBOX, FAR *LPNBOX;
  56. // helper functions
  57. //
  58. LRESULT DLLEXPORT CALLBACK NBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  59. static BOOL NBoxOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct);
  60. static void NBoxOnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
  61. static void NBoxOnPaint(HWND hwnd);
  62. static LPNBOX NBoxGetPtr(HNBOX hNBox);
  63. static HNBOX NBoxGetHandle(LPNBOX lpNBox);
  64. ////
  65. // public functions
  66. ////
  67. // NBoxCreate - notify box constructor
  68. // <dwVersion> (i) must be NBOX_VERSION
  69. // <hInst> (i) instance handle of calling module
  70. // <hwndParent> (i) window which will own the notify box
  71. // NULL desktop window
  72. // <lpszText> (i) message to be displayed
  73. // <lpszTitle> (i) notify box caption
  74. // NULL no caption
  75. // <lpszButtonText> (i) pushbutton text, if NB_CANCEL specified
  76. // NULL use default text ("Cancel")
  77. // <dwFlags> (i) control flags
  78. // NB_CANCEL notify box includes Cancel pushbutton
  79. // NB_TASKMODAL disable parent task's top-level windows
  80. // NB_HOURGLASS show hourglass cursor while notify box visible
  81. // return notify box handle (NULL if error)
  82. //
  83. // NOTE: NBoxCreate creates the window but does not show it.
  84. // See NBoxShow and NBoxHide.
  85. // The size of the notify box is determined by the number of
  86. // lines in <lpszText>, and the length of the longest line.
  87. //
  88. HNBOX DLLEXPORT WINAPI NBoxCreate(DWORD dwVersion, HINSTANCE hInst,
  89. HWND hwndParent, LPCTSTR lpszText, LPCTSTR lpszTitle,
  90. LPCTSTR lpszButtonText, DWORD dwFlags)
  91. {
  92. BOOL fSuccess = TRUE;
  93. LPNBOX lpNBox = NULL;
  94. WNDCLASS wc;
  95. int nRows;
  96. int nColumns;
  97. int cxChar;
  98. int cyChar;
  99. if (dwVersion != NBOX_VERSION)
  100. fSuccess = TraceFALSE(NULL);
  101. else if (hInst == NULL)
  102. fSuccess = TraceFALSE(NULL);
  103. else if (lpszText == NULL)
  104. fSuccess = TraceFALSE(NULL);
  105. else if ((lpNBox = (LPNBOX) MemAlloc(NULL, sizeof(NBOX), 0)) == NULL)
  106. fSuccess = TraceFALSE(NULL);
  107. else
  108. {
  109. lpNBox->dwVersion = dwVersion;
  110. lpNBox->hInst = hInst;
  111. lpNBox->hTask = GetCurrentTask();
  112. lpNBox->lpszText = NULL;
  113. lpNBox->dwFlags = dwFlags;
  114. lpNBox->hwndNBox = NULL;
  115. lpNBox->fVisible = FALSE;
  116. lpNBox->hwndCancel = NULL;
  117. lpNBox->fCancelled = FALSE;
  118. lpNBox->hwndFocusOld = NULL;
  119. lpNBox->hCursorOld = NULL;
  120. if (hwndParent == NULL)
  121. hwndParent = GetDesktopWindow();
  122. if ((lpNBox->lpszText = StrDup(lpszText)) == NULL)
  123. fSuccess = TraceFALSE(NULL);
  124. }
  125. // register notify box class unless it has been already
  126. //
  127. if (fSuccess && GetClassInfo(lpNBox->hInst, NBOXCLASS, &wc) == 0)
  128. {
  129. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  130. wc.hIcon = (HICON) NULL;
  131. wc.lpszMenuName = NULL;
  132. wc.hInstance = lpNBox->hInst;
  133. wc.lpszClassName = NBOXCLASS;
  134. wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  135. wc.lpfnWndProc = NBoxWndProc;
  136. wc.style = 0L;
  137. wc.cbWndExtra = sizeof(lpNBox);
  138. wc.cbClsExtra = 0;
  139. if (!RegisterClass(&wc))
  140. fSuccess = TraceFALSE(NULL);
  141. }
  142. // create a notify box window
  143. //
  144. if (fSuccess && (lpNBox->hwndNBox = CreateWindowEx(
  145. WS_EX_DLGMODALFRAME,
  146. NBOXCLASS,
  147. (LPTSTR) lpszTitle,
  148. WS_POPUP | (lpszTitle == NULL ? 0 : WS_CAPTION), // | WS_DLGFRAME,
  149. 0, 0, 0, 0, // we will calculate size and position later
  150. #if 1
  151. hwndParent,
  152. #else
  153. (HWND) NULL,
  154. #endif
  155. (HMENU) NULL,
  156. lpNBox->hInst,
  157. lpNBox)) == NULL)
  158. {
  159. fSuccess = TraceFALSE(NULL);
  160. }
  161. // calculate avg char width and height
  162. //
  163. if (fSuccess)
  164. {
  165. HDC hdc = NULL;
  166. TEXTMETRIC tm;
  167. if ((hdc = GetDC(hwndParent)) == NULL)
  168. fSuccess = TraceFALSE(NULL);
  169. else if (!GetTextMetrics(hdc, &tm))
  170. fSuccess = TraceFALSE(NULL);
  171. else
  172. {
  173. cxChar = tm.tmAveCharWidth;
  174. cyChar = tm.tmHeight + tm.tmExternalLeading;
  175. }
  176. if (hdc != NULL && !ReleaseDC(hwndParent, hdc))
  177. fSuccess = TraceFALSE(NULL);
  178. }
  179. if (fSuccess)
  180. {
  181. // calculate size of text
  182. //
  183. if (StrGetRowColumnCount(lpszText, &nRows, &nColumns) != 0)
  184. fSuccess = TraceFALSE(NULL);
  185. nRows = min(nRows, NBOXMAXROWS);
  186. nColumns = min(nColumns, NBOXMAXCOLUMNS);
  187. }
  188. if (fSuccess)
  189. {
  190. int cxNBox;
  191. int cyNBox;
  192. int cxCancel;
  193. int cyCancel;
  194. int xCancel;
  195. int yCancel;
  196. // calculate window size
  197. //
  198. cxNBox = (nColumns + 10) * cxChar +
  199. 2 * GetSystemMetrics(SM_CXBORDER);
  200. cyNBox = (nRows + 4) * cyChar +
  201. 2 * GetSystemMetrics(SM_CYBORDER);
  202. // increase notify box size to accomodate caption
  203. //
  204. if (lpszTitle != NULL)
  205. cyNBox += GetSystemMetrics(SM_CYCAPTION);
  206. if (lpNBox->dwFlags & NB_CANCEL)
  207. {
  208. // calculate cancel button size
  209. //
  210. cxCancel = (40 * (int) LOWORD(GetDialogBaseUnits())) / 4;
  211. cyCancel = (14 * (int) HIWORD(GetDialogBaseUnits())) / 8;
  212. // increase notify box size to accomodate CANCEL button
  213. //
  214. cxNBox = max(cxNBox, cxCancel);
  215. cyNBox += cyCancel * 2;
  216. // calculate cancel button position
  217. //
  218. xCancel = (cxNBox - cxCancel) / 2;
  219. yCancel = (cyNBox - (cyCancel * 2));
  220. // modify cancel button position to accomodate caption
  221. //
  222. if (lpszTitle != NULL)
  223. yCancel -= GetSystemMetrics(SM_CYCAPTION);
  224. }
  225. // set window size
  226. //
  227. if (!SetWindowPos(lpNBox->hwndNBox,
  228. NULL, 0, 0, cxNBox, cyNBox,
  229. SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER))
  230. fSuccess = TraceFALSE(NULL);
  231. // center the window on its parent
  232. //
  233. else if (WndCenterWindow(lpNBox->hwndNBox, hwndParent, 0, 0) != 0)
  234. fSuccess = TraceFALSE(NULL);
  235. else if ((lpNBox->dwFlags & NB_CANCEL))
  236. {
  237. // create cancel button as child of notify box
  238. //
  239. if ((lpNBox->hwndCancel = CreateWindowEx(
  240. 0L,
  241. TEXT("BUTTON"),
  242. lpszButtonText == NULL ? TEXT("Cancel") : lpszButtonText,
  243. WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
  244. xCancel, yCancel, cxCancel, cyCancel,
  245. (HWND) lpNBox->hwndNBox,
  246. (HMENU) IDCANCEL,
  247. lpNBox->hInst,
  248. NULL)) == NULL)
  249. {
  250. fSuccess = TraceFALSE(NULL);
  251. }
  252. // subclass the cancel button, so the escape key pushes it
  253. //
  254. else if (EscButtInit(lpNBox->hwndCancel, 0) != 0)
  255. fSuccess = TraceFALSE(NULL);
  256. }
  257. }
  258. if (!fSuccess)
  259. {
  260. NBoxDestroy(NBoxGetHandle(lpNBox));
  261. lpNBox = NULL;
  262. }
  263. return fSuccess ? NBoxGetHandle(lpNBox) : NULL;
  264. }
  265. // NBoxDestroy - notify box destructor
  266. // <hNBox> (i) handle returned from NBoxCreate
  267. // return 0 if success
  268. //
  269. int DLLEXPORT WINAPI NBoxDestroy(HNBOX hNBox)
  270. {
  271. BOOL fSuccess = TRUE;
  272. LPNBOX lpNBox;
  273. if (NBoxHide(hNBox) != 0)
  274. fSuccess = TraceFALSE(NULL);
  275. else if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  276. fSuccess = TraceFALSE(NULL);
  277. else
  278. {
  279. // destroy text string
  280. //
  281. if (lpNBox->lpszText != NULL &&
  282. StrDupFree(lpNBox->lpszText) != 0)
  283. fSuccess = TraceFALSE(NULL);
  284. else
  285. lpNBox->lpszText = NULL;
  286. // destroy cancel button
  287. //
  288. if (lpNBox->hwndCancel != NULL)
  289. {
  290. if (EscButtTerm(lpNBox->hwndCancel) != 0)
  291. fSuccess = TraceFALSE(NULL);
  292. if (!DestroyWindow(lpNBox->hwndCancel))
  293. fSuccess = TraceFALSE(NULL);
  294. else
  295. lpNBox->hwndCancel = NULL;
  296. }
  297. // destroy notify box
  298. //
  299. if (lpNBox->hwndNBox != NULL &&
  300. !DestroyWindow(lpNBox->hwndNBox))
  301. fSuccess = TraceFALSE(NULL);
  302. else
  303. lpNBox->hwndNBox = NULL;
  304. // destroy control struct
  305. //
  306. if ((lpNBox = MemFree(NULL, lpNBox)) != NULL)
  307. fSuccess = TraceFALSE(NULL);
  308. }
  309. return fSuccess ? 0 : -1;
  310. }
  311. // NBoxShow - show notify box
  312. // <hNBox> (i) handle returned from NBoxCreate
  313. // return 0 if success
  314. //
  315. int DLLEXPORT WINAPI NBoxShow(HNBOX hNBox)
  316. {
  317. BOOL fSuccess = TRUE;
  318. LPNBOX lpNBox;
  319. if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  320. fSuccess = TraceFALSE(NULL);
  321. else if (lpNBox->fVisible)
  322. ; // already visible, so no need to do anything else
  323. else
  324. {
  325. HWND hwndParent = GetParent(lpNBox->hwndNBox);
  326. // disable other windows in this task if necessary
  327. //
  328. if (lpNBox->dwFlags & NB_TASKMODAL)
  329. {
  330. HTASK hTaskParent;
  331. if (hwndParent != NULL)
  332. hTaskParent = GetWindowTask(hwndParent);
  333. else
  334. hTaskParent = lpNBox->hTask;
  335. if (WndEnableTaskWindows(hTaskParent, FALSE, lpNBox->hwndNBox) != 0)
  336. TraceFALSE(NULL); // not a fatal error
  337. }
  338. // otherwise just disable parent of notify box
  339. //
  340. else if (hwndParent != NULL)
  341. EnableWindow(hwndParent, FALSE);
  342. if (fSuccess)
  343. {
  344. // show the window
  345. //
  346. ShowWindow(lpNBox->hwndNBox, TRUE ? SW_SHOW : SW_SHOWNA);
  347. UpdateWindow(lpNBox->hwndNBox);
  348. lpNBox->fVisible = TRUE;
  349. // set focus to cancel button if necessary
  350. //
  351. if (lpNBox->dwFlags & NB_CANCEL && lpNBox->hwndCancel != NULL)
  352. lpNBox->hwndFocusOld = SetFocus(lpNBox->hwndCancel);
  353. }
  354. // display hourglass cursor if specified
  355. //
  356. if (fSuccess && lpNBox->dwFlags & NB_HOURGLASS)
  357. lpNBox->hCursorOld = GfxShowHourglass(lpNBox->hwndNBox);
  358. }
  359. return fSuccess ? 0 : -1;
  360. }
  361. // NBoxHide - hide notify box
  362. // <hNBox> (i) handle returned from NBoxCreate
  363. // return 0 if success
  364. //
  365. int DLLEXPORT WINAPI NBoxHide(HNBOX hNBox)
  366. {
  367. BOOL fSuccess = TRUE;
  368. LPNBOX lpNBox;
  369. if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  370. fSuccess = TraceFALSE(NULL);
  371. else if (!lpNBox->fVisible)
  372. ; // already hidden, so no need to do anything else
  373. else
  374. {
  375. HWND hwndParent = GetParent(lpNBox->hwndNBox);
  376. // enable other windows in this task if necessary
  377. //
  378. if (lpNBox->dwFlags & NB_TASKMODAL)
  379. {
  380. HTASK hTaskParent;
  381. if (hwndParent != NULL)
  382. hTaskParent = GetWindowTask(hwndParent);
  383. else
  384. hTaskParent = lpNBox->hTask;
  385. if (WndEnableTaskWindows(hTaskParent, TRUE, NULL) != 0)
  386. TraceFALSE(NULL); // not a fatal error
  387. }
  388. // otherwise just enable parent of notify box
  389. //
  390. else if (hwndParent != NULL)
  391. EnableWindow(hwndParent, TRUE);
  392. if (fSuccess)
  393. {
  394. // hide the window
  395. //
  396. ShowWindow(lpNBox->hwndNBox, SW_HIDE);
  397. UpdateWindow(lpNBox->hwndNBox);
  398. lpNBox->fVisible = FALSE;
  399. // remove focus from cancel button if necessary
  400. //
  401. if (lpNBox->dwFlags & NB_CANCEL &&
  402. lpNBox->hwndCancel != NULL &&
  403. GetFocus() == lpNBox->hwndCancel)
  404. SetFocus(lpNBox->hwndFocusOld);
  405. }
  406. // hide hourglass, restore old cursor
  407. //
  408. if (fSuccess && lpNBox->dwFlags & NB_HOURGLASS)
  409. {
  410. if (GfxHideHourglass(lpNBox->hCursorOld) != 0)
  411. fSuccess = TraceFALSE(NULL);
  412. else
  413. lpNBox->hCursorOld = NULL;
  414. }
  415. }
  416. return fSuccess ? 0 : -1;
  417. }
  418. // NBoxIsVisible - get visible flag
  419. // <hNBox> (i) handle returned from NBoxCreate
  420. // return TRUE if notify box is visible, FALSE if hidden
  421. //
  422. int DLLEXPORT WINAPI NBoxIsVisible(HNBOX hNBox)
  423. {
  424. BOOL fSuccess = TRUE;
  425. LPNBOX lpNBox;
  426. if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  427. fSuccess = TraceFALSE(NULL);
  428. return fSuccess ? lpNBox->fVisible : FALSE;
  429. }
  430. // NBoxGetWindowHandle - get notify box window handle
  431. // <hNBox> (i) handle returned from NBoxCreate
  432. // return window handle (NULL if error)
  433. //
  434. HWND DLLEXPORT WINAPI NBoxGetWindowHandle(HNBOX hNBox)
  435. {
  436. BOOL fSuccess = TRUE;
  437. LPNBOX lpNBox;
  438. if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  439. fSuccess = TraceFALSE(NULL);
  440. return fSuccess ? lpNBox->hwndNBox : NULL;
  441. }
  442. // NBoxSetText - set notify box message text
  443. // <hNBox> (i) handle returned from NBoxCreate
  444. // <lpszText> (i) message to be displayed
  445. // NULL do not modify text
  446. // <lpszTitle> (i) notify box caption
  447. // NULL do not modify caption
  448. // return 0 if success
  449. //
  450. // NOTE: The size of the notify box is not changed by this function,
  451. // even if <lpszText> is larger than when NBoxCreate() was called.
  452. //
  453. int DLLEXPORT WINAPI NBoxSetText(HNBOX hNBox, LPCTSTR lpszText, LPCTSTR lpszTitle)
  454. {
  455. BOOL fSuccess = TRUE;
  456. LPNBOX lpNBox;
  457. if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  458. fSuccess = TraceFALSE(NULL);
  459. else
  460. {
  461. if (lpszTitle != NULL)
  462. {
  463. // set new title
  464. //
  465. SetWindowText(lpNBox->hwndNBox, lpszTitle);
  466. }
  467. if (lpszText != NULL)
  468. {
  469. // dispose of previous text
  470. //
  471. if (lpNBox->lpszText != NULL)
  472. {
  473. if (StrDupFree(lpNBox->lpszText) != 0)
  474. fSuccess = TraceFALSE(NULL);
  475. else
  476. lpNBox->lpszText = NULL;
  477. }
  478. // set new text
  479. //
  480. if ((lpNBox->lpszText = StrDup(lpszText)) == NULL)
  481. fSuccess = TraceFALSE(NULL);
  482. }
  483. // update the display
  484. //
  485. if (fSuccess)
  486. {
  487. RECT rc;
  488. // assume entire client area needs to be painted
  489. //
  490. GetClientRect(lpNBox->hwndNBox, &rc);
  491. // adjust client rect so cancel button is no repainted
  492. //
  493. if (lpNBox->dwFlags & NB_CANCEL)
  494. {
  495. int cyCancel = (14 * (int) HIWORD(GetDialogBaseUnits())) / 8;
  496. rc.bottom -= cyCancel * 2;
  497. }
  498. InvalidateRect(lpNBox->hwndNBox, &rc, TRUE);
  499. UpdateWindow(lpNBox->hwndNBox);
  500. }
  501. }
  502. return fSuccess ? 0 : -1;
  503. }
  504. // NBoxIsCancelled - get cancel flag, set when Cancel button pushed
  505. // <hNBox> (i) handle returned from NBoxCreate
  506. // return TRUE if notify box Cancel button pushed
  507. //
  508. BOOL DLLEXPORT WINAPI NBoxIsCancelled(HNBOX hNBox)
  509. {
  510. BOOL fSuccess = TRUE;
  511. LPNBOX lpNBox;
  512. if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  513. fSuccess = TraceFALSE(NULL);
  514. return fSuccess ? lpNBox->fCancelled : FALSE;
  515. }
  516. // NBoxSetCancelled - set cancel flag
  517. // <hNBox> (i) handle returned from NBoxCreate
  518. // <fCancelled> (i) new value for cancel flag
  519. // return 0 if success
  520. //
  521. int DLLEXPORT WINAPI NBoxSetCancelled(HNBOX hNBox, BOOL fCancelled)
  522. {
  523. BOOL fSuccess = TRUE;
  524. LPNBOX lpNBox;
  525. if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
  526. fSuccess = TraceFALSE(NULL);
  527. else
  528. lpNBox->fCancelled = fCancelled;
  529. return fSuccess ? 0 : -1;
  530. }
  531. ////
  532. // helper functions
  533. ////
  534. // NBoxWndProc - window procedure for notify box
  535. //
  536. LRESULT DLLEXPORT CALLBACK NBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  537. {
  538. BOOL fSuccess = TRUE;
  539. LRESULT lResult;
  540. switch (msg)
  541. {
  542. case WM_NCCREATE:
  543. lResult = (LRESULT) HANDLE_WM_NCCREATE(hwnd, wParam, lParam, NBoxOnNCCreate);
  544. break;
  545. case WM_COMMAND:
  546. lResult = (LRESULT) HANDLE_WM_COMMAND(hwnd, wParam, lParam, NBoxOnCommand);
  547. break;
  548. case WM_PAINT:
  549. lResult = (LRESULT) HANDLE_WM_PAINT(hwnd, wParam, lParam, NBoxOnPaint);
  550. break;
  551. default:
  552. lResult = DefWindowProc(hwnd, msg, wParam, lParam);
  553. break;
  554. }
  555. return lResult;
  556. }
  557. // NBoxOnNCCreate - handler for WM_NCCREATE message
  558. //
  559. static BOOL NBoxOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)
  560. {
  561. LPNBOX lpNBox = (LPNBOX) lpCreateStruct->lpCreateParams;
  562. lpNBox->hwndNBox = hwnd;
  563. // store lpNBox in window extra bytes
  564. //
  565. SetWindowLongPtr(hwnd, 0, (LONG_PTR) lpNBox);
  566. return FORWARD_WM_NCCREATE(hwnd, lpCreateStruct, DefWindowProc);
  567. }
  568. // NBoxOnCommand - handler for WM_COMMAND message
  569. //
  570. static void NBoxOnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  571. {
  572. // retrieve lpNBox from window extra bytes
  573. //
  574. LPNBOX lpNBox = (LPNBOX) GetWindowLongPtr(hwnd, 0);
  575. if (id == IDCANCEL)
  576. if (codeNotify == BN_CLICKED)
  577. lpNBox->fCancelled = TRUE;
  578. return;
  579. }
  580. // NBoxOnPaint - handler for WM_PAINT message
  581. //
  582. static void NBoxOnPaint(HWND hwnd)
  583. {
  584. BOOL fSuccess = TRUE;
  585. HDC hdc;
  586. PAINTSTRUCT ps;
  587. TEXTMETRIC tm;
  588. int cxChar;
  589. int cyChar;
  590. COLORREF crBkColorOld;
  591. COLORREF crTextColorOld;
  592. int nRows;
  593. int nColumns;
  594. // retrieve lpNBox from window extra bytes
  595. //
  596. LPNBOX lpNBox = (LPNBOX) GetWindowLongPtr(hwnd, 0);
  597. hdc = BeginPaint(hwnd, &ps);
  598. if (!GetTextMetrics(hdc, &tm))
  599. fSuccess = TraceFALSE(NULL);
  600. else
  601. {
  602. cxChar = tm.tmAveCharWidth;
  603. cyChar = tm.tmHeight + tm.tmExternalLeading;
  604. // set foreground and background text colors
  605. //
  606. crBkColorOld = SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  607. crTextColorOld = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  608. if (StrGetRowColumnCount(lpNBox->lpszText, &nRows, &nColumns) != 0)
  609. fSuccess = TraceFALSE(NULL);
  610. else
  611. {
  612. int iRow;
  613. for (iRow = 0; iRow < nRows; ++iRow)
  614. {
  615. TCHAR szRow[NBOXMAXCOLUMNS + 1];
  616. if (StrGetRow(lpNBox->lpszText, iRow, szRow, SIZEOFARRAY(szRow)) != 0)
  617. fSuccess = TraceFALSE(NULL);
  618. else
  619. {
  620. int x = 5 * cxChar;
  621. int y = (iRow + 2) * cyChar;
  622. if (!TextOut(hdc, x, y, szRow, StrLen(szRow)))
  623. fSuccess = TraceFALSE(NULL);
  624. }
  625. }
  626. }
  627. //
  628. // Restore foreground and background in the right place
  629. //
  630. // restore foreground and background text colors
  631. //
  632. SetBkColor(hdc, crBkColorOld);
  633. SetTextColor(hdc, crTextColorOld);
  634. }
  635. //
  636. // Call EndPaint just BeginPaint succeded
  637. //
  638. if( hdc )
  639. EndPaint(hwnd, &ps);
  640. return;
  641. }
  642. // NBoxGetPtr - verify that nbox handle is valid,
  643. // <hNBox> (i) handle returned from NBoxInit
  644. // return corresponding nbox pointer (NULL if error)
  645. //
  646. static LPNBOX NBoxGetPtr(HNBOX hNBox)
  647. {
  648. BOOL fSuccess = TRUE;
  649. LPNBOX lpNBox;
  650. if ((lpNBox = (LPNBOX) hNBox) == NULL)
  651. fSuccess = TraceFALSE(NULL);
  652. else if (IsBadWritePtr(lpNBox, sizeof(NBOX)))
  653. fSuccess = TraceFALSE(NULL);
  654. #ifdef CHECKTASK
  655. // make sure current task owns the nbox handle
  656. //
  657. else if (lpNBox->hTask != GetCurrentTask())
  658. fSuccess = TraceFALSE(NULL);
  659. #endif
  660. return fSuccess ? lpNBox : NULL;
  661. }
  662. // NBoxGetHandle - verify that nbox pointer is valid,
  663. // <lpNBox> (i) pointer to NBOX struct
  664. // return corresponding nbox handle (NULL if error)
  665. //
  666. static HNBOX NBoxGetHandle(LPNBOX lpNBox)
  667. {
  668. BOOL fSuccess = TRUE;
  669. HNBOX hNBox;
  670. if ((hNBox = (HNBOX) lpNBox) == NULL)
  671. fSuccess = TraceFALSE(NULL);
  672. return fSuccess ? hNBox : NULL;
  673. }