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.

767 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. sendopts.c
  5. Abstract:
  6. Functions for handling events in the "Send Options" tab of
  7. the fax server configuration property sheet
  8. Environment:
  9. Fax configuration applet
  10. Revision History:
  11. 03/13/96 -davidx-
  12. Created it.
  13. mm/dd/yy -author-
  14. description
  15. --*/
  16. #include "faxcpl.h"
  17. //
  18. // Information about the fax device list view on "Send Options" page
  19. //
  20. static COLUMNINFO faxDeviceListViewColumnInfo[] = {
  21. { COLUMN_DEVICE_NAME, 2 },
  22. { COLUMN_TSID, 1 },
  23. { 0, 0 },
  24. };
  25. VOID
  26. DoInitSendOptions(
  27. HWND hDlg
  28. )
  29. /*++
  30. Routine Description:
  31. Perform one-time initialization of "Send Options" property page
  32. Arguments:
  33. hDlg - Window handle to the "Send Options" property page
  34. Return Value:
  35. NONE
  36. --*/
  37. {
  38. //
  39. // Maximum length for various text fields in the dialog
  40. //
  41. static INT textLimits[] = {
  42. IDC_TSID, 21,
  43. IDC_ARCHIVE_DIRECTORY, MAX_ARCHIVE_DIR,
  44. 0,
  45. };
  46. LimitTextFields(hDlg, textLimits);
  47. //
  48. // Connect to the fax service and retrieve the list of fax devices
  49. //
  50. GetFaxDeviceAndConfigInfo();
  51. //
  52. // Initialize the dialog appearance
  53. //
  54. if (gConfigData->configType != FAXCONFIG_SERVER) {
  55. EnableWindow(GetDlgItem(hDlg, IDC_NEW_PRINTER), FALSE);
  56. EnableWindow(GetDlgItem(hDlg, IDC_DELETE_PRINTER), FALSE);
  57. }
  58. }
  59. VOID
  60. ToggleArchiveControls(
  61. HWND hDlg
  62. )
  63. /*++
  64. Routine Description:
  65. Enable/disable archive directory edit box and browse button
  66. depending on whether archive outgoing fax checkbox is checked
  67. Arguments:
  68. hDlg - Window handle to the "Send Options" property page
  69. Return Value:
  70. NONE
  71. --*/
  72. {
  73. BOOL enabled = (IsDlgButtonChecked(hDlg, IDC_ARCHIVE_CHECKBOX) == BST_CHECKED);
  74. EnableWindow(GetDlgItem(hDlg, IDC_ARCHIVE_DIRECTORY), enabled);
  75. EnableWindow(GetDlgItem(hDlg, IDC_BROWSE_DIR), enabled && gConfigData->pServerName == NULL);
  76. }
  77. VOID
  78. DoActivateSendOptions(
  79. HWND hDlg
  80. )
  81. /*++
  82. Routine Description:
  83. Called when the "Send Options" property page is activated
  84. Arguments:
  85. hDlg - Window handle to the "Send Options" property page
  86. Return Value:
  87. NONE
  88. --*/
  89. {
  90. //
  91. // Controls on the "Send Options" page which may be enabled or disabled
  92. //
  93. static INT sendOptionsCtrls[] = {
  94. IDC_FAX_DEVICE_LIST,
  95. IDC_TSID,
  96. IDC_ARCHIVE_CHECKBOX,
  97. IDC_ARCHIVE_DIRECTORY,
  98. IDC_BROWSE_DIR,
  99. 0,
  100. };
  101. BOOL enabled = FALSE;
  102. LPTSTR pPortName = NULL;
  103. BOOL devListInSync;
  104. HWND hwndLV;
  105. LPTSTR pArchiveDir;
  106. INT index;
  107. //
  108. // Redisplay the fax device list if it's out-of-sync
  109. //
  110. hwndLV = GetDlgItem(hDlg, IDC_FAX_DEVICE_LIST);
  111. if (! (devListInSync = IsFaxDeviceListInSync(SEND_OPTIONS_PAGE))) {
  112. InitFaxDeviceListView(hwndLV, LV_HASCHECKBOX, faxDeviceListViewColumnInfo);
  113. SetFaxDeviceListInSync(SEND_OPTIONS_PAGE);
  114. for (index=0; index < gConfigData->cDevices; index++) {
  115. if (gConfigData->pDevInfo[index].Flags & FPF_SEND) {
  116. CheckListViewItem(hwndLV, index);
  117. }
  118. }
  119. }
  120. SetChangedFlag(hDlg, SEND_OPTIONS_PAGE, FALSE);
  121. Verbose(("Updating 'Send Options' page ...\n"));
  122. //
  123. // Discount rate period
  124. //
  125. InitTimeControl(hDlg, IDC_TC_CHEAP_BEGIN, &gConfigData->pFaxConfig->StartCheapTime);
  126. InitTimeControl(hDlg, IDC_TC_CHEAP_END, &gConfigData->pFaxConfig->StopCheapTime);
  127. //
  128. // Archive directory
  129. //
  130. pArchiveDir = gConfigData->pFaxConfig->ArchiveDirectory;
  131. CheckDlgButton(
  132. hDlg,
  133. IDC_ARCHIVE_CHECKBOX,
  134. gConfigData->pFaxConfig->ArchiveOutgoingFaxes ? BST_CHECKED : BST_UNCHECKED
  135. );
  136. MySetDlgItemText(hDlg, IDC_ARCHIVE_DIRECTORY, pArchiveDir ? pArchiveDir : TEXT(""));
  137. enabled = TRUE;
  138. //
  139. // Disable or enable the controls depending on whether the user
  140. // has privilege to perform printer administration.
  141. //
  142. EnableControls(hDlg, sendOptionsCtrls, enabled);
  143. EnableTimeControl(hDlg, IDC_TC_CHEAP_BEGIN, enabled);
  144. EnableTimeControl(hDlg, IDC_TC_CHEAP_END, enabled);
  145. if (enabled) {
  146. ToggleArchiveControls(hDlg);
  147. }
  148. }
  149. BOOL
  150. DoSaveSendOptions(
  151. HWND hDlg
  152. )
  153. /*++
  154. Routine Description:
  155. Save the information on the "Send Options" property page
  156. Arguments:
  157. hDlg - Handle to the "Send Options" property page
  158. Return Value:
  159. TRUE if successful, FALSE if there is an error
  160. --*/
  161. #define FAIL_SAVE_SEND_OPTIONS(err) { errorId = err; goto ExitSaveSendOptions; }
  162. {
  163. INT errorId = 0;
  164. LPTSTR pPortName = NULL;
  165. FAX_TIME beginTime, endTime;
  166. INT archiveFlag;
  167. TCHAR archiveDir[MAX_PATH];
  168. //
  169. // Check if anything on this page was changed
  170. //
  171. Verbose(("Saving 'Send Options' page ...\n"));
  172. if (! GetChangedFlag(SEND_OPTIONS_PAGE)) {
  173. return TRUE;
  174. }
  175. //
  176. // Save discount rate period and archive directory information
  177. //
  178. GetTimeControlValue(hDlg, IDC_TC_CHEAP_BEGIN, &beginTime);
  179. GetTimeControlValue(hDlg, IDC_TC_CHEAP_END, &endTime);
  180. archiveFlag = IsDlgButtonChecked(hDlg, IDC_ARCHIVE_CHECKBOX);
  181. if (! GetDlgItemText(hDlg, IDC_ARCHIVE_DIRECTORY, archiveDir, MAX_PATH)) {
  182. if (archiveFlag) {
  183. FAIL_SAVE_SEND_OPTIONS(IDS_MISSING_ARCHIVEDIR);
  184. }
  185. archiveDir[0] = NUL;
  186. }
  187. gConfigData->pFaxConfig->StartCheapTime = beginTime;
  188. gConfigData->pFaxConfig->StopCheapTime = endTime;
  189. gConfigData->pFaxConfig->ArchiveOutgoingFaxes = archiveFlag;
  190. if (gConfigData->pFaxConfig->ArchiveDirectory) {
  191. MemFree( gConfigData->pFaxConfig->ArchiveDirectory );
  192. gConfigData->pFaxConfig->ArchiveDirectory = NULL;
  193. }
  194. gConfigData->pFaxConfig->ArchiveDirectory = DuplicateString( archiveDir );
  195. ExitSaveSendOptions:
  196. MemFree(pPortName);
  197. //
  198. // Display a message box if an error is encountered
  199. //
  200. if (errorId != 0) {
  201. DisplayMessageDialog(hDlg, 0, 0, errorId);
  202. return FALSE;
  203. }
  204. //
  205. // Save the fax device information if this is the last modified page
  206. //
  207. return SaveFaxDeviceAndConfigInfo(hDlg, SEND_OPTIONS_PAGE);
  208. }
  209. VOID
  210. DoChangeTSID(
  211. HWND hDlg
  212. )
  213. /*++
  214. Routine Description:
  215. Called when the user changes sending station identifier (TSID)
  216. Arguments:
  217. hDlg - Handle to the "Send Options" property page
  218. Return Value:
  219. NONE
  220. --*/
  221. {
  222. TCHAR buffer[MAX_STRING_LEN];
  223. INT index = -1;
  224. HWND hwndLV;
  225. if (! (hwndLV = GetDlgItem(hDlg, IDC_FAX_DEVICE_LIST)))
  226. return;
  227. if (! GetDlgItemText(hDlg, IDC_TSID, buffer, MAX_STRING_LEN))
  228. buffer[0] = NUL;
  229. while ((index = ListView_GetNextItem(hwndLV, index, LVNI_ALL|LVNI_SELECTED)) != -1) {
  230. Assert(index < gConfigData->cDevices);
  231. MemFree(gConfigData->pDevInfo[index].TSID);
  232. gConfigData->pDevInfo[index].TSID = DuplicateString(buffer);
  233. }
  234. }
  235. VOID
  236. DoChangeSendDeviceSel(
  237. HWND hDlg,
  238. HWND hwndLV
  239. )
  240. /*++
  241. Routine Description:
  242. Process selection change events in the fax device list
  243. Arguments:
  244. hDlg - Window handle to the "Send Options" property page
  245. hwndLV - Handle to the fax device list
  246. Return Value:
  247. NONE
  248. --*/
  249. {
  250. LPTSTR tsid = NULL;
  251. INT index;
  252. //
  253. // Find the common attributes shared by selected devices
  254. //
  255. if ((index = ListView_GetNextItem(hwndLV, -1, LVNI_ALL|LVNI_SELECTED)) != -1) {
  256. Assert(index < gConfigData->cDevices);
  257. tsid = gConfigData->pDevInfo[index].TSID;
  258. EnableWindow(GetDlgItem(hDlg, IDC_TSID), TRUE);
  259. while ((index = ListView_GetNextItem(hwndLV, index, LVNI_ALL|LVNI_SELECTED)) != -1) {
  260. Assert(index < gConfigData->cDevices);
  261. if (! tsid ||
  262. ! gConfigData->pDevInfo[index].TSID ||
  263. _tcscmp(tsid, gConfigData->pDevInfo[index].TSID) != EQUAL_STRING)
  264. {
  265. tsid = NULL;
  266. break;
  267. }
  268. }
  269. } else {
  270. EnableWindow(GetDlgItem(hDlg, IDC_TSID), FALSE);
  271. }
  272. MySetDlgItemText(hDlg, IDC_TSID, tsid ? tsid : TEXT(""));
  273. }
  274. VOID
  275. ToggleFaxDeviceForSend(
  276. HWND hwndLV,
  277. INT index
  278. )
  279. /*++
  280. Routine Description:
  281. Toggle a fax device for sending
  282. Arguments:
  283. hwndLV - Handle to the fax device list view
  284. index - Specifies the fax device to be toggled
  285. Return Value:
  286. NONE
  287. --*/
  288. {
  289. if (IsListViewItemChecked(hwndLV, index)) {
  290. UncheckListViewItem(hwndLV, index);
  291. gConfigData->pDevInfo[index].Flags &= ~FPF_SEND;
  292. } else {
  293. CheckListViewItem(hwndLV, index);
  294. gConfigData->pDevInfo[index].Flags |= FPF_SEND;
  295. //
  296. // NOTE: Since we allow at most one fax device for sending on workstation
  297. // configuration, here we must make sure to disable all other fax devices.
  298. //
  299. if (gConfigData->configType == FAXCONFIG_WORKSTATION) {
  300. INT count = ListView_GetItemCount(hwndLV);
  301. while (count-- > 0) {
  302. if (count != index) {
  303. UncheckListViewItem(hwndLV, count);
  304. gConfigData->pDevInfo[count].Flags &= ~FPF_SEND;
  305. }
  306. }
  307. }
  308. }
  309. }
  310. BOOL
  311. HandleSendListViewMessage(
  312. HWND hDlg,
  313. LPNMHDR pNMHdr
  314. )
  315. /*++
  316. Routine Description:
  317. Handle notification events from the fax device list
  318. Arguments:
  319. hDlg - Window handle to the "Send Options" property page
  320. pNMHdr - Points to an NMHDR structure
  321. Return Value:
  322. TRUE if any change was made to the fax device list
  323. FALSE otherwise
  324. --*/
  325. {
  326. LV_HITTESTINFO hitTestInfo;
  327. DWORD msgPos;
  328. INT index;
  329. NM_LISTVIEW *pnmlv;
  330. HWND hwndLV = pNMHdr->hwndFrom;
  331. switch (pNMHdr->code) {
  332. case NM_CLICK:
  333. //
  334. // Figure out which item (if any) was clicked on
  335. //
  336. if (! IsWindowEnabled(hwndLV))
  337. break;
  338. msgPos = GetMessagePos();
  339. hitTestInfo.pt.x = LOWORD(msgPos);
  340. hitTestInfo.pt.y = HIWORD(msgPos);
  341. MapWindowPoints(HWND_DESKTOP, hwndLV, &hitTestInfo.pt, 1 );
  342. index = ListView_HitTest(hwndLV, &hitTestInfo);
  343. if (index != -1 && (hitTestInfo.flags & LVHT_ONITEMSTATEICON)) {
  344. //
  345. // Toggle between checked and unchecked state
  346. //
  347. ToggleFaxDeviceForSend(hwndLV, index);
  348. return TRUE;
  349. }
  350. break;
  351. case LVN_KEYDOWN:
  352. //
  353. // Use space key to toggle check boxes
  354. //
  355. if (! IsWindowEnabled(hwndLV))
  356. break;
  357. if (((LV_KEYDOWN *) pNMHdr)->wVKey == VK_SPACE) {
  358. index = ListView_GetNextItem(hwndLV, -1, LVNI_ALL | LVNI_SELECTED);
  359. if (index != -1) {
  360. ToggleFaxDeviceForSend(hwndLV, index);
  361. return TRUE;
  362. }
  363. }
  364. break;
  365. case LVN_ITEMCHANGED:
  366. //
  367. // Update the TSID field when the currently selected fax device has changed
  368. //
  369. pnmlv = (NM_LISTVIEW *) pNMHdr;
  370. if ((pnmlv->uChanged & LVIF_STATE) != 0 &&
  371. (pnmlv->uOldState & LVIS_SELECTED) != (pnmlv->uNewState & LVIS_SELECTED))
  372. {
  373. Verbose(("Selection change: %d\n", pnmlv->iItem));
  374. DoChangeSendDeviceSel(hDlg, hwndLV);
  375. }
  376. break;
  377. }
  378. return FALSE;
  379. }
  380. BOOL
  381. SendOptionsProc(
  382. HWND hDlg,
  383. UINT message,
  384. UINT wParam,
  385. LONG lParam
  386. )
  387. /*++
  388. Routine Description:
  389. Procedure for handling the "Send Options" tab
  390. Arguments:
  391. hDlg - Identifies the property sheet page
  392. message - Specifies the message
  393. wParam - Specifies additional message-specific information
  394. lParam - Specifies additional message-specific information
  395. Return Value:
  396. Depends on the value of message parameter
  397. --*/
  398. {
  399. INT cmdId;
  400. BOOL result;
  401. LPNMHDR pNMHdr;
  402. switch (message) {
  403. case WM_INITDIALOG:
  404. DoInitSendOptions(hDlg);
  405. return TRUE;
  406. case WM_COMMAND:
  407. switch (cmdId = GET_WM_COMMAND_ID(wParam, lParam)) {
  408. case IDC_TC_CHEAP_BEGIN+TC_HOUR:
  409. case IDC_TC_CHEAP_BEGIN+TC_MINUTE:
  410. case IDC_TC_CHEAP_BEGIN+TC_AMPM:
  411. //
  412. // Handle user actions inside the time control
  413. //
  414. result = HandleTimeControl(hDlg, message, wParam, lParam,
  415. IDC_TC_CHEAP_BEGIN,
  416. cmdId - IDC_TC_CHEAP_BEGIN);
  417. break;
  418. case IDC_TC_CHEAP_END+TC_HOUR:
  419. case IDC_TC_CHEAP_END+TC_MINUTE:
  420. case IDC_TC_CHEAP_END+TC_AMPM:
  421. result = HandleTimeControl(hDlg, message, wParam, lParam,
  422. IDC_TC_CHEAP_END,
  423. cmdId - IDC_TC_CHEAP_END);
  424. break;
  425. case IDC_ARCHIVE_CHECKBOX:
  426. ToggleArchiveControls(hDlg);
  427. break;
  428. case IDC_ARCHIVE_DIRECTORY:
  429. if (GET_WM_COMMAND_CMD(wParam, lParam) != EN_CHANGE || insideSetDlgItemText)
  430. return TRUE;
  431. break;
  432. case IDC_TSID:
  433. switch (GET_WM_COMMAND_CMD(wParam, lParam)) {
  434. case EN_CHANGE:
  435. if (! insideSetDlgItemText) {
  436. DoChangeTSID(hDlg);
  437. break;
  438. }
  439. return TRUE;
  440. case EN_KILLFOCUS:
  441. UpdateFaxDeviceListViewColumns(GetDlgItem(hDlg, IDC_FAX_DEVICE_LIST),
  442. faxDeviceListViewColumnInfo,
  443. 1);
  444. default:
  445. return TRUE;
  446. }
  447. break;
  448. case IDC_BROWSE_DIR:
  449. if (! DoBrowseForDirectory(hDlg, IDC_ARCHIVE_DIRECTORY, IDS_ARCHIVE_DIR))
  450. return TRUE;
  451. break;
  452. default:
  453. return FALSE;
  454. }
  455. SetChangedFlag(hDlg, SEND_OPTIONS_PAGE, TRUE);
  456. return TRUE;
  457. case WM_CTLCOLORLISTBOX:
  458. case WM_CTLCOLORSTATIC:
  459. case WM_CTLCOLOREDIT:
  460. case WM_CTLCOLOR:
  461. //
  462. // Deal with color changes in various time control fields
  463. //
  464. if ((result = HandleTimeControl(hDlg, message, wParam, lParam, IDC_TC_CHEAP_BEGIN, TRUE)) ||
  465. (result = HandleTimeControl(hDlg, message, wParam, lParam, IDC_TC_CHEAP_END, TRUE)))
  466. {
  467. return result;
  468. }
  469. break;
  470. case WM_NOTIFY:
  471. pNMHdr = (NMHDR *) lParam;
  472. if (pNMHdr->hwndFrom == GetDlgItem(hDlg, IDC_FAX_DEVICE_LIST)) {
  473. if (HandleSendListViewMessage(hDlg, pNMHdr))
  474. SetChangedFlag(hDlg, SEND_OPTIONS_PAGE, TRUE);
  475. } else switch (pNMHdr->code) {
  476. case PSN_SETACTIVE:
  477. DoActivateSendOptions(hDlg);
  478. break;
  479. case PSN_APPLY:
  480. //
  481. // User pressed OK or Apply - validate inputs and save changes
  482. //
  483. if (! DoSaveSendOptions(hDlg)) {
  484. SetWindowLong(hDlg, DWL_MSGRESULT, -1);
  485. return PSNRET_INVALID_NOCHANGEPAGE;
  486. } else {
  487. SetChangedFlag(hDlg, SEND_OPTIONS_PAGE, FALSE);
  488. return PSNRET_NOERROR;
  489. }
  490. }
  491. break;
  492. case WM_HELP:
  493. case WM_CONTEXTMENU:
  494. return HandleHelpPopup(hDlg, message, wParam, lParam, SEND_OPTIONS_PAGE);
  495. }
  496. return FALSE;
  497. }