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.

1429 lines
50 KiB

  1. /*******************************************************************************
  2. *
  3. * Copyright 1999 American Power Conversion, All Rights Reserved
  4. *
  5. * TITLE: UPSTAB.C
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: PaulB
  10. *
  11. * DATE: 07 June, 1999
  12. *
  13. * DESCRIPTION: This file contains the main body of code for the UPS Tab.
  14. * This dialog procedure is implemented in this file, along with
  15. * some of the support functions.
  16. *
  17. *******************************************************************************/
  18. #include <nt.h>
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <shlobj.h>
  22. #include <shellapi.h>
  23. #include "upstab.h"
  24. #include "..\powercfg.h"
  25. #include "..\pwrresid.h"
  26. #include "..\PwrMn_cs.h"
  27. #pragma hdrstop
  28. // data
  29. ///////////////////////////////////////////////////////////////////////////////
  30. HWND g_hwndDlg = 0;
  31. HICON g_hIconUPS = 0;
  32. HICON g_hIconPlug = 0;
  33. // context-sensitive help table
  34. const DWORD g_UPSPageHelpIDs[]=
  35. {
  36. IDC_STATIC, NO_HELP,
  37. IDC_STATUS_GROUPBOX, NO_HELP,
  38. IDC_POWER_SOURCE_ICON, idh_current_power_source,
  39. IDC_POWER_SOURCE_LHS, idh_current_power_source,
  40. IDC_POWER_SOURCE, idh_current_power_source,
  41. IDC_RUNTIME_REMAINING_LHS, idh_estimated_ups_runtime,
  42. IDC_RUNTIME_REMAINING, idh_estimated_ups_runtime,
  43. IDC_BATTERY_CAPACITY_LHS, idh_estimated_ups_capacity,
  44. IDC_BATTERY_CAPACITY, idh_estimated_ups_capacity,
  45. IDC_BATTERY_STATUS_LHS, idh_battery_condition,
  46. IDC_BATTERY_STATUS, idh_battery_condition,
  47. IDC_DETAILS_GROUPBOX, NO_HELP,
  48. IDB_UPS_ICON_BUTTON, idh_apc_logo_link,
  49. IDC_VENDOR_NAME_LHS, idh_manufacturer,
  50. IDC_VENDOR_NAME, idh_manufacturer,
  51. IDC_MODEL_TYPE_LHS, idh_model,
  52. IDC_MODEL_TYPE, idh_model,
  53. IDB_INSTALL_UPS, idh_select_ups,
  54. IDB_CONFIGURE_SVC, idh_configure_ups,
  55. IDC_MESSAGE_ICON, NO_HELP,
  56. IDC_MESSAGE_TEXT, NO_HELP,
  57. IDC_APC1, NO_HELP,
  58. IDC_APC2, NO_HELP,
  59. IDB_APCLOGO_SMALL, NO_HELP,
  60. 0, 0
  61. };
  62. // data
  63. ///////////////////////////////////////////////////////////////////////////////
  64. extern struct _reg_entry UPSConfigVendor;
  65. extern struct _reg_entry UPSConfigModel;
  66. //static LPCTSTR cUPSStateFormatString = TEXT("%s %s");
  67. static UINT_PTR g_UpdateTimerID = 0;
  68. static const DWORD cUpdateTimerID = 100;
  69. static BOOL g_bIsAdmin = TRUE;
  70. // functions
  71. ///////////////////////////////////////////////////////////////////////////////
  72. static DWORD FormatMessageText (LPCTSTR aFormatString,
  73. LPVOID * alpDwords,
  74. LPTSTR aMessageBuffer,
  75. DWORD * aBufferSizePtr);
  76. static BOOL UPSMainPageHandleInit (HWND aDlgHWND, WPARAM wParam, LPARAM lParam);
  77. static BOOL UPSMainPageHandleCommand (HWND aDlgHWND, WPARAM wParam, LPARAM lParam);
  78. static BOOL UPSMainPageHandleNotify (HWND aDlgHWND, WPARAM wParam, LPARAM lParam);
  79. //All these functions are commented in the source file updatdlg.c
  80. static BOOL UPSMainPageHandleDestroy (HWND hDlg,
  81. WPARAM wParam,
  82. LPARAM lParam);
  83. static BOOL CreateUPSIconButton(HWND hDlg, HICON aUPSIconHandle);
  84. static void DoUpdateDialogInfo (HWND hDlg);
  85. static void ManageConfigureButtonState (HWND hDlg);
  86. DWORD SetUpdateTimer(HWND hwnd);
  87. DWORD KillUpdateTimer(HWND hwnd);
  88. ///////////////////////////////////////////////////////////////////////////////
  89. ///////////////////////////////////////////////////////////////////////////////
  90. ///////////////////////////////////////////////////////////////////////////////
  91. //////////////////////////////////////////////////////////////////////////_/_//
  92. //////////////////////////////////////////////////////////////////////////_/_//
  93. // BOOL CALLBACK UPSMainPageProc (HWND aDlgHWND,
  94. // UINT aMsgID,
  95. // WPARAM wParam,
  96. // LPARAM lParam);
  97. //
  98. // Description: This is a standard DialogProc associated with the UPS tab dialog.
  99. //
  100. // Additional Information: See help on
  101. // \<A HREF="ms-its:C:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\1033\winui.chm::/devdoc/live/pdui/dlgboxes_5lib.htm">DialogProc\</A>
  102. //
  103. // Parameters:
  104. //
  105. // HWND aDlgHWND :- Handle to dialog box
  106. //
  107. // UINT aMsgID :- message ID
  108. //
  109. // WPARAM wParam :- Specifies additional message-specific information.
  110. //
  111. // LPARAM lParam :- Specifies additional message-specific information.
  112. //
  113. // Return Value: Except in response to the WM_INITDIALOG message, the dialog
  114. // box procedure should return nonzero if it processes the
  115. // message, and zero if it does not.
  116. //
  117. INT_PTR CALLBACK UPSMainPageProc (HWND aDlgHWND,
  118. UINT aMsgID,
  119. WPARAM wParam,
  120. LPARAM lParam) {
  121. BOOL bRet = TRUE;
  122. switch (aMsgID) {
  123. case WM_INITDIALOG: {
  124. //The dialog box procedure should return TRUE to direct the system to
  125. //set the keyboard focus to the control given by wParam.
  126. bRet = UPSMainPageHandleInit(aDlgHWND, wParam, lParam);
  127. break;
  128. }
  129. case WM_COMMAND: {
  130. //If an application processes this message, it should return zero.
  131. bRet = UPSMainPageHandleCommand(aDlgHWND, wParam, lParam);
  132. break;
  133. }
  134. case WM_NOTIFY: {
  135. bRet = UPSMainPageHandleNotify(aDlgHWND, wParam, lParam);
  136. break;
  137. }
  138. case WM_TIMER: {
  139. //If an application processes this message, it should return zero.
  140. DoUpdateDialogInfo(aDlgHWND);
  141. bRet = FALSE;
  142. break;
  143. }
  144. case WM_HELP: { //Help for WM_HELP says: Returns TRUE
  145. bRet = WinHelp(((LPHELPINFO)lParam)->hItemHandle,
  146. PWRMANHLP,
  147. HELP_WM_HELP,
  148. (ULONG_PTR)(LPTSTR)g_UPSPageHelpIDs);
  149. break;
  150. }
  151. case WM_CONTEXTMENU: { // right mouse click
  152. //
  153. // Kill the update timer while context help is active.
  154. // Otherwise the code in the timer handler interferes with the help UI.
  155. //
  156. KillUpdateTimer(aDlgHWND);
  157. bRet = WinHelp((HWND)wParam,
  158. PWRMANHLP,
  159. HELP_CONTEXTMENU,
  160. (ULONG_PTR)(LPTSTR)g_UPSPageHelpIDs);
  161. SetUpdateTimer(aDlgHWND);
  162. break;
  163. }
  164. case WM_DESTROY: {
  165. //An application returns 0 if it processes WM_DESTROY
  166. bRet = UPSMainPageHandleDestroy(aDlgHWND, wParam, lParam);
  167. break;
  168. }
  169. default: {
  170. bRet = FALSE;
  171. break;
  172. }
  173. } // switch (aMsgID)
  174. return(bRet);
  175. }
  176. //////////////////////////////////////////////////////////////////////////_/_//
  177. //////////////////////////////////////////////////////////////////////////_/_//
  178. // BOOL UPSMainPageHandleInit (HWND aDlgHWND,
  179. // WPARAM wParam,
  180. // LPARAM lParam);
  181. //
  182. // Description: This is the handler function for WM_INITDIALOG. It creates the
  183. // tooltip window, initialize the controls and creates the update
  184. // timer.
  185. //
  186. // Additional Information:
  187. //
  188. // Parameters:
  189. //
  190. // HWND aDlgHWND :- Identifies the dialog box.
  191. //
  192. // WPARAM wParam :- Handle of control to receive focus
  193. //
  194. // LPARAM lParam :- Initialization parameter
  195. //
  196. // Return Value: The dialog box procedure should return TRUE to direct the
  197. // system to set the keyboard focus to the control given by
  198. // wParam.
  199. //
  200. BOOL UPSMainPageHandleInit (HWND aDlgHWND,
  201. WPARAM wParam,
  202. LPARAM lParam) {
  203. /*
  204. * The dialog is being created. By default many of the controls in the UPS
  205. * page will appear disabled. If there is no data to display then this is
  206. * the required behavior. We need to get the UPS data. When an individual
  207. * data item is retrieved we then enable the field associated with that data
  208. * item. If the data item is not available we disabled the field. We have
  209. * to disable even though in this case the field is already disabled
  210. * due to the fact that it's disabled in the RC file and we are in startup.
  211. * But this same code is used in the "Refresh" scenario, requiring the the
  212. * status of the field be able to be changed from enabled to disabled.
  213. */
  214. static BOOL bIsInitialized = FALSE;
  215. TCHAR szVendorName[MAX_PATH] = _T("");
  216. TCHAR szModelName[MAX_PATH] = _T("");
  217. g_hwndDlg = aDlgHWND;
  218. /*
  219. * Determine if the registry needs to be initialized for the UPS service.
  220. * if it is already initialized, do nothing
  221. */
  222. g_bIsAdmin = InitializeRegistry();
  223. /*
  224. * Disable or hide the configure and select buttons depending on
  225. * whether or not we can write to the registry.
  226. */
  227. EnableWindow( GetDlgItem( aDlgHWND, IDB_INSTALL_UPS ), g_bIsAdmin );
  228. EnableWindow( GetDlgItem( aDlgHWND, IDB_CONFIGURE_SVC ), g_bIsAdmin );
  229. InitializeApplyButton(aDlgHWND);
  230. // Load icon images for Power Source and UPS Info button
  231. g_hIconUPS = LoadImage(GetUPSModuleHandle(),
  232. MAKEINTRESOURCE(IDI_UPS),
  233. IMAGE_ICON,
  234. 0, 0,
  235. LR_LOADMAP3DCOLORS | LR_SHARED);
  236. g_hIconPlug = LoadImage(GetUPSModuleHandle(),
  237. MAKEINTRESOURCE(IDI_PLUG),
  238. IMAGE_ICON,
  239. 0, 0,
  240. LR_LOADMAP3DCOLORS | LR_SHARED);
  241. if( NULL != g_hIconUPS )
  242. CreateUPSIconButton(aDlgHWND, g_hIconUPS);
  243. // Init the Registry info blocks ONCE
  244. if (!bIsInitialized) {
  245. InitUPSConfigBlock();
  246. InitUPSStatusBlock();
  247. bIsInitialized = TRUE;
  248. }
  249. /*
  250. * NOTE:
  251. * This is a workaround to fix previously hard-coded default
  252. * strings in upsreg.c If the Vendor Name is null then we assume
  253. * that we should apply
  254. * default values from the resource file
  255. */
  256. GetUPSConfigVendor( szVendorName);
  257. GetUPSConfigModel( szModelName);
  258. /*
  259. * The function IsUPSInstalled assumes the config
  260. * block has been initialized.
  261. */
  262. if (!_tcsclen(szVendorName) && IsUPSInstalled()) {
  263. // Get the "Generic" vendor name from the resource file.
  264. LoadString(GetUPSModuleHandle(),
  265. IDS_OTHER_UPS_VENDOR,
  266. (LPTSTR) szVendorName,
  267. sizeof(szVendorName)/sizeof(TCHAR));
  268. // Get the "Custom" model name from the resource file.
  269. LoadString(GetUPSModuleHandle(),
  270. IDS_CUSTOM_UPS_MODEL,
  271. (LPTSTR) szModelName,
  272. sizeof(szModelName)/sizeof(TCHAR));
  273. SetUPSConfigVendor( szVendorName);
  274. SetUPSConfigModel( szModelName);
  275. SaveUPSConfigBlock(FALSE);
  276. }
  277. if (!_tcsclen(szVendorName) && !IsUPSInstalled()) {
  278. // Get the "No UPS" vendor name from the resource file.
  279. LoadString(GetUPSModuleHandle(),
  280. IDS_NO_UPS_VENDOR,
  281. (LPTSTR) szVendorName,
  282. sizeof(szVendorName)/sizeof(TCHAR));
  283. SetUPSConfigVendor( szVendorName);
  284. SaveUPSConfigBlock(FALSE);
  285. }
  286. DoUpdateDialogInfo(aDlgHWND);
  287. SetUpdateTimer(aDlgHWND);
  288. return(FALSE);
  289. }
  290. //////////////////////////////////////////////////////////////////////////_/_//
  291. //////////////////////////////////////////////////////////////////////////_/_//
  292. // BOOL UPSMainPageHandleCommand (HWND aDlgHWND,
  293. // WPARAM wParam,
  294. // LPARAM lParam);
  295. //
  296. // Description: This is the handler function for WM_COMMAND.
  297. //
  298. // Additional Information: See help on WM_COMMAND
  299. //
  300. // Parameters:
  301. //
  302. // HWND aDlgHWND :- Handle to dialog box
  303. //
  304. // WPARAM wParam :- HIWORD(wParam) gives the notification code.
  305. // LOWORD(wParam) gives the control id.
  306. //
  307. // LPARAM lParam :- Gives the HWND or handle of the control.
  308. //
  309. // Return Value: If an application processes this message, it should return 0.
  310. //
  311. BOOL UPSMainPageHandleCommand (HWND aDlgHWND,
  312. WPARAM wParam,
  313. LPARAM lParam) {
  314. switch (LOWORD(wParam)) {// control ID
  315. case IDB_INSTALL_UPS: {
  316. DialogBoxParam( GetUPSModuleHandle(),
  317. MAKEINTRESOURCE(IDD_UPSSELECT),
  318. aDlgHWND,
  319. UPSSelectDlgProc, (LPARAM) aDlgHWND);
  320. break;
  321. }
  322. case IDB_UPS_ICON_BUTTON: {
  323. DisplayUPSInfoDialogBox(aDlgHWND);
  324. break;
  325. }
  326. case IDC_APC1:
  327. case IDC_APC2:
  328. case IDB_APCLOGO_SMALL: {
  329. DisplayAboutDialogBox(aDlgHWND);
  330. break;
  331. }
  332. case IDB_CONFIGURE_SVC: {
  333. DialogBoxParam( GetUPSModuleHandle(),
  334. MAKEINTRESOURCE(IDD_UPSCONFIGURATION),
  335. aDlgHWND, UPSConfigDlgProc, (LPARAM) aDlgHWND);
  336. break;
  337. }
  338. default: {
  339. break;
  340. }
  341. }//end switch
  342. //If an application processes this message, it should return zero.
  343. return(FALSE);
  344. }
  345. //////////////////////////////////////////////////////////////////////////_/_//
  346. //////////////////////////////////////////////////////////////////////////_/_//
  347. // BOOL UPSMainPageHandleNotify (HWND aDlgHWND,
  348. // WPARAM wParam,
  349. // LPARAM lParam);
  350. //
  351. // Description: Sent by a common control to its parent window when an event has
  352. // occurred in the control or the control requires some kind of
  353. // information.
  354. //
  355. // Additional Information: See help on NMHDR
  356. //
  357. // Parameters:
  358. //
  359. // HWND aDlgHWND :- Handle to dialog box
  360. //
  361. // WPARAM wParam :- Identifier of the common control sending the message.
  362. //
  363. // LPARAM lParam :- Address of an NMHDR structure that contains the
  364. // notification code and additional information.
  365. //
  366. // Return Value: If an application processes this message, it should return 0.
  367. //
  368. BOOL UPSMainPageHandleNotify (HWND aDlgHWND,
  369. WPARAM wParam,
  370. LPARAM lParam) {
  371. LPNMHDR pnmhdr = (LPNMHDR) lParam;
  372. UINT uNotify = pnmhdr->code;
  373. BOOL bWait = FALSE;
  374. switch(uNotify) {
  375. case PSN_APPLY: {
  376. DWORD dataState = GetActiveDataState();
  377. /*
  378. * Indicates that the user clicked the OK or Apply button and wants
  379. * all changes to take effect.
  380. * A page should not call the EndDialog function when processing this
  381. * notification message.
  382. */
  383. // Has anything changed? Do nothing otherwise.
  384. if (DATA_NO_CHANGE != dataState) {
  385. // Yes - make changes permanent
  386. SetUPSConfigUpgrade(FALSE); // this really only needs to be done the first time, but...
  387. SaveUPSConfigBlock(FALSE);
  388. SetWindowLongPtr(aDlgHWND, DWLP_MSGRESULT, PSNRET_NOERROR);
  389. // Did the service data change?
  390. if ((dataState & SERVICE_DATA_CHANGE) == SERVICE_DATA_CHANGE) {
  391. // Yes - need to restart the service for the changes to take effect
  392. StopService(UPS_SERVICE_NAME); // Stop the service if it's running
  393. ConfigureService(IsUPSInstalled()); // Set the UPS service to automatic or manual
  394. // Was the change that No UPS is installed?
  395. if (IsUPSInstalled() == TRUE) {
  396. //
  397. if (StartOffService(UPS_SERVICE_NAME, TRUE) == FALSE) {
  398. // If OK was selected this will stop the applet from closing
  399. // so that you can see that the service didn't start properly.
  400. SetWindowLongPtr(aDlgHWND, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  401. // Since we've committed our changes, disable the Apply button.
  402. PropSheet_UnChanged(GetParent(aDlgHWND), aDlgHWND);
  403. }
  404. }
  405. }
  406. SetActiveDataState(DATA_NO_CHANGE);
  407. }
  408. break;
  409. }
  410. case PSN_RESET: {
  411. //Notifies a page that the user has clicked the Cancel button and the
  412. //property sheet is about to be destroyed.
  413. break;
  414. }
  415. default:
  416. return(FALSE);
  417. }//end switch
  418. return(TRUE);
  419. }
  420. //////////////////////////////////////////////////////////////////////////_/_//
  421. //////////////////////////////////////////////////////////////////////////_/_//
  422. // BOOL IsUPSInstalled (void);
  423. //
  424. // Description: This function checks the "internal" values to determine if a
  425. // UPS is installed or not.
  426. //
  427. // Additional Information:
  428. //
  429. // Parameters: None
  430. //
  431. // Return Value: Returns TRUE if a UPS is installed, FALSE otherwise.
  432. //
  433. BOOL IsUPSInstalled (void) {
  434. BOOL bIsInstalled = FALSE;
  435. DWORD options = 0;
  436. if (GetUPSConfigOptions(&options) == ERROR_SUCCESS) {
  437. //If Options includes UPS_INSTALLED
  438. if ((options & UPS_INSTALLED) == UPS_INSTALLED) {
  439. bIsInstalled = TRUE;
  440. }
  441. }
  442. else {
  443. //The Options value should exist at this stage, or something is wrong
  444. //with SaveUPSConfigBlock()
  445. _ASSERT(FALSE);
  446. }
  447. return(bIsInstalled);
  448. }
  449. //////////////////////////////////////////////////////////////////////////_/_//
  450. //////////////////////////////////////////////////////////////////////////_/_//
  451. // DWORD FormatMessageText (LPCTSTR aFormatString,
  452. // LPVOID * alpDwords,
  453. // LPTSTR aMessageBuffer,
  454. // DWORD * aBufferSizePtr);
  455. //
  456. // Description: This function wraps FormatMessage and is used to put inserts
  457. // into a given string. The inserts must be stored in an array of
  458. // 32-bit values that represent the arguments.
  459. //
  460. // Additional Information: FormatMessage
  461. //
  462. // Parameters:
  463. //
  464. // LPCTSTR aFormatString :- Pointer to the format string containing inserts
  465. // of the form %1, %2 etc.
  466. //
  467. // LPVOID * alpDwords :- A pointer to an array of 32-bit values that
  468. // represent the arguments.
  469. //
  470. // LPTSTR aMessageBuffer :- Buffer to which the fully formatted string is
  471. // written, if successful.
  472. //
  473. // DWORD * aBufferSizePtr :- Pointer to a DWORD that holds the size of the
  474. // buffer to write to. If this function returns
  475. // successfully this will contain the number
  476. // of bytes written.
  477. //
  478. // Return Value: Function returns ERROR_SUCCESS on success and a Win32 error
  479. // code if an error occurs.
  480. //
  481. DWORD FormatMessageText (LPCTSTR aFormatString,
  482. LPVOID * alpDwords,
  483. LPTSTR aMessageBuffer,
  484. DWORD * aBufferSizePtr) {
  485. LPTSTR lpBuf = NULL; // Will Hold text of the message (allocated by FormatMessage
  486. DWORD errStatus = ERROR_SUCCESS;
  487. DWORD numChars = 0;
  488. if ((numChars = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  489. (LPCVOID) aFormatString,
  490. 0,
  491. 0,
  492. (LPTSTR) &lpBuf,
  493. MAX_MESSAGE_LENGTH,
  494. (va_list *)alpDwords)) == 0) {
  495. *aBufferSizePtr = 0;
  496. *aMessageBuffer = TEXT('\0');
  497. }
  498. else {
  499. if (aBufferSizePtr != NULL) {
  500. if (numChars < *aBufferSizePtr) {
  501. //the given buffer is big enough to hold the string
  502. if (aMessageBuffer != NULL) {
  503. _tcscpy(aMessageBuffer, lpBuf);
  504. }
  505. }
  506. *aBufferSizePtr = numChars;
  507. }
  508. LocalFree(lpBuf);
  509. }
  510. return(errStatus);
  511. }
  512. //////////////////////////////////////////////////////////////////////////_/_//
  513. //////////////////////////////////////////////////////////////////////////_/_//
  514. // DWORD GetMessageFromStringTable (DWORD aMessageID,
  515. // LPVOID * alpDwords,
  516. // LPTSTR aMessageBuffer,
  517. // DWORD * aBufferSizePtr);
  518. //
  519. // Description: This function reads a string resource from the resource table
  520. // inserting the given string inserts.
  521. //
  522. // Additional Information:
  523. //
  524. // Parameters:
  525. //
  526. // DWORD aMessageID :- Message ID of the string resource to get.
  527. //
  528. // LPVOID * alpDwords :- A pointer to an array of 32-bit values that
  529. // represent the arguments.
  530. //
  531. // LPTSTR aMessageBuffer :- Buffer to which the fully formatted string is
  532. // written, if successful.
  533. //
  534. // DWORD * aBufferSizePtr :- Pointer to a DWORD that holds the size of the
  535. // buffer to write to. If this function returns
  536. // successfully this will contain the number
  537. // of bytes written.
  538. //
  539. // Return Value: Function returns ERROR_SUCCESS on success and a Win32 error
  540. // code if an error occurs.
  541. //
  542. DWORD GetMessageFromStringTable (DWORD aMessageID,
  543. LPVOID * alpDwords,
  544. LPTSTR aMessageBuffer,
  545. DWORD * aBufferSizePtr) {
  546. TCHAR resourceTemplateString[MAX_MESSAGE_LENGTH] = TEXT("");
  547. DWORD resStringBufSize = DIMENSION_OF(resourceTemplateString);
  548. HMODULE hUPSModule = GetUPSModuleHandle();
  549. DWORD errStatus = ERROR_INVALID_PARAMETER;
  550. if (LoadString(hUPSModule,
  551. aMessageID,
  552. resourceTemplateString,
  553. resStringBufSize) > 0) {
  554. //Now we have the resource string
  555. errStatus = FormatMessageText(resourceTemplateString,
  556. alpDwords,
  557. aMessageBuffer,
  558. aBufferSizePtr);
  559. }
  560. return(errStatus);
  561. }
  562. // UPDATDLG.C
  563. // static data
  564. ///////////////////////////////////////////////////////////////////////////////
  565. static DialogAssociations g_DialogAssocs[] = {
  566. MAKE_ARRAY ( VENDOR_NAME, IDS_STRING, IDS_STRING, RESOURCE_FIXED, 0, eShallowGet, getStringValue, &UPSConfigVendor),
  567. MAKE_ARRAY ( MODEL_TYPE, IDS_STRING, IDS_STRING, RESOURCE_FIXED, 0, eShallowGet, getStringValue, &UPSConfigModel),
  568. MAKE_ARRAY ( POWER_SOURCE, IDS_STRING, IDS_UTILITYPOWER_UNKNOWN, RESOURCE_INCREMENT, 2, eDeepGet, 0, 0),
  569. MAKE_ARRAY ( RUNTIME_REMAINING, IDS_RUNTIME_REMAINING, IDS_STRING, RESOURCE_FIXED, 0, eDeepGet, 0, 0),
  570. MAKE_ARRAY ( BATTERY_CAPACITY, IDS_CAPACITY, IDS_STRING, RESOURCE_FIXED, 0, eDeepGet, 0, 0),
  571. MAKE_ARRAY ( BATTERY_STATUS, IDS_STRING, IDS_BATTERYSTATUS_UNKNOWN, RESOURCE_INCREMENT, 2, eDeepGet, 0, 0) };
  572. static DWORD g_NoServiceControls[] = { IDC_MESSAGE_TEXT };
  573. // functions
  574. ///////////////////////////////////////////////////////////////////////////////
  575. static void SelectServiceTextMessage (HWND aDlgHWND, HWND aNoServiceControlHwnd, HWND aServiceControlHwnd);
  576. static void ChangeTextIfDifferent (HWND aWindowHandle, LPTSTR aBuffer);
  577. //static void GetServiceTextMessages (HWND aNoServiceControlHwnd, LPTSTR aOriginalTextBuffer, DWORD aOriginalTextBufferSize,
  578. // DWORD aCommListStringID, LPTSTR aCommStringBuffer, DWORD aCommStringBufferSize,
  579. // DWORD aPressApplyStringID, LPTSTR aPressApplyStringBuffer, DWORD aPressApplyStringBufferSize,
  580. // DWORD aNoUPSStringID, LPTSTR aNoUPSInstalledStringBuffer, DWORD aNoUPSInstalledStringBufferSize);
  581. //static void GetServiceTextMessage (DWORD aStringID, LPTSTR aBuffer, DWORD aBufferSize);
  582. static BOOL IsDataOKToDisplay (void);
  583. static BOOL IsDataUpToDate (void);
  584. ///////////////////////////////////////////////////////////////////////////////
  585. ///////////////////////////////////////////////////////////////////////////////
  586. //////////////////////////////////////////////////////////////////////////_/_//
  587. //////////////////////////////////////////////////////////////////////////_/_//
  588. // void UPSMainPageHandleDestroy (HWND aDlgHWND,
  589. // WPARAM wParam,
  590. // LPARAM lParam);
  591. //
  592. // Description: This function is called when the UPS page is being destroyed.
  593. // It is responsible for any cleanup that is required.
  594. //
  595. // Additional Information: See KillTimer
  596. //
  597. // Parameters:
  598. //
  599. // HWND aDlgHWND :- Dialog window handle.
  600. //
  601. // WPARAM wParam :- Specifies additional message-specific information.
  602. // For WM_DESTROY this parameter is ignored.
  603. //
  604. // LPARAM lParam :- Specifies additional message-specific information.
  605. // For WM_DESTROY this parameter is ignored.
  606. //
  607. // Return Value: An application returns 0 if it processes WM_DESTROY
  608. //
  609. BOOL UPSMainPageHandleDestroy (HWND aDlgHWND,
  610. WPARAM wParam,
  611. LPARAM lParam) {
  612. // deallocate the registry block memory
  613. FreeUPSConfigBlock();
  614. FreeUPSStatusBlock();
  615. KillUpdateTimer(aDlgHWND);
  616. //An application returns 0 if it processes WM_DESTROY
  617. return(FALSE);
  618. }
  619. //////////////////////////////////////////////////////////////////////////_/_//
  620. //////////////////////////////////////////////////////////////////////////_/_//
  621. // BOOL CreateUPSIconButton (HWND aDlgHWND, HICON aUPSIconHandle);
  622. //
  623. // Description: Creates the small UPS icon button on the UPS page.
  624. //
  625. // Additional Information:
  626. //
  627. // Parameters:
  628. //
  629. // HWND aDlgHWND :- Dialog window handle.
  630. //
  631. // HICON aUPSIconHandle :- Handle to the icon to display in the button.
  632. //
  633. // Return Value: Returns TRUE.
  634. //
  635. BOOL CreateUPSIconButton (HWND aDlgHWND, HICON aUPSIconHandle) {
  636. HWND hAPCLogoButton = GetDlgItem(aDlgHWND, IDB_UPS_ICON_BUTTON);
  637. POINT pt = { 0, 0 };
  638. ICONINFO info;
  639. BITMAP bm;
  640. _ASSERT(aDlgHWND != NULL);
  641. _ASSERT(aUPSIconHandle != NULL);
  642. _ASSERT(hAPCLogoButton != NULL);
  643. ZeroMemory(&info, sizeof(ICONINFO));
  644. if (GetIconInfo(aUPSIconHandle, &info) == TRUE) {
  645. //Now determine the size of the icon's color bitmap
  646. _ASSERT(info.fIcon == TRUE);
  647. _ASSERT(info.hbmColor != NULL);
  648. ZeroMemory(&bm, sizeof(BITMAP));
  649. if (GetObject(info.hbmColor, sizeof(BITMAP), &bm) != 0) {
  650. pt.x = bm.bmWidth;
  651. pt.y = bm.bmHeight;
  652. }
  653. //GetIconInfo creates bitmaps for the hbmMask and hbmColor members of
  654. //ICONINFO. The calling application must manage these bitmaps and delete
  655. //them when they are no longer necessary.
  656. DeleteObject(info.hbmColor);
  657. DeleteObject(info.hbmMask);
  658. }
  659. //Resize the button control.
  660. SetWindowPos(hAPCLogoButton,
  661. HWND_NOTOPMOST,
  662. -1,
  663. -1,
  664. pt.x,
  665. pt.y,
  666. SWP_NOMOVE | SWP_NOREPOSITION | SWP_NOZORDER);
  667. //This sets the button's icon image.
  668. SendMessage(hAPCLogoButton, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) aUPSIconHandle);
  669. return(TRUE);
  670. }
  671. //////////////////////////////////////////////////////////////////////////_/_//
  672. //////////////////////////////////////////////////////////////////////////_/_//
  673. // void DoUpdateDialogInfo (HWND aDlgHWND);
  674. //
  675. // Description: This functions gets the latest UPS information and updates the
  676. // contents/form of the various controls within the dialog, based
  677. // on the availability and content of the various settings.
  678. //
  679. // Additional Information:
  680. //
  681. // Parameters:
  682. //
  683. // HWND aDlgHWND :- Dialog window handle.
  684. //
  685. // Return Value: None
  686. //
  687. void DoUpdateDialogInfo (HWND aDlgHWND) {
  688. //Get the UPS data and for each item that's available display the appropriate
  689. //value and enable the associated controls. All other fields
  690. static const DWORD numRunningFields = DIMENSION_OF(g_DialogAssocs);
  691. static const DWORD numNoServiceFields = DIMENSION_OF(g_NoServiceControls);
  692. HWND hMessageControl = GetDlgItem(aDlgHWND, IDC_MESSAGE_TEXT);
  693. HWND hServiceControl = GetDlgItem(aDlgHWND, IDC_SERVICE_TEXT);
  694. DWORD dwUtilityStatus = 0;
  695. BOOL bIsUPSInstalled = IsUPSInstalled();
  696. //The IDC_MESSAGE_TEXT control contains default information in the
  697. //Static control in the dialog resource. This text message can be
  698. //changed to the "service not running" message, the "no comm" message
  699. //or the "press apply to commit" message depending on the current
  700. //state of the registry, the upsreg data buffer, the UPS service
  701. //and the status of the UPS communication. However, if conditions
  702. //dictate we want the original text from the control to be displayed.
  703. //For this reason we must store the original text so that the control
  704. //text can be set to this text without having to have the actual
  705. //text as a string resource.
  706. DoUpdateInfo(aDlgHWND,
  707. g_DialogAssocs,
  708. numRunningFields,
  709. (DWORD *) &g_NoServiceControls,
  710. numNoServiceFields,
  711. FALSE);
  712. //Now the IDC_MESSAGE_TEXT control may need to be changed to display different information.
  713. SelectServiceTextMessage(aDlgHWND, hMessageControl, hServiceControl);
  714. // Update the Power Source Icon
  715. if( (TRUE == IsUPSInstalled()) &&
  716. (TRUE == GetUPSDataItemDWORD(eREG_POWER_SOURCE, &dwUtilityStatus)) &&
  717. (UPS_UTILITYPOWER_OFF == dwUtilityStatus) )
  718. SendMessage(GetDlgItem(aDlgHWND, IDC_POWER_SOURCE_ICON),STM_SETICON,(WPARAM)g_hIconUPS,0);
  719. else
  720. SendMessage(GetDlgItem(aDlgHWND, IDC_POWER_SOURCE_ICON),STM_SETICON,(WPARAM)g_hIconPlug,0);
  721. //Finally if no UPS is installed then disable the IDB_CONFIGURE_SVC control otherwise
  722. //enable it.
  723. ManageConfigureButtonState(aDlgHWND);
  724. }
  725. //////////////////////////////////////////////////////////////////////////_/_//
  726. //////////////////////////////////////////////////////////////////////////_/_//
  727. // void SelectServiceTextMessage (HWND aDlgHWND, HWND aNoServiceControlHwnd, HWND aServiceControlHwnd);
  728. //
  729. // Description: This function changes the text displayed in the bottom half
  730. // of the UPS page. There are two control because the
  731. // IDC_SERVICE_TEXT control needs to be positioned to the left
  732. // of the "Configure..." button, while the other messages need
  733. // to be centered in the group box. The first control is not
  734. // as wide and is off centre. The second control is centered.
  735. // If the requirements were different this could have been
  736. // one control whose text changed.
  737. //
  738. // If the first control is visible, the second one is made
  739. // invisible, and vice versa, as their contents are mutually
  740. // exclusive.
  741. //
  742. // Additional Information:
  743. //
  744. // Parameters:
  745. //
  746. // HWND aNoServiceControlHwnd :- Handle to the IDC_MESSAGE_TEXT control.
  747. //
  748. // HWND aServiceControlHwnd :- Handle to the IDC_SERVICE_TEXT control.
  749. //
  750. // Return Value: None
  751. //
  752. void SelectServiceTextMessage (HWND aDlgHWND, HWND aNoServiceControlHwnd, HWND aServiceControlHwnd) {
  753. static BOOL bGotServiceTextMessages = FALSE;
  754. static TCHAR originalControlTextBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  755. static TCHAR noCommStringBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  756. static TCHAR pressApplyStringBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  757. static TCHAR noUPSInstalledStringBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  758. static HICON hInfoIcon;
  759. static HICON hWarningIcon;
  760. static HICON hErrorIcon;
  761. BOOL bShow = TRUE;
  762. DWORD commStatus = 0;
  763. BOOL bIsRunning = IsServiceRunning(UPS_SERVICE_NAME);
  764. BOOL bIsDataUpToDate = IsDataUpToDate();
  765. BOOL bIsUPSInstalled = IsUPSInstalled();
  766. BOOL bIsDataOK = IsDataOKToDisplay();
  767. DWORD dataState = GetActiveDataState();
  768. _ASSERT(aNoServiceControlHwnd != NULL);
  769. //Determine which control should be shown. Is it the "everything OK" control
  770. //or the second control that is used for all other messages.
  771. ShowWindow(aServiceControlHwnd, (bIsRunning == TRUE) &&
  772. (bIsDataUpToDate == TRUE) &&
  773. (bIsDataOK == TRUE) && FALSE ? SW_SHOW : SW_HIDE);
  774. //Get the strings if this is the first time into this function.
  775. if (bGotServiceTextMessages == FALSE) {
  776. // GetServiceTextMessages(aNoServiceControlHwnd, originalControlTextBuffer, DIMENSION_OF(originalControlTextBuffer),
  777. // IDS_COMM_LOST, noCommStringBuffer, DIMENSION_OF(noCommStringBuffer),
  778. // IDS_PRESS_APPLY, pressApplyStringBuffer, DIMENSION_OF(pressApplyStringBuffer),
  779. // IDS_NO_UPS_INSTALLED, noUPSInstalledStringBuffer, DIMENSION_OF(noUPSInstalledStringBuffer));
  780. bGotServiceTextMessages = TRUE;
  781. if (LoadString( GetUPSModuleHandle(),
  782. IDS_UPS_STOPPED,
  783. originalControlTextBuffer,
  784. DIMENSION_OF(originalControlTextBuffer)) > 0) {}
  785. if (LoadString( GetUPSModuleHandle(),
  786. IDS_COMM_LOST,
  787. noCommStringBuffer,
  788. DIMENSION_OF(noCommStringBuffer)) > 0) {}
  789. if (LoadString( GetUPSModuleHandle(),
  790. IDS_PRESS_APPLY,
  791. pressApplyStringBuffer,
  792. DIMENSION_OF(pressApplyStringBuffer)) > 0) {}
  793. if (LoadString( GetUPSModuleHandle(),
  794. IDS_NO_UPS_INSTALLED,
  795. noUPSInstalledStringBuffer,
  796. DIMENSION_OF(noUPSInstalledStringBuffer)) > 0) {}
  797. hInfoIcon = LoadImage(NULL,
  798. MAKEINTRESOURCE(IDI_INFORMATION),
  799. IMAGE_ICON,
  800. 0,0,
  801. LR_LOADMAP3DCOLORS | LR_SHARED);
  802. hWarningIcon = LoadImage(NULL,
  803. MAKEINTRESOURCE(IDI_WARNING),
  804. IMAGE_ICON,
  805. 0,0,
  806. LR_LOADMAP3DCOLORS | LR_SHARED);
  807. hErrorIcon = LoadImage(NULL,
  808. MAKEINTRESOURCE(IDI_ERROR),
  809. IMAGE_ICON,
  810. 0,0,
  811. LR_LOADMAP3DCOLORS | LR_SHARED);
  812. }
  813. //Determime which string to display in the second control.
  814. if( (bIsDataUpToDate == FALSE) ||
  815. (dataState & CONFIG_DATA_CHANGE) ) {
  816. ChangeTextIfDifferent(aNoServiceControlHwnd, pressApplyStringBuffer);
  817. SendMessage(GetDlgItem(aDlgHWND, IDC_MESSAGE_ICON),STM_SETICON,(WPARAM)hInfoIcon,0);
  818. }
  819. else if (bIsRunning == FALSE) {
  820. ChangeTextIfDifferent(aNoServiceControlHwnd, originalControlTextBuffer);
  821. SendMessage(GetDlgItem(aDlgHWND, IDC_MESSAGE_ICON),STM_SETICON,(WPARAM)hWarningIcon,0);
  822. }
  823. else if (GetUPSDataItemDWORD(eREG_COMM_STATUS, &commStatus) == TRUE) {
  824. if ((commStatus == UPS_COMMSTATUS_LOST) && (bIsRunning == TRUE)) {
  825. ChangeTextIfDifferent(aNoServiceControlHwnd, noCommStringBuffer);
  826. SendMessage(GetDlgItem(aDlgHWND, IDC_MESSAGE_ICON),STM_SETICON,(WPARAM)hErrorIcon,0);
  827. }//End Comm Lost
  828. else
  829. bShow = FALSE;
  830. }//end if GetUPSDataItemDWORD(eREG_COMM_STATUS...
  831. ShowWindow(GetDlgItem(aDlgHWND,IDC_MESSAGE_TEXT), bShow ? SW_SHOW : SW_HIDE);
  832. ShowWindow(GetDlgItem(aDlgHWND,IDC_MESSAGE_ICON), bShow ? SW_SHOW : SW_HIDE);
  833. }
  834. //////////////////////////////////////////////////////////////////////////_/_//
  835. //////////////////////////////////////////////////////////////////////////_/_//
  836. // void ChangeTextIfDifferent (HWND aWindowHandle, LPTSTR aBuffer);
  837. //
  838. // Description: This function set a window's text to the given value, unless
  839. // the window text is matches this string already in which case
  840. // the function does nothing.
  841. //
  842. // Additional Information:
  843. //
  844. // Parameters:
  845. //
  846. // HWND aWindowHandle :- Handle to a control.
  847. //
  848. // LPTSTR aBuffer :- Pointer to new window text. This parameter should not be
  849. // NULL, although it can point to an empty string.
  850. //
  851. // Return Value: None
  852. //
  853. void ChangeTextIfDifferent (HWND aWindowHandle, LPTSTR aBuffer) {
  854. TCHAR controlTextBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  855. DWORD controlTextBufferSize = DIMENSION_OF(controlTextBuffer);
  856. HICON hMsgIcon = NULL;
  857. _ASSERT(aWindowHandle != NULL);
  858. _ASSERT(aBuffer != NULL);
  859. // if (GetWindowText(aWindowHandle, controlTextBuffer, controlTextBufferSize) > 0) {
  860. GetWindowText(aWindowHandle, controlTextBuffer, controlTextBufferSize);
  861. if (_tcscmp(controlTextBuffer, aBuffer) != 0) {
  862. //Only set the window text if it has changed (reduces screen flicker).
  863. SetWindowText(aWindowHandle, aBuffer);
  864. }
  865. // }
  866. // else {
  867. // SetWindowText(aWindowHandle, aBuffer);
  868. // }
  869. }
  870. //////////////////////////////////////////////////////////////////////////_/_//
  871. //////////////////////////////////////////////////////////////////////////_/_//
  872. // void ManageConfigureButtonState (HWND aDlgHWND);
  873. //
  874. // Description: This "Configure..." button (IDB_CONFIGURE_SVC) should be
  875. // enabled only if a UPS is installed and the system is on AC Power.
  876. // This function enables
  877. // this button if a UPS is currently selected and disables
  878. // it if one isn't.
  879. //
  880. // The state of the Configure button reflects the state of
  881. // the "cached" values, not the actual committed registry
  882. // values.
  883. //
  884. // Additional Information:
  885. //
  886. // Parameters:
  887. //
  888. // HWND aDlgHWND :- A handle to the main UPS window.
  889. //
  890. // Return Value: None
  891. //
  892. void ManageConfigureButtonState (HWND aDlgHWND) {
  893. DWORD bIsUpgrade = 0;
  894. DWORD dwUtilityStatus = 0;
  895. HWND hControl = GetDlgItem(aDlgHWND, IDB_CONFIGURE_SVC);
  896. if (hControl != NULL)
  897. {
  898. BOOL bIsUPSInstalled = IsUPSInstalled();
  899. GetUPSConfigUpgrade(&bIsUpgrade);
  900. GetUPSDataItemDWORD(eREG_POWER_SOURCE, &dwUtilityStatus);
  901. if( !bIsUPSInstalled ||
  902. !g_bIsAdmin ||
  903. bIsUpgrade ||
  904. (UPS_UTILITYPOWER_OFF == dwUtilityStatus) )
  905. {
  906. EnableWindow(hControl, FALSE);
  907. }
  908. else
  909. {
  910. EnableWindow(hControl, TRUE);
  911. }
  912. }
  913. }
  914. //////////////////////////////////////////////////////////////////////////_/_//
  915. //////////////////////////////////////////////////////////////////////////_/_//
  916. // BOOL DoUpdateInfo (HWND aDlgHWND,
  917. // DialogAssociations * aDialogAssociationsArray,
  918. // DWORD aNumRunningFields,
  919. // BOOL aShowWindowBool);
  920. //
  921. // Description: This function updates the current information in the main
  922. // UPS page to reflect the current UPS status information.
  923. //
  924. // Additional Information:
  925. //
  926. // Parameters:
  927. //
  928. // HWND aDlgHWND :- A handle to the main UPS window.
  929. //
  930. // DialogAssociations * aDialogAssociationsArray :- Pointer to an array of
  931. // DialogAssociations's.
  932. //
  933. // DWORD aNumRunningFields :- This is the number of elements in the above array.
  934. //
  935. // BOOL aShowWindowBool :- Indicates whether the visibility of the
  936. // controls that have no data should be
  937. // affected. For the main UPS page the
  938. // visibility is not changed. For the
  939. // Advanced data the visibility is changed.
  940. //
  941. // Return Value: TRUE if any one of the data item has data associated with it.
  942. //
  943. BOOL DoUpdateInfo (HWND aDlgHWND,
  944. DialogAssociations * aDialogAssociationsArray,
  945. DWORD aNumRunningFields,
  946. DWORD * aNoServiceControlIDs,
  947. DWORD aNumNoServiceControls,
  948. BOOL aShowWindowBool) {
  949. //Get the UPS data and for each item that's available display the appropriate
  950. //value and enable the associated controls. All other fields
  951. TCHAR upsDataBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  952. TCHAR resourceStringBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  953. TCHAR controlBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  954. DWORD dwordValue = 0;
  955. DWORD i=0;
  956. DWORD firstControlID = 0;
  957. DWORD secondControlID = 0;
  958. HWND hFirstControl = NULL;
  959. HWND hSecondControl = NULL;
  960. LPVOID lppArgs[1];
  961. BOOL bShowField = FALSE;
  962. BOOL bIsDataOK = IsDataOKToDisplay();
  963. bIsDataOK &= IsDataUpToDate();
  964. //Display/hide the NO service controls and hide/display all the
  965. //DialogAssociations fields.
  966. for (i=0; i<aNumNoServiceControls; i++) {
  967. HWND hNoServiceControl = GetDlgItem(aDlgHWND, *(aNoServiceControlIDs + i));
  968. ShowWindow(hNoServiceControl, SW_SHOW);
  969. // ShowWindow(hNoServiceControl, !bIsDataOK ? SW_SHOW : SW_HIDE);
  970. }
  971. for (i=0; i<aNumRunningFields; i++) {
  972. DialogAssociations * pCurrentEntryDetails = aDialogAssociationsArray + i;
  973. DWORD upsDataBufSize = DIMENSION_OF(upsDataBuffer);
  974. DWORD resStringBufSize = DIMENSION_OF(resourceStringBuffer);
  975. DWORD fieldID = (DWORD) pCurrentEntryDetails->theFieldTypeID;
  976. RegField * pRegField = GetRegField(fieldID);
  977. BOOL bGotData = FALSE;
  978. BOOL bValueSupported = TRUE;
  979. lppArgs[0] = (VOID *) 0;
  980. if (pRegField != NULL) {
  981. #ifdef _DEBUG
  982. {
  983. //If pCurrentEntryDetails->theResourceStringType is of type RESOURCE_INCREMENT
  984. //then pRegField->theValueType must be some DWORD type
  985. if (pCurrentEntryDetails->theResourceStringType == RESOURCE_INCREMENT) {
  986. DWORD allowedTypesDbg = REG_ANY_DWORD_TYPE;
  987. _ASSERT((pRegField->theValueType & allowedTypesDbg) == pRegField->theValueType);
  988. }
  989. }
  990. #endif
  991. if (pCurrentEntryDetails->theRegAccessType == eDeepGet) {
  992. if (bIsDataOK == TRUE) {
  993. if ((pRegField->theValueType & (REG_SZ | REG_EXPAND_SZ)) == pRegField->theValueType) {
  994. bGotData = GetUPSDataItemString(fieldID, upsDataBuffer, &upsDataBufSize);
  995. lppArgs[0] = (VOID *) (LPCTSTR) upsDataBuffer;
  996. }
  997. else {
  998. #ifdef _DEBUG
  999. {
  1000. DWORD allowedTypesDbg = REG_ANY_DWORD_TYPE;
  1001. _ASSERT((pRegField->theValueType & allowedTypesDbg) == pRegField->theValueType);
  1002. }
  1003. #endif
  1004. if ((bGotData = GetUPSDataItemDWORD(fieldID, &dwordValue)) == TRUE) {
  1005. //Need some special handling here if the
  1006. if (pCurrentEntryDetails->theResourceStringType == RESOURCE_INCREMENT) {
  1007. //This DWORD value represents an offset into the resource string table
  1008. //to identify a string that is to be displayed, not a DWORD value
  1009. //If the index is 0 then the value is unknown and the associated
  1010. //fields are shown disabled. 0 is a special case that will do this
  1011. //for all fields of this type.
  1012. DWORD realResID = 0;
  1013. //If the given value is greater than the given maximum value
  1014. //then the field is "not supported" and the associated
  1015. //fields are hidden.
  1016. if (dwordValue > pCurrentEntryDetails->theResourceIndexMax) {
  1017. bValueSupported = FALSE;
  1018. bGotData = FALSE;
  1019. }
  1020. else if (dwordValue == 0) {
  1021. bGotData = FALSE;
  1022. }
  1023. else {
  1024. realResID = pCurrentEntryDetails->theResourceIndexID + dwordValue;
  1025. if (LoadString(GetUPSModuleHandle(),
  1026. realResID,
  1027. upsDataBuffer,
  1028. upsDataBufSize) > 0) {
  1029. lppArgs[0] = (VOID *) (LPCTSTR) upsDataBuffer;
  1030. }
  1031. }
  1032. }
  1033. else {
  1034. lppArgs[0] = IntToPtr(dwordValue);
  1035. //If the value of a regular number field is 0 then it is not supported.
  1036. if (dwordValue == 0) {
  1037. bGotData = FALSE;
  1038. }
  1039. }
  1040. }
  1041. }
  1042. }//end bIsDataOK
  1043. }
  1044. else {
  1045. _ASSERT(pCurrentEntryDetails->theRegAccessType == eShallowGet);
  1046. _ASSERT((pCurrentEntryDetails->theShallowAccessFunctionPtr == getDwordValue) ||
  1047. (pCurrentEntryDetails->theShallowAccessFunctionPtr == getStringValue));
  1048. _ASSERT(pCurrentEntryDetails->theRegEntryPtr != 0);
  1049. if (pCurrentEntryDetails->theShallowAccessFunctionPtr == getDwordValue) {
  1050. if (getDwordValue(pCurrentEntryDetails->theRegEntryPtr, &dwordValue) == ERROR_SUCCESS) {
  1051. lppArgs[0] = IntToPtr(dwordValue);
  1052. bGotData = TRUE;
  1053. }
  1054. }
  1055. else {
  1056. if (getStringValue(pCurrentEntryDetails->theRegEntryPtr, upsDataBuffer) == ERROR_SUCCESS) {
  1057. lppArgs[0] = (VOID *) (LPCTSTR) upsDataBuffer;
  1058. bGotData = TRUE;
  1059. }
  1060. }
  1061. }
  1062. //If bGotData == TRUE then the field was active in the registry and we react accordingly
  1063. //by enabling the associated controls.
  1064. firstControlID = pCurrentEntryDetails->theStaticFieldID;
  1065. secondControlID = pCurrentEntryDetails->theDisplayControlID;
  1066. hFirstControl = GetDlgItem(aDlgHWND, firstControlID);
  1067. hSecondControl = GetDlgItem(aDlgHWND, secondControlID);
  1068. _ASSERT(firstControlID > 0);
  1069. _ASSERT(secondControlID > 0);
  1070. _ASSERT(hFirstControl != NULL);
  1071. _ASSERT(hSecondControl != NULL);
  1072. EnableWindow(hFirstControl, bGotData);
  1073. EnableWindow(hSecondControl, bGotData);
  1074. if (bValueSupported == FALSE) {
  1075. ShowWindow(hFirstControl, bValueSupported ? SW_SHOW : SW_HIDE);
  1076. ShowWindow(hSecondControl, bValueSupported ? SW_SHOW : SW_HIDE);
  1077. }
  1078. if (aShowWindowBool == TRUE) {
  1079. ShowWindow(hFirstControl, bGotData ? SW_SHOW : SW_HIDE);
  1080. ShowWindow(hSecondControl, bGotData ? SW_SHOW : SW_HIDE);
  1081. }
  1082. if (bGotData == TRUE) {
  1083. bShowField = TRUE;
  1084. //Now we want to form the string to display.
  1085. if (GetMessageFromStringTable(pCurrentEntryDetails->theResourceInsertID,
  1086. lppArgs,
  1087. resourceStringBuffer,
  1088. &resStringBufSize) == ERROR_SUCCESS) {
  1089. if (GetWindowText(hSecondControl, controlBuffer, DIMENSION_OF(controlBuffer)) > 0) {
  1090. if (_tcscmp(controlBuffer, resourceStringBuffer) != 0) {
  1091. SetWindowText(hSecondControl, resourceStringBuffer);
  1092. }
  1093. }
  1094. else {
  1095. SetWindowText(hSecondControl, resourceStringBuffer);
  1096. }
  1097. }
  1098. #ifdef _DEBUG
  1099. else {
  1100. //An unexpected error occurred. The number of parameters identified
  1101. //in the resource string and the number passed may not match
  1102. _ASSERT(FALSE);
  1103. }
  1104. #endif
  1105. }
  1106. else {
  1107. //Empty the contents of the second control
  1108. SetWindowText(hSecondControl, TEXT(""));
  1109. }
  1110. }
  1111. }//end for
  1112. return(bShowField);
  1113. }
  1114. //////////////////////////////////////////////////////////////////////////_/_//
  1115. //////////////////////////////////////////////////////////////////////////_/_//
  1116. // BOOL IsDataOKToDisplay (void);
  1117. //
  1118. // Description: This function determines how suitable it is to display the
  1119. // UPS status information. The UPS statius information is only
  1120. // accurate if the service is running and communication exists
  1121. // between the UPS service and the UPS. If this is not the
  1122. // case then this function returns FALSE.
  1123. //
  1124. // Additional Information:
  1125. //
  1126. // Parameters: None
  1127. //
  1128. // Return Value: Returns TRUE if it is OK to display UPS status information.
  1129. //
  1130. BOOL IsDataOKToDisplay (void) {
  1131. BOOL bIsRunning = IsServiceRunning(UPS_SERVICE_NAME);
  1132. DWORD commStatus = 0;
  1133. BOOL bIsCommEstablished = FALSE;
  1134. BOOL bIsDataOK = bIsRunning;
  1135. if (GetUPSDataItemDWORD(eREG_COMM_STATUS, &commStatus) == TRUE) {
  1136. if (commStatus == 1) {
  1137. bIsCommEstablished = TRUE;
  1138. }
  1139. bIsDataOK &= bIsCommEstablished;
  1140. }
  1141. return(bIsDataOK);
  1142. }
  1143. //////////////////////////////////////////////////////////////////////////_/_//
  1144. //////////////////////////////////////////////////////////////////////////_/_//
  1145. // BOOL IsDataUpToDate (void);
  1146. //
  1147. // Description: If the user changes the vendor, model or COM port then
  1148. // the main UPS page should not display the UPS status
  1149. // information.
  1150. //
  1151. // Additional Information:
  1152. //
  1153. // Parameters: None
  1154. //
  1155. // Return Value: This function returns FALSE if the values currently stored in
  1156. // the registry for vendor, model, or port differs from the
  1157. // "internal" values (that is the value stored in the upsreg
  1158. // buffers, see upsreg.h and upsreg.c).
  1159. //
  1160. BOOL IsDataUpToDate (void) {
  1161. //if the Vendor or Model Type or Port in the registry differs from
  1162. //upsreg value then the data is out of sync.
  1163. TCHAR vendorBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  1164. DWORD vendorBufferSize = DIMENSION_OF(vendorBuffer);
  1165. TCHAR modelBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  1166. DWORD modelBufferSize = DIMENSION_OF(modelBuffer);
  1167. TCHAR portBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  1168. DWORD portBufferSize = DIMENSION_OF(portBuffer);
  1169. TCHAR vendorOtherBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  1170. TCHAR modelOtherBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  1171. TCHAR portOtherBuffer[MAX_MESSAGE_LENGTH] = TEXT("");
  1172. GetUPSDataItemString(eREG_VENDOR_NAME, vendorBuffer, &vendorBufferSize);
  1173. GetUPSConfigVendor(vendorOtherBuffer);
  1174. GetUPSDataItemString(eREG_MODEL_TYPE, modelBuffer, &modelBufferSize);
  1175. GetUPSConfigModel(modelOtherBuffer);
  1176. GetUPSDataItemString(eREG_PORT, portBuffer, &portBufferSize);
  1177. GetUPSConfigPort(portOtherBuffer);
  1178. return((_tcscmp(vendorBuffer, vendorOtherBuffer) == 0) &&
  1179. (_tcscmp(modelOtherBuffer, modelBuffer) == 0) &&
  1180. (_tcscmp(portBuffer, portOtherBuffer) == 0));
  1181. }
  1182. /*******************************************************************************
  1183. *
  1184. * IsUpsPresent
  1185. *
  1186. * DESCRIPTION: This function gets called to determine if UPS is present
  1187. * and should be displayed in a tab. For now this functions
  1188. * returns TRUE
  1189. *
  1190. * RETURNS: TRUE if UPS is present, FALSE if UPS is no present
  1191. *
  1192. *
  1193. *******************************************************************************/
  1194. BOOLEAN IsUpsPresent(PSYSTEM_POWER_CAPABILITIES pspc)
  1195. {
  1196. BOOLEAN UpsPresent;
  1197. DWORD dwShowTab;
  1198. TCHAR szImagePath[MAX_PATH];
  1199. InitUPSConfigBlock();
  1200. if ((ERROR_SUCCESS == GetUPSConfigShowUPSTab(&dwShowTab)) && dwShowTab) {
  1201. UpsPresent = TRUE;
  1202. } else if (pspc->SystemBatteriesPresent) {
  1203. UpsPresent = FALSE;
  1204. } else if (!(ERROR_SUCCESS == GetUPSConfigImagePath(szImagePath))) {
  1205. UpsPresent = TRUE;
  1206. } else if (!_tcsicmp(DEFAULT_CONFIG_IMAGEPATH, szImagePath)) {
  1207. UpsPresent = TRUE;
  1208. } else {
  1209. UpsPresent = FALSE;
  1210. }
  1211. return(UpsPresent);
  1212. }
  1213. //
  1214. // Kill the 1-second update timer.
  1215. //
  1216. DWORD KillUpdateTimer(HWND hwnd)
  1217. {
  1218. if (0 != g_UpdateTimerID)
  1219. {
  1220. KillTimer(hwnd, g_UpdateTimerID);
  1221. g_UpdateTimerID = 0;
  1222. }
  1223. return ERROR_SUCCESS;
  1224. }
  1225. //
  1226. // Create the 1-second update timer.
  1227. //
  1228. DWORD SetUpdateTimer(HWND hwnd)
  1229. {
  1230. DWORD dwResult = ERROR_SUCCESS;
  1231. KillUpdateTimer(hwnd);
  1232. g_UpdateTimerID = SetTimer(hwnd, cUpdateTimerID, 1000, NULL);
  1233. if (0 == g_UpdateTimerID)
  1234. {
  1235. dwResult = GetLastError();
  1236. }
  1237. return dwResult;
  1238. }