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.

1615 lines
44 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1999
  3. All rights reserved.
  4. Module Name:
  5. forms.cxx
  6. Abstract:
  7. Printer Forms
  8. Author:
  9. Steve Kiraly (SteveKi) 11/20/95
  10. Lazar Ivanov (LazarI) Jun-2000 (major changes)
  11. Revision History:
  12. --*/
  13. #include "precomp.hxx"
  14. #pragma hdrstop
  15. #include "forms.hxx"
  16. DWORD pEntryFields[] = { IDD_FM_EF_WIDTH,
  17. IDD_FM_EF_HEIGHT,
  18. IDD_FM_EF_LEFT,
  19. IDD_FM_EF_RIGHT,
  20. IDD_FM_EF_TOP,
  21. IDD_FM_EF_BOTTOM,
  22. 0 };
  23. DWORD pTextFields[] = { IDD_FM_TX_WIDTH,
  24. IDD_FM_TX_HEIGHT,
  25. IDD_FM_TX_LEFT,
  26. IDD_FM_TX_RIGHT,
  27. IDD_FM_TX_TOP,
  28. IDD_FM_TX_BOTTOM,
  29. 0 };
  30. /*++
  31. Routine Name:
  32. TPropDriverExists
  33. Routine Description:
  34. Fix the server handle. This routine tries to use a
  35. server handle to enum the forms on the specified machine.
  36. Arguments:
  37. hPrintServer,
  38. pszServerName,
  39. bAdministrator,
  40. *phPrinter
  41. Return Value:
  42. Possible return values
  43. HANDLE_FIX_NOT_NEEDED
  44. HANDLE_FIXED_NEW_HANDLE_RETURNED
  45. HANDLE_NEEDS_FIXING_NO_PRINTERS_FOUND
  46. --*/
  47. UINT
  48. sFormsFixServerHandle(
  49. IN HANDLE hPrintServer,
  50. IN LPCTSTR pszServerName,
  51. IN BOOL bAdministrator,
  52. IN HANDLE *phPrinter
  53. )
  54. {
  55. // Check if server handle can be used.
  56. PFORM_INFO_1 pFormInfo;
  57. DWORD dwNumberOfForms;
  58. BOOL bStatus;
  59. bStatus = bEnumForms(
  60. hPrintServer,
  61. 1,
  62. (PBYTE *)&pFormInfo,
  63. &dwNumberOfForms );
  64. // Server handle succeeded.
  65. if( bStatus && dwNumberOfForms )
  66. {
  67. FreeMem(pFormInfo);
  68. return HANDLE_FIX_NOT_NEEDED;
  69. }
  70. // Enumerate the printers on the specified server looking for a printer.
  71. PRINTER_INFO_2 *pPrinterInfo2 = NULL;
  72. DWORD cPrinterInfo2 = 0;
  73. DWORD cbPrinterInfo2 = 0;
  74. DWORD dwFlags = PRINTER_ENUM_NAME;
  75. bStatus = VDataRefresh::bEnumPrinters(
  76. dwFlags,
  77. (LPTSTR)pszServerName,
  78. 2,
  79. (PVOID *)&pPrinterInfo2,
  80. &cbPrinterInfo2,
  81. &cPrinterInfo2);
  82. // If success and at least one printer was enumerated.
  83. if( bStatus && cPrinterInfo2 )
  84. {
  85. TStatus Status;
  86. Status DBGNOCHK = ERROR_INVALID_FUNCTION;
  87. DWORD dwAccess = 0;
  88. for( UINT i = 0; i < cPrinterInfo2; i++ )
  89. {
  90. // Attempt to open the printer using the specified access.
  91. dwAccess = 0;
  92. Status DBGCHK = TPrinter::sOpenPrinter(pPrinterInfo2[i].pPrinterName,
  93. &dwAccess,
  94. phPrinter);
  95. // Done if a valid printer handle was returned.
  96. if( Status == ERROR_SUCCESS )
  97. {
  98. break;
  99. }
  100. else
  101. {
  102. DBGMSG(DBG_WARN, ( "Error opening printer \"" TSTR "\".\n", pPrinterInfo2[i].pPrinterName));
  103. }
  104. }
  105. // Release the printer enumeration buffer.
  106. FreeMem(pPrinterInfo2);
  107. //
  108. // Return the new handle value. Note: Access privilage
  109. // may have changed.
  110. //
  111. DWORD dwAccessType;
  112. if( Status == ERROR_SUCCESS )
  113. {
  114. dwAccessType = bAdministrator ? PRINTER_ALL_ACCESS : PRINTER_READ;
  115. return (dwAccess == dwAccessType ?
  116. HANDLE_FIXED_NEW_HANDLE_RETURNED :
  117. HANDLE_FIXED_NEW_HANDLE_RETURNED_ACCESS_CHANGED);
  118. }
  119. }
  120. // Error no printers were found using the specifed server handle.
  121. return HANDLE_NEEDS_FIXING_NO_PRINTERS_FOUND;
  122. }
  123. PVOID
  124. FormsInit(
  125. IN LPCTSTR pszServerName,
  126. IN HANDLE hPrintServer,
  127. IN BOOL bAdministrator,
  128. IN LPCTSTR pszComputerName
  129. )
  130. {
  131. FORMS_DLG_DATA *pFormsDlgData = (FORMS_DLG_DATA *)AllocMem(sizeof(*pFormsDlgData));
  132. if( pFormsDlgData )
  133. {
  134. // initialize the forms dialog data here.
  135. ZeroMemory(pFormsDlgData, sizeof(*pFormsDlgData));
  136. // set the forms dialog data.
  137. pFormsDlgData->pServerName = (LPTSTR)pszServerName;
  138. pFormsDlgData->AccessGranted = bAdministrator;
  139. pFormsDlgData->hPrinter = hPrintServer;
  140. pFormsDlgData->bNeedClose = FALSE;
  141. pFormsDlgData->pszComputerName= pszComputerName;
  142. // get the current metric setting.
  143. pFormsDlgData->uMetricMeasurement = !((BOOL)GetProfileInt(TEXT( "intl" ), TEXT("iMeasure"), 0));
  144. // get decimal point setting.
  145. GetProfileString(TEXT( "intl" ), TEXT( "sDecimal" ), TEXT( "." ),
  146. pFormsDlgData->szDecimalPoint, ARRAYSIZE(pFormsDlgData->szDecimalPoint));
  147. // if this machine does not suport using a server handle to
  148. // administer forms, we need to attempt to acquire a printer handle
  149. // for the specified access and then remember to close the handle when this
  150. // dialog terminates.
  151. HANDLE hPrinter;
  152. UINT Status = sFormsFixServerHandle(pFormsDlgData->hPrinter, pszServerName, bAdministrator, &hPrinter);
  153. // there are three cases which can occurr.
  154. switch( Status )
  155. {
  156. case HANDLE_FIXED_NEW_HANDLE_RETURNED:
  157. pFormsDlgData->hPrinter = hPrinter;
  158. pFormsDlgData->bNeedClose = TRUE;
  159. break;
  160. case HANDLE_NEEDS_FIXING_NO_PRINTERS_FOUND:
  161. pFormsDlgData->hPrinter = NULL;
  162. pFormsDlgData->AccessGranted = FALSE;
  163. break;
  164. case HANDLE_FIXED_NEW_HANDLE_RETURNED_ACCESS_CHANGED:
  165. pFormsDlgData->hPrinter = hPrinter;
  166. pFormsDlgData->bNeedClose = TRUE;
  167. pFormsDlgData->AccessGranted = !pFormsDlgData->AccessGranted;
  168. break;
  169. case HANDLE_FIX_NOT_NEEDED:
  170. break;
  171. default:
  172. DBGMSG( DBG_TRACE, ( "Un handled case value HANDLE_FIX.\n" ) );
  173. break;
  174. }
  175. }
  176. return pFormsDlgData;
  177. }
  178. VOID
  179. FormsFini(
  180. PVOID p
  181. )
  182. {
  183. // Get pointer to forms data.
  184. FORMS_DLG_DATA *pFormsDlgData = (FORMS_DLG_DATA *)p;
  185. // Validate forms data pointer
  186. if( pFormsDlgData )
  187. {
  188. // If printer opened ok, then we must close it.
  189. if( pFormsDlgData->bNeedClose && pFormsDlgData->hPrinter )
  190. {
  191. ClosePrinter( pFormsDlgData->hPrinter );
  192. }
  193. // Release the forms enumeration.
  194. FreeMem(pFormsDlgData->pFormInfo);
  195. // Release the forms data
  196. FreeMem(pFormsDlgData);
  197. }
  198. }
  199. BOOL APIENTRY
  200. FormsDlg(
  201. HWND hwnd,
  202. UINT msg,
  203. WPARAM wparam,
  204. LPARAM lparam
  205. )
  206. {
  207. // clear the last error each time message is about to be
  208. // handled
  209. PFORMS_DLG_DATA pFormsDlgData =
  210. (WM_INITDIALOG == msg ? (PFORMS_DLG_DATA)lparam :
  211. (PFORMS_DLG_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA));
  212. if( pFormsDlgData )
  213. {
  214. pFormsDlgData->dwLastError = ERROR_SUCCESS;
  215. }
  216. // switch madness
  217. switch(msg)
  218. {
  219. case WM_INITDIALOG:
  220. return FormsInitDialog(hwnd, pFormsDlgData);
  221. case WM_COMMAND:
  222. switch( LOWORD( wparam ) )
  223. {
  224. case IDD_FM_PB_SAVEFORM:
  225. return FormsCommandAddForm(hwnd);
  226. case IDD_FM_PB_DELFORM:
  227. return FormsCommandDelForm(hwnd);
  228. case IDD_FM_LB_FORMS:
  229. switch (HIWORD(wparam))
  230. {
  231. case LBN_SELCHANGE:
  232. return FormsCommandFormsSelChange(hwnd);
  233. }
  234. break;
  235. case IDD_FM_EF_NAME:
  236. return FormsCommandNameChange(hwnd, wparam, lparam );
  237. case IDD_FM_RB_METRIC:
  238. case IDD_FM_RB_ENGLISH:
  239. return FormsCommandUnits(hwnd);
  240. case IDD_FM_CK_NEW_FORM:
  241. return FormsNewForms(hwnd);
  242. }
  243. }
  244. return FALSE;
  245. }
  246. LPTSTR
  247. AllocStr(
  248. LPCTSTR pszStr
  249. )
  250. {
  251. if( pszStr && *pszStr )
  252. {
  253. size_t cbLen = (lstrlen(pszStr) + 1) * sizeof(*pszStr);
  254. LPTSTR pszRet = (LPTSTR)AllocMem(cbLen);
  255. if( pszRet )
  256. {
  257. StringCbCopy(pszRet, cbLen, pszStr);
  258. return pszRet;
  259. }
  260. }
  261. return NULL;
  262. }
  263. VOID
  264. FreeStr(
  265. LPTSTR pszStr
  266. )
  267. {
  268. if( pszStr )
  269. {
  270. FreeMem((PVOID)pszStr);
  271. }
  272. }
  273. /* Grey Text
  274. *
  275. * If the window has an ID of -1, grey it.
  276. */
  277. BOOL CALLBACK GreyText( HWND hwnd, LPARAM lParam )
  278. {
  279. UNREFERENCED_PARAMETER( lParam );
  280. if( GetDlgCtrlID(hwnd) == (int)(USHORT)-1 )
  281. {
  282. EnableWindow(hwnd, FALSE);
  283. }
  284. return TRUE;
  285. }
  286. /* Macro: FORMSDIFFER
  287. *
  288. * Used to determine whether two forms have any differences between them.
  289. * The Names of the respective forms are not checked.
  290. */
  291. #define FORMSDIFFER( pFormInfoA, pFormInfoB ) \
  292. ( memcmp( &(pFormInfoA)->Size, &(pFormInfoB)->Size, sizeof (pFormInfoA)->Size ) \
  293. ||memcmp( &(pFormInfoA)->ImageableArea, &(pFormInfoB)->ImageableArea, \
  294. sizeof (pFormInfoA)->ImageableArea ) )
  295. /*
  296. * Initalize the forms dialog fields.
  297. */
  298. BOOL FormsInitDialog(HWND hwnd, PFORMS_DLG_DATA pFormsDlgData)
  299. {
  300. DWORD i;
  301. // Get forms dialog data.
  302. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pFormsDlgData);
  303. // Set the foms name limit text.
  304. SendDlgItemMessage(hwnd, IDD_FM_EF_NAME, EM_LIMITTEXT, FORMS_NAME_MAX, 0L);
  305. for( i = 0; pEntryFields[i]; i++ )
  306. {
  307. SendDlgItemMessage(hwnd, pEntryFields[i], EM_LIMITTEXT, FORMS_PARAM_MAX-1, 0L);
  308. }
  309. HWND hWndName;
  310. hWndName = GetDlgItem( hwnd, IDD_FM_EF_NAME );
  311. ::SetWindowLong(hWndName, GWL_STYLE, ::GetWindowLong(hWndName, GWL_STYLE) | WS_CLIPSIBLINGS);
  312. hWndName = GetDlgItem( hwnd, IDD_FM_DESC_GBOX );
  313. ::SetWindowLong(hWndName, GWL_STYLE, ::GetWindowLong(hWndName, GWL_STYLE) | WS_CLIPSIBLINGS);
  314. // Set the forms title name.
  315. SetFormsComputerName(hwnd, pFormsDlgData);
  316. // Read the forms data
  317. InitializeFormsData(hwnd, pFormsDlgData, FALSE);
  318. // Set up the units default based on the current international setting:
  319. pFormsDlgData->Units = pFormsDlgData->uMetricMeasurement;
  320. SETUNITS(hwnd, pFormsDlgData->Units);
  321. if( pFormsDlgData->cForms > 0 )
  322. {
  323. SetFormDescription(hwnd, &pFormsDlgData->pFormInfo[0], pFormsDlgData->Units);
  324. SendDlgItemMessage(hwnd, IDD_FM_LB_FORMS, LB_SETCURSEL, 0, 0L);
  325. }
  326. EnableWindow(GetDlgItem( hwnd, IDD_FM_EF_NAME ), FALSE);
  327. EnableWindow(GetDlgItem( hwnd, IDC_FORMNAME_LABEL ), FALSE);
  328. EnableWindow(GetDlgItem( hwnd, IDD_FM_TX_NEW_FORM ), FALSE);
  329. EnableWindow(GetDlgItem( hwnd, IDD_FM_PB_SAVEFORM ), FALSE);
  330. EnableWindow(GetDlgItem( hwnd, IDD_FM_TX_FORMS_DESC ), TRUE);
  331. if( FALSE == pFormsDlgData->AccessGranted )
  332. {
  333. EnableWindow(GetDlgItem(hwnd, IDD_FM_CK_NEW_FORM), FALSE);
  334. EnableWindow(GetDlgItem(hwnd, IDD_FM_TX_WIDTH), FALSE);
  335. EnableWindow(GetDlgItem(hwnd, IDD_FM_TX_HEIGHT), FALSE);
  336. EnableWindow(GetDlgItem(hwnd, IDD_FM_TX_LEFT), FALSE);
  337. EnableWindow(GetDlgItem(hwnd, IDD_FM_TX_RIGHT), FALSE);
  338. EnableWindow(GetDlgItem(hwnd, IDD_FM_TX_TOP), FALSE);
  339. EnableWindow(GetDlgItem(hwnd, IDD_FM_TX_BOTTOM), FALSE);
  340. // Handle is invalid disable all controls and set error text.
  341. if( !pFormsDlgData->hPrinter )
  342. {
  343. EnableWindow(GetDlgItem(hwnd, IDD_FM_RB_METRIC), FALSE);
  344. EnableWindow(GetDlgItem(hwnd, IDD_FM_RB_ENGLISH), FALSE);
  345. EnableWindow(GetDlgItem(hwnd, IDD_FM_RB_ENGLISH), FALSE);
  346. SetDlgItemTextFromResID(hwnd, IDC_SERVER_NAME, IDS_SERVER_NO_PRINTER_DEFINED);
  347. }
  348. }
  349. // Enable/Disable the dialog controls here
  350. EnableDialogFields(hwnd, pFormsDlgData);
  351. return FALSE;
  352. }
  353. /*
  354. *
  355. */
  356. BOOL FormsCommandAddForm(HWND hwnd)
  357. {
  358. PFORMS_DLG_DATA pFormsDlgData;
  359. INT PrevSel;
  360. FORM_INFO_1 NewFormInfo;
  361. INT i = -1;
  362. //
  363. // If the save form button is disable nothing to do. This
  364. // Check is needed for handling the apply button or ok
  365. // event in a property sheet.
  366. //
  367. if( !IsWindowEnabled(GetDlgItem(hwnd, IDD_FM_PB_SAVEFORM)) )
  368. {
  369. return TRUE;
  370. }
  371. ZeroMemory(&NewFormInfo, sizeof(NewFormInfo));
  372. pFormsDlgData = (PFORMS_DLG_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  373. NewFormInfo.pName = GetFormName(hwnd);
  374. if( !NewFormInfo.pName )
  375. {
  376. //
  377. // Out of memory.
  378. //
  379. iMessage( hwnd,
  380. IDS_ERR_FORMS_TITLE,
  381. IDS_ERR_GENERIC,
  382. MB_OK|MB_ICONSTOP,
  383. ERROR_OUTOFMEMORY,
  384. NULL );
  385. // save the last error, so the property sheet won't close
  386. pFormsDlgData->dwLastError = ERROR_OUTOFMEMORY;
  387. goto Cleanup;
  388. }
  389. //
  390. // Check if we are to save and existing form.
  391. //
  392. if( !Button_GetCheck(GetDlgItem(hwnd, IDD_FM_CK_NEW_FORM)) )
  393. {
  394. //
  395. // Check if the form is currently in the list.
  396. //
  397. i = GetFormIndex(NewFormInfo.pName, pFormsDlgData->pFormInfo, pFormsDlgData->cForms);
  398. if( i >= 0 )
  399. {
  400. //
  401. // Preserve the old data.
  402. //
  403. NewFormInfo.Flags = pFormsDlgData->pFormInfo[i].Flags;
  404. NewFormInfo.Size = pFormsDlgData->pFormInfo[i].Size;
  405. NewFormInfo.ImageableArea = pFormsDlgData->pFormInfo[i].ImageableArea;
  406. }
  407. }
  408. //
  409. // Get the form data from the controls & validate it.
  410. //
  411. UINT uIDFailed;
  412. if( !GetFormDescription(hwnd, &NewFormInfo, pFormsDlgData->Units, &uIDFailed) )
  413. {
  414. SetFocus(GetDlgItem(hwnd, uIDFailed));
  415. SendMessage(GetDlgItem(hwnd, uIDFailed), EM_SETSEL, 0, -1);
  416. //
  417. // Form validation failed. Set the focus info the correct control.
  418. //
  419. iMessage( hwnd,
  420. IDS_ERR_FORMS_TITLE,
  421. IDS_FORMS_INVALIDNUMBER,
  422. MB_OK|MB_ICONSTOP,
  423. kMsgNone,
  424. NULL );
  425. // save the last error, so the property sheet won't close
  426. pFormsDlgData->dwLastError = ERROR_INVALID_PARAMETER;
  427. goto Cleanup;
  428. }
  429. //
  430. // Check if we are to save and existing form.
  431. //
  432. if( i >= 0 && FORMSDIFFER(&pFormsDlgData->pFormInfo[i], &NewFormInfo) )
  433. {
  434. //
  435. // Call spooler to set the form data.
  436. //
  437. if( !SetForm(pFormsDlgData->hPrinter, NewFormInfo.pName, 1, (LPBYTE)&NewFormInfo) )
  438. {
  439. //
  440. // Display error message.
  441. //
  442. iMessage( hwnd,
  443. IDS_ERR_FORMS_TITLE,
  444. IDS_ERR_FORMS_COULDNOTSETFORM,
  445. MB_OK|MB_ICONSTOP,
  446. kMsgGetLastError,
  447. NULL,
  448. NewFormInfo.pName );
  449. // save the last error, so the property sheet won't close
  450. pFormsDlgData->dwLastError = GetLastError();
  451. }
  452. else
  453. {
  454. //
  455. // Insure we maintain the previous selection state.
  456. //
  457. i = ListBox_GetCurSel(GetDlgItem( hwnd, IDD_FM_LB_FORMS));
  458. InitializeFormsData(hwnd, pFormsDlgData, TRUE);
  459. ListBox_SetCurSel(GetDlgItem(hwnd, IDD_FM_LB_FORMS), i);
  460. //
  461. // Update controls.
  462. //
  463. SetFormDescription(hwnd, &NewFormInfo, pFormsDlgData->Units);
  464. FormChanged(pFormsDlgData); // notify whoever cares
  465. }
  466. goto Cleanup;
  467. }
  468. if( i < 0 && Button_GetCheck(GetDlgItem(hwnd, IDD_FM_CK_NEW_FORM)) )
  469. {
  470. //
  471. // Add form case.
  472. //
  473. if( (PrevSel = ListBox_GetCurSel(GetDlgItem(hwnd, IDD_FM_LB_FORMS))) < 0 )
  474. {
  475. PrevSel = 0;
  476. }
  477. //
  478. // Check if the new form name is not currently used.
  479. //
  480. LRESULT Status;
  481. Status = SendDlgItemMessage(hwnd,
  482. IDD_FM_LB_FORMS,
  483. LB_FINDSTRINGEXACT,
  484. (WPARAM)-1,
  485. (LPARAM)NewFormInfo.pName );
  486. //
  487. // If string was found.
  488. //
  489. if( Status != LB_ERR )
  490. {
  491. iMessage( hwnd,
  492. IDS_ERR_FORMS_TITLE,
  493. IDS_ERR_FORMS_NAMECONFLICT,
  494. MB_OK|MB_ICONEXCLAMATION,
  495. kMsgNone,
  496. NULL );
  497. // save the last error, so the property sheet won't close
  498. pFormsDlgData->dwLastError = ERROR_INVALID_PARAMETER;
  499. goto Cleanup;
  500. }
  501. if( AddForm(pFormsDlgData->hPrinter, 1, (LPBYTE)&NewFormInfo) )
  502. {
  503. InitializeFormsData(hwnd, pFormsDlgData, TRUE);
  504. // highlight the one we just added:
  505. i = GetFormIndex(NewFormInfo.pName, pFormsDlgData->pFormInfo, pFormsDlgData->cForms);
  506. // if we can't find it, restore the previous selection.
  507. // (This assumes that the last EnumForms returned the same buffer
  508. // as we had last time.)
  509. if( i < 0 )
  510. {
  511. i = (pFormsDlgData->cForms > (DWORD)PrevSel) ? PrevSel : 0;
  512. }
  513. if( pFormsDlgData->cForms > 0 )
  514. {
  515. SetFormDescription(hwnd, &pFormsDlgData->pFormInfo[i], pFormsDlgData->Units);
  516. SendDlgItemMessage(hwnd, IDD_FM_LB_FORMS, LB_SETCURSEL, i, 0L);
  517. }
  518. // the Add button is about to be greyed, it currently
  519. // has focus therefore we will shift the focus to the
  520. // edit box.
  521. SetFocus(GetDlgItem(hwnd, IDD_FM_EF_NAME));
  522. FormChanged(pFormsDlgData); // notify whoever cares
  523. }
  524. else
  525. {
  526. iMessage( hwnd,
  527. IDS_ERR_FORMS_TITLE,
  528. IDS_ERR_FORMS_COULDNOTADDFORM,
  529. MB_OK|MB_ICONSTOP,
  530. kMsgGetLastError,
  531. NULL,
  532. NewFormInfo.pName );
  533. // save the last error, so the property sheet won't close
  534. pFormsDlgData->dwLastError = GetLastError();
  535. }
  536. }
  537. Cleanup:
  538. if( NewFormInfo.pName )
  539. {
  540. FreeStr(NewFormInfo.pName);
  541. }
  542. EnableDialogFields(hwnd, pFormsDlgData);
  543. return TRUE;
  544. }
  545. /*
  546. *
  547. */
  548. BOOL FormsCommandDelForm(HWND hwnd)
  549. {
  550. PFORMS_DLG_DATA pFormsDlgData;
  551. DWORD i;
  552. DWORD TopIndex;
  553. DWORD Count;
  554. LPTSTR pFormName;
  555. pFormsDlgData = (PFORMS_DLG_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  556. ASSERT(pFormsDlgData);
  557. i = ListBox_GetCurSel(GetDlgItem(hwnd, IDD_FM_LB_FORMS));
  558. TopIndex = (DWORD)SendDlgItemMessage(hwnd, IDD_FM_LB_FORMS, LB_GETTOPINDEX, 0, 0L);
  559. pFormName = GetFormName(hwnd);
  560. if( DeleteForm(pFormsDlgData->hPrinter, pFormName) )
  561. {
  562. InitializeFormsData(hwnd, pFormsDlgData, TRUE);
  563. Count = (DWORD)SendDlgItemMessage(hwnd, IDD_FM_LB_FORMS, LB_GETCOUNT, 0, 0L);
  564. if( i >= Count )
  565. {
  566. i = ( Count-1 );
  567. }
  568. if( pFormsDlgData->cForms > 0 )
  569. {
  570. SetFormDescription(hwnd, &pFormsDlgData->pFormInfo[i], pFormsDlgData->Units);
  571. SendDlgItemMessage(hwnd, IDD_FM_LB_FORMS, LB_SETCURSEL, i, 0L);
  572. SendDlgItemMessage(hwnd, IDD_FM_LB_FORMS, LB_SETTOPINDEX, TopIndex, 0L);
  573. PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM )GetDlgItem(hwnd, IDD_FM_LB_FORMS), (LPARAM )TRUE);
  574. }
  575. FormChanged(pFormsDlgData); // notify whoever cares
  576. }
  577. else
  578. {
  579. iMessage( hwnd,
  580. IDS_ERR_FORMS_TITLE,
  581. IDS_ERR_FORMS_COULDNOTDELETEFORM,
  582. MB_OK|MB_ICONSTOP,
  583. kMsgGetLastError,
  584. NULL,
  585. pFormName );
  586. }
  587. if( pFormName )
  588. {
  589. FreeStr(pFormName);
  590. }
  591. EnableDialogFields( hwnd, pFormsDlgData );
  592. return TRUE;
  593. }
  594. /*
  595. *
  596. */
  597. BOOL FormsCommandFormsSelChange(HWND hwnd)
  598. {
  599. PFORMS_DLG_DATA pFormsDlgData;
  600. DWORD i;
  601. pFormsDlgData = (PFORMS_DLG_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  602. i = ListBox_GetCurSel(GetDlgItem(hwnd, IDD_FM_LB_FORMS));
  603. SetFormDescription(hwnd, &pFormsDlgData->pFormInfo[i], pFormsDlgData->Units);
  604. EnableDialogFields(hwnd, pFormsDlgData);
  605. return TRUE;
  606. }
  607. /*
  608. * User change the units of the currently selected form.
  609. */
  610. BOOL FormsCommandUnits(HWND hwnd)
  611. {
  612. PFORMS_DLG_DATA pFormsDlgData;
  613. INT i;
  614. FORM_INFO_1 FormInfo;
  615. //
  616. // Get dialog data.
  617. //
  618. pFormsDlgData = (PFORMS_DLG_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  619. ZeroMemory(&FormInfo, sizeof(FormInfo));
  620. if( pFormsDlgData->Units == GETUNITS(hwnd) )
  621. goto Cleanup;
  622. FormInfo.pName = GetFormName(hwnd);
  623. if( !FormInfo.pName )
  624. {
  625. //
  626. // Out of memory.
  627. //
  628. iMessage( hwnd,
  629. IDS_ERR_FORMS_TITLE,
  630. IDS_ERR_GENERIC,
  631. MB_OK|MB_ICONSTOP,
  632. ERROR_OUTOFMEMORY,
  633. NULL );
  634. goto Cleanup;
  635. }
  636. //
  637. // Check if the form is currently in the list.
  638. //
  639. i = GetFormIndex(FormInfo.pName, pFormsDlgData->pFormInfo, pFormsDlgData->cForms);
  640. if( i >= 0 )
  641. {
  642. //
  643. // Preserve the old data.
  644. //
  645. FormInfo.Flags = pFormsDlgData->pFormInfo[i].Flags;
  646. FormInfo.Size = pFormsDlgData->pFormInfo[i].Size;
  647. FormInfo.ImageableArea = pFormsDlgData->pFormInfo[i].ImageableArea;
  648. }
  649. //
  650. // Get the forms description.
  651. //
  652. UINT uIDFailed;
  653. if( GetFormDescription(hwnd, &FormInfo, pFormsDlgData->Units, &uIDFailed) )
  654. {
  655. //
  656. // Get and save the currently selected units.
  657. //
  658. pFormsDlgData->Units = GETUNITS(hwnd);
  659. //
  660. // Set the forms values.
  661. //
  662. SetValue(hwnd, IDD_FM_EF_WIDTH, FormInfo.Size.cx, pFormsDlgData->Units);
  663. SetValue(hwnd, IDD_FM_EF_HEIGHT, FormInfo.Size.cy, pFormsDlgData->Units);
  664. SetValue(hwnd, IDD_FM_EF_LEFT, FormInfo.ImageableArea.left, pFormsDlgData->Units);
  665. SetValue(hwnd, IDD_FM_EF_RIGHT, FormInfo.Size.cx - FormInfo.ImageableArea.right, pFormsDlgData->Units);
  666. SetValue(hwnd, IDD_FM_EF_TOP, FormInfo.ImageableArea.top, pFormsDlgData->Units);
  667. SetValue(hwnd, IDD_FM_EF_BOTTOM, FormInfo.Size.cy - FormInfo.ImageableArea.bottom, pFormsDlgData->Units);
  668. }
  669. else
  670. {
  671. SETUNITS(hwnd, pFormsDlgData->Units);
  672. SetFocus(GetDlgItem(hwnd, uIDFailed));
  673. SendMessage(GetDlgItem(hwnd, uIDFailed), EM_SETSEL, 0, -1);
  674. //
  675. // Form validation failed. Set the focus info the correct control.
  676. //
  677. iMessage( hwnd,
  678. IDS_ERR_FORMS_TITLE,
  679. IDS_FORMS_INVALIDNUMBER,
  680. MB_OK|MB_ICONSTOP,
  681. kMsgNone,
  682. NULL );
  683. }
  684. Cleanup:
  685. if( FormInfo.pName )
  686. {
  687. FreeStr(FormInfo.pName);
  688. }
  689. return TRUE;
  690. }
  691. /*
  692. *
  693. */
  694. VOID InitializeFormsData(HWND hwnd, PFORMS_DLG_DATA pFormsDlgData, BOOL ResetList)
  695. {
  696. LPFORM_INFO_1 pFormInfo;
  697. DWORD cForms;
  698. DWORD i;
  699. if( ResetList )
  700. {
  701. if( pFormsDlgData->pFormInfo )
  702. {
  703. FreeMem(pFormsDlgData->pFormInfo);
  704. }
  705. }
  706. pFormInfo = GetFormsList(pFormsDlgData->hPrinter, &cForms);
  707. if( !pFormInfo )
  708. {
  709. DBGMSG( DBG_WARNING, ( "GetFormsList failed.\n") );
  710. pFormsDlgData->pFormInfo = NULL;
  711. pFormsDlgData->cForms = 0;
  712. return;
  713. }
  714. pFormsDlgData->pFormInfo = pFormInfo;
  715. pFormsDlgData->cForms = cForms;
  716. if( ResetList )
  717. {
  718. ListBox_ResetContent(GetDlgItem( hwnd, IDD_FM_LB_FORMS));
  719. }
  720. for( i = 0; i < cForms; i++ )
  721. {
  722. SendDlgItemMessage(
  723. hwnd,
  724. IDD_FM_LB_FORMS,
  725. LB_INSERTSTRING,
  726. (WPARAM)-1,
  727. (LPARAM)(LPTSTR)pFormInfo[i].pName
  728. );
  729. }
  730. }
  731. /* GetFormsList
  732. *
  733. * This function works in exactly the same way as GetPortsList.
  734. * There's a good case for writing a generic EnumerateObject function
  735. * (Done!)
  736. */
  737. LPFORM_INFO_1 GetFormsList(HANDLE hPrinter, PDWORD pNumberOfForms)
  738. {
  739. PFORM_INFO_1 pFormInfo = NULL;
  740. TStatusB bStatus;
  741. bStatus DBGCHK = bEnumForms(hPrinter, 1, (PBYTE *)&pFormInfo, pNumberOfForms);
  742. if( bStatus && pFormInfo )
  743. {
  744. //
  745. // Sort the forms list.
  746. //
  747. qsort((PVOID )pFormInfo, (UINT)*pNumberOfForms, sizeof(*pFormInfo), CompareFormNames);
  748. }
  749. return pFormInfo;
  750. }
  751. /*
  752. * CompareFormNames
  753. */
  754. int _cdecl CompareFormNames( const void *p1, const void *p2 )
  755. {
  756. return lstrcmpi( ( (PFORM_INFO_1)p1 )->pName,
  757. ( (PFORM_INFO_1)p2 )->pName );
  758. }
  759. /*
  760. * SetFormsComputerName
  761. */
  762. VOID SetFormsComputerName( HWND hwnd, PFORMS_DLG_DATA pFormsDlgData )
  763. {
  764. //
  765. // Set the title to the name of this machine.
  766. //
  767. SetDlgItemText( hwnd, IDC_SERVER_NAME, pFormsDlgData->pszComputerName );
  768. }
  769. /*
  770. * SetFormDescription
  771. */
  772. VOID SetFormDescription( HWND hwnd, LPFORM_INFO_1 pFormInfo, BOOL Units )
  773. {
  774. SetDlgItemText( hwnd, IDD_FM_EF_NAME, pFormInfo->pName );
  775. SetValue( hwnd, IDD_FM_EF_WIDTH, pFormInfo->Size.cx, Units );
  776. SetValue( hwnd, IDD_FM_EF_HEIGHT, pFormInfo->Size.cy, Units );
  777. SetValue( hwnd, IDD_FM_EF_LEFT, pFormInfo->ImageableArea.left, Units );
  778. SetValue( hwnd, IDD_FM_EF_RIGHT, ( pFormInfo->Size.cx -
  779. pFormInfo->ImageableArea.right ), Units );
  780. SetValue( hwnd, IDD_FM_EF_TOP, pFormInfo->ImageableArea.top, Units );
  781. SetValue( hwnd, IDD_FM_EF_BOTTOM, ( pFormInfo->Size.cy -
  782. pFormInfo->ImageableArea.bottom ), Units );
  783. }
  784. /*
  785. * GetFormDescription
  786. */
  787. BOOL
  788. GetFormDescription(
  789. IN HWND hwnd,
  790. OUT LPFORM_INFO_1 pFormInfo,
  791. IN BOOL bDefaultMetric,
  792. OUT PUINT puIDFailed
  793. )
  794. {
  795. BOOL bReturn = FALSE;
  796. FORM_INFO_1 info;
  797. LONG lRight = pFormInfo->Size.cx - pFormInfo->ImageableArea.right;
  798. LONG lBottom = pFormInfo->Size.cy - pFormInfo->ImageableArea.bottom;
  799. *puIDFailed =
  800. !GetValue(hwnd, IDD_FM_EF_WIDTH, pFormInfo->Size.cx,
  801. bDefaultMetric, &info.Size.cx) ? IDD_FM_EF_WIDTH :
  802. !GetValue(hwnd, IDD_FM_EF_HEIGHT, pFormInfo->Size.cy,
  803. bDefaultMetric, &info.Size.cy) ? IDD_FM_EF_HEIGHT :
  804. !GetValue(hwnd, IDD_FM_EF_LEFT, pFormInfo->ImageableArea.left,
  805. bDefaultMetric, &info.ImageableArea.left) ? IDD_FM_EF_LEFT :
  806. !GetValue(hwnd, IDD_FM_EF_TOP, pFormInfo->ImageableArea.top,
  807. bDefaultMetric, &info.ImageableArea.top) ? IDD_FM_EF_TOP :
  808. !GetValue(hwnd, IDD_FM_EF_RIGHT, lRight,
  809. bDefaultMetric, &lRight) ? IDD_FM_EF_RIGHT :
  810. !GetValue(hwnd, IDD_FM_EF_BOTTOM, lBottom,
  811. bDefaultMetric, &lBottom) ? IDD_FM_EF_BOTTOM :
  812. 0;
  813. // validate top, left, rigt & bottom of the ImageableArea.
  814. if( 0 == *puIDFailed && info.ImageableArea.left >= info.Size.cx )
  815. {
  816. *puIDFailed = IDD_FM_EF_LEFT;
  817. }
  818. if( 0 == *puIDFailed && info.ImageableArea.top >= info.Size.cy )
  819. {
  820. *puIDFailed = IDD_FM_EF_TOP;
  821. }
  822. info.ImageableArea.right = info.Size.cx - lRight;
  823. if( 0 == *puIDFailed && info.ImageableArea.right <= info.ImageableArea.left )
  824. {
  825. *puIDFailed = IDD_FM_EF_RIGHT;
  826. }
  827. info.ImageableArea.bottom = info.Size.cy - lBottom;
  828. if( 0 == *puIDFailed && info.ImageableArea.bottom <= info.ImageableArea.top )
  829. {
  830. *puIDFailed = IDD_FM_EF_BOTTOM;
  831. }
  832. if( 0 == *puIDFailed )
  833. {
  834. pFormInfo->Size = info.Size;
  835. pFormInfo->ImageableArea = info.ImageableArea;
  836. bReturn = TRUE;
  837. }
  838. return bReturn;
  839. }
  840. /* GetFormIndex
  841. *
  842. * Searches an array of FORM_INFO structures for one with name pFormName.
  843. *
  844. * Return:
  845. *
  846. * The index of the form found, or -1 if the form is not found.
  847. */
  848. int GetFormIndex( LPTSTR pFormName, LPFORM_INFO_1 pFormInfo, DWORD cForms )
  849. {
  850. int i = 0;
  851. BOOL Found = FALSE;
  852. while( i < (int)cForms && !( Found = !lstrcmpi( pFormInfo[i].pName, pFormName ) ) )
  853. i++;
  854. if( Found )
  855. return i;
  856. else
  857. return -1;
  858. }
  859. /* GetFormName
  860. *
  861. * Returns a pointer to a newly allocated string containing the form name,
  862. * stripped of leading and trailing blanks.
  863. * Caller must remember to free up the string.
  864. *
  865. */
  866. LPTSTR GetFormName( HWND hwnd )
  867. {
  868. TCHAR FormName[FORMS_NAME_MAX+1];
  869. INT i = 0;
  870. PTCHAR pFormNameWithBlanksStripped;
  871. PTCHAR pReturnFormName = NULL;
  872. if( GetDlgItemText( hwnd, IDD_FM_EF_NAME, FormName, COUNTOF( FormName ) ) > 0 )
  873. {
  874. /* Step over any blank characters at the beginning:
  875. */
  876. while( FormName[i] && ( FormName[i] == TEXT(' ') ) )
  877. i++;
  878. if( FormName[i] )
  879. {
  880. pFormNameWithBlanksStripped = &FormName[i];
  881. /* Find the NULL terminator:
  882. */
  883. while( FormName[i] )
  884. i++;
  885. /* Now step back to find the last character that isn't a blank:
  886. */
  887. if( i > 0 )
  888. i--;
  889. while( ( i > 0 ) && ( FormName[i] == TEXT( ' ' ) ) )
  890. i--;
  891. FormName[i+1] = TEXT( '\0' );
  892. if( *pFormNameWithBlanksStripped )
  893. pReturnFormName = AllocStr( pFormNameWithBlanksStripped );
  894. }
  895. /* Otherwise, the name contains nothing but blanks. */
  896. }
  897. return pReturnFormName;
  898. }
  899. /*
  900. * SetValue
  901. */
  902. BOOL
  903. SetValue(
  904. HWND hwnd,
  905. DWORD uID,
  906. LONG lValueInPoint001mm,
  907. BOOL bMetric
  908. )
  909. {
  910. PFORMS_DLG_DATA pFormsDlgData = (PFORMS_DLG_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  911. ASSERT(pFormsDlgData);
  912. TCHAR szValue[FORMS_PARAM_MAX];
  913. BOOL bReturn = Value2String(pFormsDlgData, lValueInPoint001mm, bMetric, TRUE,
  914. ARRAYSIZE(szValue), szValue);
  915. if( bReturn )
  916. {
  917. bReturn = SetDlgItemText(hwnd, uID, szValue);
  918. }
  919. return bReturn;
  920. }
  921. /*
  922. * GetValue
  923. */
  924. BOOL
  925. GetValue(
  926. HWND hwnd,
  927. DWORD uID,
  928. LONG lCurrentValueInPoint001mm,
  929. BOOL bDefaultMetric,
  930. PLONG plValueInPoint001mm
  931. )
  932. {
  933. TCHAR szValue[FORMS_PARAM_MAX];
  934. szValue[0] = 0;
  935. GetDlgItemText(hwnd, uID, szValue, ARRAYSIZE(szValue));
  936. PFORMS_DLG_DATA pFormsDlgData = (PFORMS_DLG_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  937. return String2Value(pFormsDlgData, szValue, bDefaultMetric, lCurrentValueInPoint001mm, plValueInPoint001mm);
  938. }
  939. /*
  940. * SetDlgItemTextFromResID
  941. */
  942. VOID SetDlgItemTextFromResID(HWND hwnd, int idCtl, int idRes)
  943. {
  944. TCHAR string[kStrMax];
  945. LoadString(ghInst, idRes, string, ARRAYSIZE(string));
  946. SetDlgItemText(hwnd, idCtl, string);
  947. }
  948. /*
  949. *
  950. */
  951. VOID EnableDialogFields( HWND hwnd, PFORMS_DLG_DATA pFormsDlgData )
  952. {
  953. INT i;
  954. BOOL EnableEntryFields = TRUE;
  955. BOOL EnableAddButton = TRUE;
  956. BOOL EnableDeleteButton = TRUE;
  957. LPTSTR pFormName;
  958. // if new form check keep edit fields enabled.
  959. if( Button_GetCheck(GetDlgItem(hwnd, IDD_FM_CK_NEW_FORM)) )
  960. {
  961. vFormsEnableEditFields(hwnd, TRUE);
  962. return;
  963. }
  964. // if not granted all access access.
  965. if( FALSE == pFormsDlgData->AccessGranted == TRUE )
  966. {
  967. EnableWindow(GetDlgItem(hwnd, IDD_FM_EF_NAME), FALSE);
  968. EnableWindow(GetDlgItem(hwnd, IDC_FORMNAME_LABEL), FALSE);
  969. EnableEntryFields = FALSE;
  970. EnableAddButton = FALSE;
  971. EnableDeleteButton = FALSE;
  972. EnumChildWindows(hwnd, GreyText, 0);
  973. }
  974. /* else - See whether the Form Name is new:
  975. */
  976. else if( ( pFormName = GetFormName(hwnd) ) != NULL )
  977. {
  978. /* Now see if the name is already in the list:
  979. */
  980. i = GetFormIndex( pFormName, pFormsDlgData->pFormInfo,
  981. pFormsDlgData->cForms );
  982. if( i >= 0 )
  983. {
  984. /* Can't modify a built-in form:
  985. */
  986. if( pFormsDlgData->pFormInfo[i].Flags & FORM_BUILTIN )
  987. {
  988. EnableEntryFields = FALSE;
  989. EnableDeleteButton = FALSE;
  990. }
  991. else
  992. {
  993. EnableEntryFields = TRUE;
  994. EnableDeleteButton = TRUE;
  995. }
  996. /* Can't add a form with the same name:
  997. */
  998. EnableAddButton = FALSE;
  999. }
  1000. else
  1001. {
  1002. EnableDeleteButton = FALSE;
  1003. }
  1004. FreeStr(pFormName);
  1005. }
  1006. else
  1007. {
  1008. /* Name field is blank: Can't add or delete:
  1009. */
  1010. EnableAddButton = FALSE;
  1011. EnableDeleteButton = FALSE;
  1012. }
  1013. // enable the edit fields.
  1014. vFormsEnableEditFields( hwnd, EnableEntryFields );
  1015. // enable the delete button
  1016. EnableWindow( GetDlgItem( hwnd, IDD_FM_PB_DELFORM ), EnableDeleteButton );
  1017. // enable the save form button
  1018. EnableWindow( GetDlgItem( hwnd, IDD_FM_PB_SAVEFORM ), EnableEntryFields );
  1019. }
  1020. /*++
  1021. Routine Name:
  1022. bEnumForms
  1023. Routine Description:
  1024. Enumerates the forms on the printer identified by handle.
  1025. Arguments:
  1026. IN HANDLE hPrinter,
  1027. IN DWORD dwLevel,
  1028. IN PBYTE *ppBuff,
  1029. IN PDWORD pcReturned
  1030. Return Value:
  1031. Pointer to forms array and count of forms in the array if
  1032. success, NULL ponter and zero number of forms if failure.
  1033. TRUE if success, FALSE if error.
  1034. --*/
  1035. BOOL
  1036. bEnumForms(
  1037. IN HANDLE hPrinter,
  1038. IN DWORD dwLevel,
  1039. IN PBYTE *ppBuff,
  1040. IN PDWORD pcReturned
  1041. )
  1042. {
  1043. BOOL bReturn = FALSE;
  1044. DWORD dwReturned = 0;
  1045. DWORD dwNeeded = 0;
  1046. PBYTE p = NULL;
  1047. TStatusB bStatus( DBG_WARN, ERROR_INSUFFICIENT_BUFFER );
  1048. // get buffer size for enum forms.
  1049. bStatus DBGNOCHK = EnumForms(
  1050. hPrinter,
  1051. dwLevel,
  1052. NULL,
  1053. 0,
  1054. &dwNeeded,
  1055. &dwReturned );
  1056. // check if the function returned the buffer size.
  1057. if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
  1058. {
  1059. goto Cleanup;
  1060. }
  1061. // if buffer allocation fails.
  1062. if( (p = (PBYTE)AllocMem(dwNeeded) ) == NULL )
  1063. {
  1064. goto Cleanup;
  1065. }
  1066. // get the forms enumeration
  1067. bStatus DBGCHK = EnumForms(
  1068. hPrinter,
  1069. dwLevel,
  1070. p,
  1071. dwNeeded,
  1072. &dwNeeded,
  1073. &dwReturned );
  1074. // copy back the buffer pointer and count.
  1075. if( bStatus )
  1076. {
  1077. bReturn = TRUE;
  1078. *ppBuff = p;
  1079. *pcReturned = dwReturned;
  1080. }
  1081. Cleanup:
  1082. if( bReturn == FALSE )
  1083. {
  1084. // indicate failure.
  1085. *ppBuff = NULL;
  1086. *pcReturned = 0;
  1087. // release any allocated memory.
  1088. if( p )
  1089. {
  1090. FreeMem(p);
  1091. }
  1092. }
  1093. return bReturn;
  1094. }
  1095. /*
  1096. * Checked new forms check box.
  1097. */
  1098. BOOL
  1099. FormsNewForms(
  1100. IN HWND hWnd
  1101. )
  1102. {
  1103. // get Current check state.
  1104. BOOL bState = Button_GetCheck(GetDlgItem(hWnd, IDD_FM_CK_NEW_FORM));
  1105. // set the name edit field.
  1106. EnableWindow(GetDlgItem(hWnd, IDD_FM_EF_NAME), bState);
  1107. EnableWindow(GetDlgItem(hWnd, IDC_FORMNAME_LABEL), bState);
  1108. // set the new form text state.
  1109. EnableWindow(GetDlgItem(hWnd, IDD_FM_TX_NEW_FORM), bState);
  1110. // if enabling new form then the delete button should be disabled.
  1111. if( bState )
  1112. {
  1113. EnableWindow(GetDlgItem(hWnd, IDD_FM_PB_DELFORM), FALSE);
  1114. }
  1115. // Enable the edit fields.
  1116. vFormsEnableEditFields(hWnd, bState);
  1117. // if disabling new forms set edit fields based on
  1118. // current selection.
  1119. if( !bState )
  1120. {
  1121. FormsCommandFormsSelChange(hWnd);
  1122. }
  1123. return FALSE;
  1124. }
  1125. /*
  1126. * vFormsEnableEditFields
  1127. */
  1128. VOID
  1129. vFormsEnableEditFields(
  1130. IN HWND hWnd,
  1131. IN BOOL bState
  1132. )
  1133. {
  1134. UINT i;
  1135. for( i = 0; pEntryFields[i]; i++ )
  1136. {
  1137. EnableWindow( GetDlgItem( hWnd, pEntryFields[i] ), bState );
  1138. }
  1139. for( i = 0; pTextFields[i]; i++ )
  1140. {
  1141. EnableWindow( GetDlgItem( hWnd, pTextFields[i] ), bState );
  1142. }
  1143. }
  1144. //
  1145. // Enable the save form button when the name changes.
  1146. //
  1147. BOOL
  1148. FormsCommandNameChange(
  1149. IN HWND hWnd,
  1150. IN WPARAM wParam,
  1151. IN LPARAM lParam
  1152. )
  1153. {
  1154. BOOL bStatus;
  1155. LPTSTR pFormName = NULL;
  1156. LRESULT Status = TRUE;
  1157. switch( GET_WM_COMMAND_CMD(wParam, lParam) )
  1158. {
  1159. case EN_CHANGE:
  1160. // if the name edit box is not in the enabled state.
  1161. if( !IsWindowEnabled((HWND)lParam) )
  1162. {
  1163. bStatus = FALSE;
  1164. break;
  1165. }
  1166. // Get the form name from the edit control.
  1167. pFormName = GetFormName(hWnd);
  1168. // If a form name was returned.
  1169. if( pFormName )
  1170. {
  1171. // If the name has length then
  1172. // check if it's in the list.
  1173. if( lstrlen(pFormName) )
  1174. {
  1175. // Locate the form name in the list box.
  1176. Status = SendDlgItemMessage(
  1177. hWnd,
  1178. IDD_FM_LB_FORMS,
  1179. LB_FINDSTRINGEXACT,
  1180. (WPARAM)-1,
  1181. (LPARAM)pFormName);
  1182. }
  1183. // Insure we release the form name, since we have
  1184. // adopted the nemory.
  1185. if( pFormName )
  1186. {
  1187. FreeMem(pFormName);
  1188. }
  1189. }
  1190. // Set the save form enable state.
  1191. EnableWindow(GetDlgItem(hWnd, IDD_FM_PB_SAVEFORM), Status == LB_ERR ? TRUE : FALSE);
  1192. bStatus = TRUE;
  1193. break;
  1194. default:
  1195. bStatus = FALSE;
  1196. break;
  1197. }
  1198. return bStatus;
  1199. }
  1200. BOOL
  1201. String2Value(
  1202. IN PFORMS_DLG_DATA pFormsDlgData,
  1203. IN LPCTSTR pszValue,
  1204. IN BOOL bDefaultMetric,
  1205. IN LONG lCurrentValueInPoint001mm,
  1206. OUT PLONG plValueInPoint001mm
  1207. )
  1208. {
  1209. ASSERT(pFormsDlgData);
  1210. ASSERT(pszValue);
  1211. ASSERT(plValueInPoint001mm);
  1212. double dValue = 0.0;
  1213. *plValueInPoint001mm = 0;
  1214. BOOL bMetric = bDefaultMetric;
  1215. BOOL bResult = TRUE;
  1216. if( *pszValue )
  1217. {
  1218. // make a copy of the input string
  1219. TCHAR szValue[FORMS_PARAM_MAX];
  1220. lstrcpyn(szValue, pszValue, ARRAYSIZE(szValue));
  1221. // convert international decimal separator, if necessary:
  1222. if( *pFormsDlgData->szDecimalPoint != TEXT('.') )
  1223. {
  1224. TCHAR *p = szValue;
  1225. while( *p )
  1226. {
  1227. if( *p == *pFormsDlgData->szDecimalPoint )
  1228. {
  1229. *p = TEXT('.');
  1230. }
  1231. p++;
  1232. }
  1233. }
  1234. // convert to double, pGarbage should be "in" or "cm" (depends on metric)
  1235. TCHAR *pGarbage = NULL;
  1236. dValue = _tcstod(szValue, &pGarbage);
  1237. ASSERT(pGarbage);
  1238. // load the measurement strings from resource
  1239. TCHAR szUnitsIn[CCH_MAX_UNITS];
  1240. TCHAR szUnitsCm[CCH_MAX_UNITS];
  1241. bResult = LoadString(ghInst, IDS_INCHES, szUnitsIn, ARRAYSIZE(szUnitsIn)) &&
  1242. LoadString(ghInst, IDS_CENTIMETERS, szUnitsCm, ARRAYSIZE(szUnitsCm));
  1243. if( bResult )
  1244. {
  1245. // check to validate the converted number
  1246. if( dValue < 0.0 )
  1247. {
  1248. // negative values are invalid
  1249. bResult = FALSE;
  1250. }
  1251. else if( 0 == lstrcmpi(pGarbage, szUnitsIn) )
  1252. {
  1253. // enforce inches
  1254. bMetric = FALSE;
  1255. }
  1256. else if( 0 == lstrcmpi(pGarbage, szUnitsCm) )
  1257. {
  1258. // enforce centimeters
  1259. bMetric = TRUE;
  1260. }
  1261. else if( lstrlen(pGarbage) )
  1262. {
  1263. // pGarbage is neither "in" nor "cm" - error!
  1264. bResult = FALSE;
  1265. }
  1266. }
  1267. if( bResult )
  1268. {
  1269. TCHAR szCurrentValue[FORMS_PARAM_MAX];
  1270. // cut the garbage first
  1271. *pGarbage = 0;
  1272. // if the converted number is valid, check to see if not the
  1273. // same as the current one...
  1274. if( bMetric == bDefaultMetric &&
  1275. Value2String(pFormsDlgData, lCurrentValueInPoint001mm,
  1276. bDefaultMetric, FALSE, ARRAYSIZE(szCurrentValue), szCurrentValue) &&
  1277. 0 == lstrcmp(szCurrentValue, szValue) )
  1278. {
  1279. // it is the same. don't recalc, so we don't loose precision.
  1280. *plValueInPoint001mm = lCurrentValueInPoint001mm;
  1281. }
  1282. else
  1283. {
  1284. // calculate in point001mm
  1285. *plValueInPoint001mm = (DWORD)(dValue * (bMetric ? 100*100 : 254*100));
  1286. }
  1287. }
  1288. }
  1289. return bResult;
  1290. }
  1291. BOOL
  1292. Value2String(
  1293. IN PFORMS_DLG_DATA pFormsDlgData,
  1294. IN LONG lValueInPoint001mm,
  1295. IN BOOL bMetric,
  1296. IN BOOL bAppendMetric,
  1297. IN UINT cchMaxChars,
  1298. OUT LPTSTR szOutBuffer
  1299. )
  1300. {
  1301. ASSERT(pFormsDlgData);
  1302. ASSERT(szOutBuffer);
  1303. BOOL bReturn = FALSE;
  1304. static const TCHAR szFormat[] = TEXT("%d%s%02d%s");
  1305. static const TCHAR szFormat1[] = TEXT("%d%s%02d");
  1306. TCHAR szUnits[CCH_MAX_UNITS];
  1307. DWORD dwUnitsX100 = (DWORD)((lValueInPoint001mm / (bMetric ? 100.0 : 254.0)) + 0.5);
  1308. if( LoadString(ghInst, bMetric ? IDS_CENTIMETERS: IDS_INCHES, szUnits, ARRAYSIZE(szUnits)) )
  1309. {
  1310. wnsprintf(szOutBuffer, cchMaxChars, bAppendMetric ? szFormat : szFormat1,
  1311. dwUnitsX100 / 100, pFormsDlgData->szDecimalPoint, dwUnitsX100 % 100, szUnits);
  1312. bReturn = TRUE;
  1313. }
  1314. return bReturn;
  1315. }
  1316. VOID
  1317. FormChanged(
  1318. IN OUT PFORMS_DLG_DATA pFormsDlgData
  1319. )
  1320. {
  1321. // if part of property sheet this will notify the UI to
  1322. // call PSM_CANCELTOCLOSE
  1323. pFormsDlgData->bFormChanged = TRUE;
  1324. }
  1325. BOOL
  1326. Forms_IsThereCommitedChanges(
  1327. IN PVOID pFormsData
  1328. )
  1329. {
  1330. ASSERT(pFormsData);
  1331. PFORMS_DLG_DATA pFormsDlgData = (PFORMS_DLG_DATA)pFormsData;
  1332. return pFormsDlgData->bFormChanged;
  1333. }
  1334. DWORD
  1335. Forms_GetLastError(
  1336. IN PVOID pFormsData
  1337. )
  1338. {
  1339. ASSERT(pFormsData);
  1340. PFORMS_DLG_DATA pFormsDlgData = (PFORMS_DLG_DATA)pFormsData;
  1341. return pFormsDlgData->dwLastError;
  1342. }