/******************************************************************************* * * Copyright 1999 American Power Conversion, All Rights Reserved * * TITLE: UPSTAB.C * * VERSION: 1.0 * * AUTHOR: PaulB * * DATE: 07 June, 1999 * * DESCRIPTION: This file contains the main body of code for the UPS Tab. * This dialog procedure is implemented in this file, along with * some of the support functions. * *******************************************************************************/ #include #include #include #include #include #include "upstab.h" #include "..\powercfg.h" #include "..\pwrresid.h" #include "..\PwrMn_cs.h" #pragma hdrstop // data /////////////////////////////////////////////////////////////////////////////// HWND g_hwndDlg = 0; HICON g_hIconUPS = 0; HICON g_hIconPlug = 0; // context-sensitive help table const DWORD g_UPSPageHelpIDs[]= { IDC_STATIC, NO_HELP, IDC_STATUS_GROUPBOX, NO_HELP, IDC_POWER_SOURCE_ICON, idh_current_power_source, IDC_POWER_SOURCE_LHS, idh_current_power_source, IDC_POWER_SOURCE, idh_current_power_source, IDC_RUNTIME_REMAINING_LHS, idh_estimated_ups_runtime, IDC_RUNTIME_REMAINING, idh_estimated_ups_runtime, IDC_BATTERY_CAPACITY_LHS, idh_estimated_ups_capacity, IDC_BATTERY_CAPACITY, idh_estimated_ups_capacity, IDC_BATTERY_STATUS_LHS, idh_battery_condition, IDC_BATTERY_STATUS, idh_battery_condition, IDC_DETAILS_GROUPBOX, NO_HELP, IDB_UPS_ICON_BUTTON, idh_apc_logo_link, IDC_VENDOR_NAME_LHS, idh_manufacturer, IDC_VENDOR_NAME, idh_manufacturer, IDC_MODEL_TYPE_LHS, idh_model, IDC_MODEL_TYPE, idh_model, IDB_INSTALL_UPS, idh_select_ups, IDB_CONFIGURE_SVC, idh_configure_ups, IDC_MESSAGE_ICON, NO_HELP, IDC_MESSAGE_TEXT, NO_HELP, IDC_APC1, NO_HELP, IDC_APC2, NO_HELP, IDB_APCLOGO_SMALL, NO_HELP, 0, 0 }; // data /////////////////////////////////////////////////////////////////////////////// extern struct _reg_entry UPSConfigVendor; extern struct _reg_entry UPSConfigModel; //static LPCTSTR cUPSStateFormatString = TEXT("%s %s"); static UINT_PTR g_UpdateTimerID = 0; static const DWORD cUpdateTimerID = 100; static BOOL g_bIsAdmin = TRUE; // functions /////////////////////////////////////////////////////////////////////////////// static DWORD FormatMessageText (LPCTSTR aFormatString, LPVOID * alpDwords, LPTSTR aMessageBuffer, DWORD * aBufferSizePtr); static BOOL UPSMainPageHandleInit (HWND aDlgHWND, WPARAM wParam, LPARAM lParam); static BOOL UPSMainPageHandleCommand (HWND aDlgHWND, WPARAM wParam, LPARAM lParam); static BOOL UPSMainPageHandleNotify (HWND aDlgHWND, WPARAM wParam, LPARAM lParam); //All these functions are commented in the source file updatdlg.c static BOOL UPSMainPageHandleDestroy (HWND hDlg, WPARAM wParam, LPARAM lParam); static BOOL CreateUPSIconButton(HWND hDlg, HICON aUPSIconHandle); static void DoUpdateDialogInfo (HWND hDlg); static void ManageConfigureButtonState (HWND hDlg); DWORD SetUpdateTimer(HWND hwnd); DWORD KillUpdateTimer(HWND hwnd); /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL CALLBACK UPSMainPageProc (HWND aDlgHWND, // UINT aMsgID, // WPARAM wParam, // LPARAM lParam); // // Description: This is a standard DialogProc associated with the UPS tab dialog. // // Additional Information: See help on // \DialogProc\ // // Parameters: // // HWND aDlgHWND :- Handle to dialog box // // UINT aMsgID :- message ID // // WPARAM wParam :- Specifies additional message-specific information. // // LPARAM lParam :- Specifies additional message-specific information. // // Return Value: Except in response to the WM_INITDIALOG message, the dialog // box procedure should return nonzero if it processes the // message, and zero if it does not. // INT_PTR CALLBACK UPSMainPageProc (HWND aDlgHWND, UINT aMsgID, WPARAM wParam, LPARAM lParam) { BOOL bRet = TRUE; switch (aMsgID) { case WM_INITDIALOG: { //The dialog box procedure should return TRUE to direct the system to //set the keyboard focus to the control given by wParam. bRet = UPSMainPageHandleInit(aDlgHWND, wParam, lParam); break; } case WM_COMMAND: { //If an application processes this message, it should return zero. bRet = UPSMainPageHandleCommand(aDlgHWND, wParam, lParam); break; } case WM_NOTIFY: { bRet = UPSMainPageHandleNotify(aDlgHWND, wParam, lParam); break; } case WM_TIMER: { //If an application processes this message, it should return zero. DoUpdateDialogInfo(aDlgHWND); bRet = FALSE; break; } case WM_HELP: { //Help for WM_HELP says: Returns TRUE bRet = WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_UPSPageHelpIDs); break; } case WM_CONTEXTMENU: { // right mouse click // // Kill the update timer while context help is active. // Otherwise the code in the timer handler interferes with the help UI. // KillUpdateTimer(aDlgHWND); bRet = WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_UPSPageHelpIDs); SetUpdateTimer(aDlgHWND); break; } case WM_DESTROY: { //An application returns 0 if it processes WM_DESTROY bRet = UPSMainPageHandleDestroy(aDlgHWND, wParam, lParam); break; } default: { bRet = FALSE; break; } } // switch (aMsgID) return(bRet); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL UPSMainPageHandleInit (HWND aDlgHWND, // WPARAM wParam, // LPARAM lParam); // // Description: This is the handler function for WM_INITDIALOG. It creates the // tooltip window, initialize the controls and creates the update // timer. // // Additional Information: // // Parameters: // // HWND aDlgHWND :- Identifies the dialog box. // // WPARAM wParam :- Handle of control to receive focus // // LPARAM lParam :- Initialization parameter // // Return Value: The dialog box procedure should return TRUE to direct the // system to set the keyboard focus to the control given by // wParam. // BOOL UPSMainPageHandleInit (HWND aDlgHWND, WPARAM wParam, LPARAM lParam) { /* * The dialog is being created. By default many of the controls in the UPS * page will appear disabled. If there is no data to display then this is * the required behavior. We need to get the UPS data. When an individual * data item is retrieved we then enable the field associated with that data * item. If the data item is not available we disabled the field. We have * to disable even though in this case the field is already disabled * due to the fact that it's disabled in the RC file and we are in startup. * But this same code is used in the "Refresh" scenario, requiring the the * status of the field be able to be changed from enabled to disabled. */ static BOOL bIsInitialized = FALSE; TCHAR szVendorName[MAX_PATH] = _T(""); TCHAR szModelName[MAX_PATH] = _T(""); g_hwndDlg = aDlgHWND; /* * Determine if the registry needs to be initialized for the UPS service. * if it is already initialized, do nothing */ g_bIsAdmin = InitializeRegistry(); /* * Disable or hide the configure and select buttons depending on * whether or not we can write to the registry. */ EnableWindow( GetDlgItem( aDlgHWND, IDB_INSTALL_UPS ), g_bIsAdmin ); EnableWindow( GetDlgItem( aDlgHWND, IDB_CONFIGURE_SVC ), g_bIsAdmin ); InitializeApplyButton(aDlgHWND); // Load icon images for Power Source and UPS Info button g_hIconUPS = LoadImage(GetUPSModuleHandle(), MAKEINTRESOURCE(IDI_UPS), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS | LR_SHARED); g_hIconPlug = LoadImage(GetUPSModuleHandle(), MAKEINTRESOURCE(IDI_PLUG), IMAGE_ICON, 0, 0, LR_LOADMAP3DCOLORS | LR_SHARED); if( NULL != g_hIconUPS ) CreateUPSIconButton(aDlgHWND, g_hIconUPS); // Init the Registry info blocks ONCE if (!bIsInitialized) { InitUPSConfigBlock(); InitUPSStatusBlock(); bIsInitialized = TRUE; } /* * NOTE: * This is a workaround to fix previously hard-coded default * strings in upsreg.c If the Vendor Name is null then we assume * that we should apply * default values from the resource file */ GetUPSConfigVendor( szVendorName); GetUPSConfigModel( szModelName); /* * The function IsUPSInstalled assumes the config * block has been initialized. */ if (!_tcsclen(szVendorName) && IsUPSInstalled()) { // Get the "Generic" vendor name from the resource file. LoadString(GetUPSModuleHandle(), IDS_OTHER_UPS_VENDOR, (LPTSTR) szVendorName, sizeof(szVendorName)/sizeof(TCHAR)); // Get the "Custom" model name from the resource file. LoadString(GetUPSModuleHandle(), IDS_CUSTOM_UPS_MODEL, (LPTSTR) szModelName, sizeof(szModelName)/sizeof(TCHAR)); SetUPSConfigVendor( szVendorName); SetUPSConfigModel( szModelName); SaveUPSConfigBlock(FALSE); } if (!_tcsclen(szVendorName) && !IsUPSInstalled()) { // Get the "No UPS" vendor name from the resource file. LoadString(GetUPSModuleHandle(), IDS_NO_UPS_VENDOR, (LPTSTR) szVendorName, sizeof(szVendorName)/sizeof(TCHAR)); SetUPSConfigVendor( szVendorName); SaveUPSConfigBlock(FALSE); } DoUpdateDialogInfo(aDlgHWND); SetUpdateTimer(aDlgHWND); return(FALSE); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL UPSMainPageHandleCommand (HWND aDlgHWND, // WPARAM wParam, // LPARAM lParam); // // Description: This is the handler function for WM_COMMAND. // // Additional Information: See help on WM_COMMAND // // Parameters: // // HWND aDlgHWND :- Handle to dialog box // // WPARAM wParam :- HIWORD(wParam) gives the notification code. // LOWORD(wParam) gives the control id. // // LPARAM lParam :- Gives the HWND or handle of the control. // // Return Value: If an application processes this message, it should return 0. // BOOL UPSMainPageHandleCommand (HWND aDlgHWND, WPARAM wParam, LPARAM lParam) { switch (LOWORD(wParam)) {// control ID case IDB_INSTALL_UPS: { DialogBoxParam( GetUPSModuleHandle(), MAKEINTRESOURCE(IDD_UPSSELECT), aDlgHWND, UPSSelectDlgProc, (LPARAM) aDlgHWND); break; } case IDB_UPS_ICON_BUTTON: { DisplayUPSInfoDialogBox(aDlgHWND); break; } case IDC_APC1: case IDC_APC2: case IDB_APCLOGO_SMALL: { DisplayAboutDialogBox(aDlgHWND); break; } case IDB_CONFIGURE_SVC: { DialogBoxParam( GetUPSModuleHandle(), MAKEINTRESOURCE(IDD_UPSCONFIGURATION), aDlgHWND, UPSConfigDlgProc, (LPARAM) aDlgHWND); break; } default: { break; } }//end switch //If an application processes this message, it should return zero. return(FALSE); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL UPSMainPageHandleNotify (HWND aDlgHWND, // WPARAM wParam, // LPARAM lParam); // // Description: Sent by a common control to its parent window when an event has // occurred in the control or the control requires some kind of // information. // // Additional Information: See help on NMHDR // // Parameters: // // HWND aDlgHWND :- Handle to dialog box // // WPARAM wParam :- Identifier of the common control sending the message. // // LPARAM lParam :- Address of an NMHDR structure that contains the // notification code and additional information. // // Return Value: If an application processes this message, it should return 0. // BOOL UPSMainPageHandleNotify (HWND aDlgHWND, WPARAM wParam, LPARAM lParam) { LPNMHDR pnmhdr = (LPNMHDR) lParam; UINT uNotify = pnmhdr->code; BOOL bWait = FALSE; switch(uNotify) { case PSN_APPLY: { DWORD dataState = GetActiveDataState(); /* * Indicates that the user clicked the OK or Apply button and wants * all changes to take effect. * A page should not call the EndDialog function when processing this * notification message. */ // Has anything changed? Do nothing otherwise. if (DATA_NO_CHANGE != dataState) { // Yes - make changes permanent SetUPSConfigUpgrade(FALSE); // this really only needs to be done the first time, but... SaveUPSConfigBlock(FALSE); SetWindowLongPtr(aDlgHWND, DWLP_MSGRESULT, PSNRET_NOERROR); // Did the service data change? if ((dataState & SERVICE_DATA_CHANGE) == SERVICE_DATA_CHANGE) { // Yes - need to restart the service for the changes to take effect StopService(UPS_SERVICE_NAME); // Stop the service if it's running ConfigureService(IsUPSInstalled()); // Set the UPS service to automatic or manual // Was the change that No UPS is installed? if (IsUPSInstalled() == TRUE) { // if (StartOffService(UPS_SERVICE_NAME, TRUE) == FALSE) { // If OK was selected this will stop the applet from closing // so that you can see that the service didn't start properly. SetWindowLongPtr(aDlgHWND, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); // Since we've committed our changes, disable the Apply button. PropSheet_UnChanged(GetParent(aDlgHWND), aDlgHWND); } } } SetActiveDataState(DATA_NO_CHANGE); } break; } case PSN_RESET: { //Notifies a page that the user has clicked the Cancel button and the //property sheet is about to be destroyed. break; } default: return(FALSE); }//end switch return(TRUE); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL IsUPSInstalled (void); // // Description: This function checks the "internal" values to determine if a // UPS is installed or not. // // Additional Information: // // Parameters: None // // Return Value: Returns TRUE if a UPS is installed, FALSE otherwise. // BOOL IsUPSInstalled (void) { BOOL bIsInstalled = FALSE; DWORD options = 0; if (GetUPSConfigOptions(&options) == ERROR_SUCCESS) { //If Options includes UPS_INSTALLED if ((options & UPS_INSTALLED) == UPS_INSTALLED) { bIsInstalled = TRUE; } } else { //The Options value should exist at this stage, or something is wrong //with SaveUPSConfigBlock() _ASSERT(FALSE); } return(bIsInstalled); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // DWORD FormatMessageText (LPCTSTR aFormatString, // LPVOID * alpDwords, // LPTSTR aMessageBuffer, // DWORD * aBufferSizePtr); // // Description: This function wraps FormatMessage and is used to put inserts // into a given string. The inserts must be stored in an array of // 32-bit values that represent the arguments. // // Additional Information: FormatMessage // // Parameters: // // LPCTSTR aFormatString :- Pointer to the format string containing inserts // of the form %1, %2 etc. // // LPVOID * alpDwords :- A pointer to an array of 32-bit values that // represent the arguments. // // LPTSTR aMessageBuffer :- Buffer to which the fully formatted string is // written, if successful. // // DWORD * aBufferSizePtr :- Pointer to a DWORD that holds the size of the // buffer to write to. If this function returns // successfully this will contain the number // of bytes written. // // Return Value: Function returns ERROR_SUCCESS on success and a Win32 error // code if an error occurs. // DWORD FormatMessageText (LPCTSTR aFormatString, LPVOID * alpDwords, LPTSTR aMessageBuffer, DWORD * aBufferSizePtr) { LPTSTR lpBuf = NULL; // Will Hold text of the message (allocated by FormatMessage DWORD errStatus = ERROR_SUCCESS; DWORD numChars = 0; if ((numChars = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, (LPCVOID) aFormatString, 0, 0, (LPTSTR) &lpBuf, MAX_MESSAGE_LENGTH, (va_list *)alpDwords)) == 0) { *aBufferSizePtr = 0; *aMessageBuffer = TEXT('\0'); } else { if (aBufferSizePtr != NULL) { if (numChars < *aBufferSizePtr) { //the given buffer is big enough to hold the string if (aMessageBuffer != NULL) { _tcscpy(aMessageBuffer, lpBuf); } } *aBufferSizePtr = numChars; } LocalFree(lpBuf); } return(errStatus); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // DWORD GetMessageFromStringTable (DWORD aMessageID, // LPVOID * alpDwords, // LPTSTR aMessageBuffer, // DWORD * aBufferSizePtr); // // Description: This function reads a string resource from the resource table // inserting the given string inserts. // // Additional Information: // // Parameters: // // DWORD aMessageID :- Message ID of the string resource to get. // // LPVOID * alpDwords :- A pointer to an array of 32-bit values that // represent the arguments. // // LPTSTR aMessageBuffer :- Buffer to which the fully formatted string is // written, if successful. // // DWORD * aBufferSizePtr :- Pointer to a DWORD that holds the size of the // buffer to write to. If this function returns // successfully this will contain the number // of bytes written. // // Return Value: Function returns ERROR_SUCCESS on success and a Win32 error // code if an error occurs. // DWORD GetMessageFromStringTable (DWORD aMessageID, LPVOID * alpDwords, LPTSTR aMessageBuffer, DWORD * aBufferSizePtr) { TCHAR resourceTemplateString[MAX_MESSAGE_LENGTH] = TEXT(""); DWORD resStringBufSize = DIMENSION_OF(resourceTemplateString); HMODULE hUPSModule = GetUPSModuleHandle(); DWORD errStatus = ERROR_INVALID_PARAMETER; if (LoadString(hUPSModule, aMessageID, resourceTemplateString, resStringBufSize) > 0) { //Now we have the resource string errStatus = FormatMessageText(resourceTemplateString, alpDwords, aMessageBuffer, aBufferSizePtr); } return(errStatus); } // UPDATDLG.C // static data /////////////////////////////////////////////////////////////////////////////// static DialogAssociations g_DialogAssocs[] = { MAKE_ARRAY ( VENDOR_NAME, IDS_STRING, IDS_STRING, RESOURCE_FIXED, 0, eShallowGet, getStringValue, &UPSConfigVendor), MAKE_ARRAY ( MODEL_TYPE, IDS_STRING, IDS_STRING, RESOURCE_FIXED, 0, eShallowGet, getStringValue, &UPSConfigModel), MAKE_ARRAY ( POWER_SOURCE, IDS_STRING, IDS_UTILITYPOWER_UNKNOWN, RESOURCE_INCREMENT, 2, eDeepGet, 0, 0), MAKE_ARRAY ( RUNTIME_REMAINING, IDS_RUNTIME_REMAINING, IDS_STRING, RESOURCE_FIXED, 0, eDeepGet, 0, 0), MAKE_ARRAY ( BATTERY_CAPACITY, IDS_CAPACITY, IDS_STRING, RESOURCE_FIXED, 0, eDeepGet, 0, 0), MAKE_ARRAY ( BATTERY_STATUS, IDS_STRING, IDS_BATTERYSTATUS_UNKNOWN, RESOURCE_INCREMENT, 2, eDeepGet, 0, 0) }; static DWORD g_NoServiceControls[] = { IDC_MESSAGE_TEXT }; // functions /////////////////////////////////////////////////////////////////////////////// static void SelectServiceTextMessage (HWND aDlgHWND, HWND aNoServiceControlHwnd, HWND aServiceControlHwnd); static void ChangeTextIfDifferent (HWND aWindowHandle, LPTSTR aBuffer); //static void GetServiceTextMessages (HWND aNoServiceControlHwnd, LPTSTR aOriginalTextBuffer, DWORD aOriginalTextBufferSize, // DWORD aCommListStringID, LPTSTR aCommStringBuffer, DWORD aCommStringBufferSize, // DWORD aPressApplyStringID, LPTSTR aPressApplyStringBuffer, DWORD aPressApplyStringBufferSize, // DWORD aNoUPSStringID, LPTSTR aNoUPSInstalledStringBuffer, DWORD aNoUPSInstalledStringBufferSize); //static void GetServiceTextMessage (DWORD aStringID, LPTSTR aBuffer, DWORD aBufferSize); static BOOL IsDataOKToDisplay (void); static BOOL IsDataUpToDate (void); /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // void UPSMainPageHandleDestroy (HWND aDlgHWND, // WPARAM wParam, // LPARAM lParam); // // Description: This function is called when the UPS page is being destroyed. // It is responsible for any cleanup that is required. // // Additional Information: See KillTimer // // Parameters: // // HWND aDlgHWND :- Dialog window handle. // // WPARAM wParam :- Specifies additional message-specific information. // For WM_DESTROY this parameter is ignored. // // LPARAM lParam :- Specifies additional message-specific information. // For WM_DESTROY this parameter is ignored. // // Return Value: An application returns 0 if it processes WM_DESTROY // BOOL UPSMainPageHandleDestroy (HWND aDlgHWND, WPARAM wParam, LPARAM lParam) { // deallocate the registry block memory FreeUPSConfigBlock(); FreeUPSStatusBlock(); KillUpdateTimer(aDlgHWND); //An application returns 0 if it processes WM_DESTROY return(FALSE); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL CreateUPSIconButton (HWND aDlgHWND, HICON aUPSIconHandle); // // Description: Creates the small UPS icon button on the UPS page. // // Additional Information: // // Parameters: // // HWND aDlgHWND :- Dialog window handle. // // HICON aUPSIconHandle :- Handle to the icon to display in the button. // // Return Value: Returns TRUE. // BOOL CreateUPSIconButton (HWND aDlgHWND, HICON aUPSIconHandle) { HWND hAPCLogoButton = GetDlgItem(aDlgHWND, IDB_UPS_ICON_BUTTON); POINT pt = { 0, 0 }; ICONINFO info; BITMAP bm; _ASSERT(aDlgHWND != NULL); _ASSERT(aUPSIconHandle != NULL); _ASSERT(hAPCLogoButton != NULL); ZeroMemory(&info, sizeof(ICONINFO)); if (GetIconInfo(aUPSIconHandle, &info) == TRUE) { //Now determine the size of the icon's color bitmap _ASSERT(info.fIcon == TRUE); _ASSERT(info.hbmColor != NULL); ZeroMemory(&bm, sizeof(BITMAP)); if (GetObject(info.hbmColor, sizeof(BITMAP), &bm) != 0) { pt.x = bm.bmWidth; pt.y = bm.bmHeight; } //GetIconInfo creates bitmaps for the hbmMask and hbmColor members of //ICONINFO. The calling application must manage these bitmaps and delete //them when they are no longer necessary. DeleteObject(info.hbmColor); DeleteObject(info.hbmMask); } //Resize the button control. SetWindowPos(hAPCLogoButton, HWND_NOTOPMOST, -1, -1, pt.x, pt.y, SWP_NOMOVE | SWP_NOREPOSITION | SWP_NOZORDER); //This sets the button's icon image. SendMessage(hAPCLogoButton, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) aUPSIconHandle); return(TRUE); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // void DoUpdateDialogInfo (HWND aDlgHWND); // // Description: This functions gets the latest UPS information and updates the // contents/form of the various controls within the dialog, based // on the availability and content of the various settings. // // Additional Information: // // Parameters: // // HWND aDlgHWND :- Dialog window handle. // // Return Value: None // void DoUpdateDialogInfo (HWND aDlgHWND) { //Get the UPS data and for each item that's available display the appropriate //value and enable the associated controls. All other fields static const DWORD numRunningFields = DIMENSION_OF(g_DialogAssocs); static const DWORD numNoServiceFields = DIMENSION_OF(g_NoServiceControls); HWND hMessageControl = GetDlgItem(aDlgHWND, IDC_MESSAGE_TEXT); HWND hServiceControl = GetDlgItem(aDlgHWND, IDC_SERVICE_TEXT); DWORD dwUtilityStatus = 0; BOOL bIsUPSInstalled = IsUPSInstalled(); //The IDC_MESSAGE_TEXT control contains default information in the //Static control in the dialog resource. This text message can be //changed to the "service not running" message, the "no comm" message //or the "press apply to commit" message depending on the current //state of the registry, the upsreg data buffer, the UPS service //and the status of the UPS communication. However, if conditions //dictate we want the original text from the control to be displayed. //For this reason we must store the original text so that the control //text can be set to this text without having to have the actual //text as a string resource. DoUpdateInfo(aDlgHWND, g_DialogAssocs, numRunningFields, (DWORD *) &g_NoServiceControls, numNoServiceFields, FALSE); //Now the IDC_MESSAGE_TEXT control may need to be changed to display different information. SelectServiceTextMessage(aDlgHWND, hMessageControl, hServiceControl); // Update the Power Source Icon if( (TRUE == IsUPSInstalled()) && (TRUE == GetUPSDataItemDWORD(eREG_POWER_SOURCE, &dwUtilityStatus)) && (UPS_UTILITYPOWER_OFF == dwUtilityStatus) ) SendMessage(GetDlgItem(aDlgHWND, IDC_POWER_SOURCE_ICON),STM_SETICON,(WPARAM)g_hIconUPS,0); else SendMessage(GetDlgItem(aDlgHWND, IDC_POWER_SOURCE_ICON),STM_SETICON,(WPARAM)g_hIconPlug,0); //Finally if no UPS is installed then disable the IDB_CONFIGURE_SVC control otherwise //enable it. ManageConfigureButtonState(aDlgHWND); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // void SelectServiceTextMessage (HWND aDlgHWND, HWND aNoServiceControlHwnd, HWND aServiceControlHwnd); // // Description: This function changes the text displayed in the bottom half // of the UPS page. There are two control because the // IDC_SERVICE_TEXT control needs to be positioned to the left // of the "Configure..." button, while the other messages need // to be centered in the group box. The first control is not // as wide and is off centre. The second control is centered. // If the requirements were different this could have been // one control whose text changed. // // If the first control is visible, the second one is made // invisible, and vice versa, as their contents are mutually // exclusive. // // Additional Information: // // Parameters: // // HWND aNoServiceControlHwnd :- Handle to the IDC_MESSAGE_TEXT control. // // HWND aServiceControlHwnd :- Handle to the IDC_SERVICE_TEXT control. // // Return Value: None // void SelectServiceTextMessage (HWND aDlgHWND, HWND aNoServiceControlHwnd, HWND aServiceControlHwnd) { static BOOL bGotServiceTextMessages = FALSE; static TCHAR originalControlTextBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); static TCHAR noCommStringBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); static TCHAR pressApplyStringBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); static TCHAR noUPSInstalledStringBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); static HICON hInfoIcon; static HICON hWarningIcon; static HICON hErrorIcon; BOOL bShow = TRUE; DWORD commStatus = 0; BOOL bIsRunning = IsServiceRunning(UPS_SERVICE_NAME); BOOL bIsDataUpToDate = IsDataUpToDate(); BOOL bIsUPSInstalled = IsUPSInstalled(); BOOL bIsDataOK = IsDataOKToDisplay(); DWORD dataState = GetActiveDataState(); _ASSERT(aNoServiceControlHwnd != NULL); //Determine which control should be shown. Is it the "everything OK" control //or the second control that is used for all other messages. ShowWindow(aServiceControlHwnd, (bIsRunning == TRUE) && (bIsDataUpToDate == TRUE) && (bIsDataOK == TRUE) && FALSE ? SW_SHOW : SW_HIDE); //Get the strings if this is the first time into this function. if (bGotServiceTextMessages == FALSE) { // GetServiceTextMessages(aNoServiceControlHwnd, originalControlTextBuffer, DIMENSION_OF(originalControlTextBuffer), // IDS_COMM_LOST, noCommStringBuffer, DIMENSION_OF(noCommStringBuffer), // IDS_PRESS_APPLY, pressApplyStringBuffer, DIMENSION_OF(pressApplyStringBuffer), // IDS_NO_UPS_INSTALLED, noUPSInstalledStringBuffer, DIMENSION_OF(noUPSInstalledStringBuffer)); bGotServiceTextMessages = TRUE; if (LoadString( GetUPSModuleHandle(), IDS_UPS_STOPPED, originalControlTextBuffer, DIMENSION_OF(originalControlTextBuffer)) > 0) {} if (LoadString( GetUPSModuleHandle(), IDS_COMM_LOST, noCommStringBuffer, DIMENSION_OF(noCommStringBuffer)) > 0) {} if (LoadString( GetUPSModuleHandle(), IDS_PRESS_APPLY, pressApplyStringBuffer, DIMENSION_OF(pressApplyStringBuffer)) > 0) {} if (LoadString( GetUPSModuleHandle(), IDS_NO_UPS_INSTALLED, noUPSInstalledStringBuffer, DIMENSION_OF(noUPSInstalledStringBuffer)) > 0) {} hInfoIcon = LoadImage(NULL, MAKEINTRESOURCE(IDI_INFORMATION), IMAGE_ICON, 0,0, LR_LOADMAP3DCOLORS | LR_SHARED); hWarningIcon = LoadImage(NULL, MAKEINTRESOURCE(IDI_WARNING), IMAGE_ICON, 0,0, LR_LOADMAP3DCOLORS | LR_SHARED); hErrorIcon = LoadImage(NULL, MAKEINTRESOURCE(IDI_ERROR), IMAGE_ICON, 0,0, LR_LOADMAP3DCOLORS | LR_SHARED); } //Determime which string to display in the second control. if( (bIsDataUpToDate == FALSE) || (dataState & CONFIG_DATA_CHANGE) ) { ChangeTextIfDifferent(aNoServiceControlHwnd, pressApplyStringBuffer); SendMessage(GetDlgItem(aDlgHWND, IDC_MESSAGE_ICON),STM_SETICON,(WPARAM)hInfoIcon,0); } else if (bIsRunning == FALSE) { ChangeTextIfDifferent(aNoServiceControlHwnd, originalControlTextBuffer); SendMessage(GetDlgItem(aDlgHWND, IDC_MESSAGE_ICON),STM_SETICON,(WPARAM)hWarningIcon,0); } else if (GetUPSDataItemDWORD(eREG_COMM_STATUS, &commStatus) == TRUE) { if ((commStatus == UPS_COMMSTATUS_LOST) && (bIsRunning == TRUE)) { ChangeTextIfDifferent(aNoServiceControlHwnd, noCommStringBuffer); SendMessage(GetDlgItem(aDlgHWND, IDC_MESSAGE_ICON),STM_SETICON,(WPARAM)hErrorIcon,0); }//End Comm Lost else bShow = FALSE; }//end if GetUPSDataItemDWORD(eREG_COMM_STATUS... ShowWindow(GetDlgItem(aDlgHWND,IDC_MESSAGE_TEXT), bShow ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(aDlgHWND,IDC_MESSAGE_ICON), bShow ? SW_SHOW : SW_HIDE); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // void ChangeTextIfDifferent (HWND aWindowHandle, LPTSTR aBuffer); // // Description: This function set a window's text to the given value, unless // the window text is matches this string already in which case // the function does nothing. // // Additional Information: // // Parameters: // // HWND aWindowHandle :- Handle to a control. // // LPTSTR aBuffer :- Pointer to new window text. This parameter should not be // NULL, although it can point to an empty string. // // Return Value: None // void ChangeTextIfDifferent (HWND aWindowHandle, LPTSTR aBuffer) { TCHAR controlTextBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); DWORD controlTextBufferSize = DIMENSION_OF(controlTextBuffer); HICON hMsgIcon = NULL; _ASSERT(aWindowHandle != NULL); _ASSERT(aBuffer != NULL); // if (GetWindowText(aWindowHandle, controlTextBuffer, controlTextBufferSize) > 0) { GetWindowText(aWindowHandle, controlTextBuffer, controlTextBufferSize); if (_tcscmp(controlTextBuffer, aBuffer) != 0) { //Only set the window text if it has changed (reduces screen flicker). SetWindowText(aWindowHandle, aBuffer); } // } // else { // SetWindowText(aWindowHandle, aBuffer); // } } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // void ManageConfigureButtonState (HWND aDlgHWND); // // Description: This "Configure..." button (IDB_CONFIGURE_SVC) should be // enabled only if a UPS is installed and the system is on AC Power. // This function enables // this button if a UPS is currently selected and disables // it if one isn't. // // The state of the Configure button reflects the state of // the "cached" values, not the actual committed registry // values. // // Additional Information: // // Parameters: // // HWND aDlgHWND :- A handle to the main UPS window. // // Return Value: None // void ManageConfigureButtonState (HWND aDlgHWND) { DWORD bIsUpgrade = 0; DWORD dwUtilityStatus = 0; HWND hControl = GetDlgItem(aDlgHWND, IDB_CONFIGURE_SVC); if (hControl != NULL) { BOOL bIsUPSInstalled = IsUPSInstalled(); GetUPSConfigUpgrade(&bIsUpgrade); GetUPSDataItemDWORD(eREG_POWER_SOURCE, &dwUtilityStatus); if( !bIsUPSInstalled || !g_bIsAdmin || bIsUpgrade || (UPS_UTILITYPOWER_OFF == dwUtilityStatus) ) { EnableWindow(hControl, FALSE); } else { EnableWindow(hControl, TRUE); } } } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL DoUpdateInfo (HWND aDlgHWND, // DialogAssociations * aDialogAssociationsArray, // DWORD aNumRunningFields, // BOOL aShowWindowBool); // // Description: This function updates the current information in the main // UPS page to reflect the current UPS status information. // // Additional Information: // // Parameters: // // HWND aDlgHWND :- A handle to the main UPS window. // // DialogAssociations * aDialogAssociationsArray :- Pointer to an array of // DialogAssociations's. // // DWORD aNumRunningFields :- This is the number of elements in the above array. // // BOOL aShowWindowBool :- Indicates whether the visibility of the // controls that have no data should be // affected. For the main UPS page the // visibility is not changed. For the // Advanced data the visibility is changed. // // Return Value: TRUE if any one of the data item has data associated with it. // BOOL DoUpdateInfo (HWND aDlgHWND, DialogAssociations * aDialogAssociationsArray, DWORD aNumRunningFields, DWORD * aNoServiceControlIDs, DWORD aNumNoServiceControls, BOOL aShowWindowBool) { //Get the UPS data and for each item that's available display the appropriate //value and enable the associated controls. All other fields TCHAR upsDataBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); TCHAR resourceStringBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); TCHAR controlBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); DWORD dwordValue = 0; DWORD i=0; DWORD firstControlID = 0; DWORD secondControlID = 0; HWND hFirstControl = NULL; HWND hSecondControl = NULL; LPVOID lppArgs[1]; BOOL bShowField = FALSE; BOOL bIsDataOK = IsDataOKToDisplay(); bIsDataOK &= IsDataUpToDate(); //Display/hide the NO service controls and hide/display all the //DialogAssociations fields. for (i=0; itheFieldTypeID; RegField * pRegField = GetRegField(fieldID); BOOL bGotData = FALSE; BOOL bValueSupported = TRUE; lppArgs[0] = (VOID *) 0; if (pRegField != NULL) { #ifdef _DEBUG { //If pCurrentEntryDetails->theResourceStringType is of type RESOURCE_INCREMENT //then pRegField->theValueType must be some DWORD type if (pCurrentEntryDetails->theResourceStringType == RESOURCE_INCREMENT) { DWORD allowedTypesDbg = REG_ANY_DWORD_TYPE; _ASSERT((pRegField->theValueType & allowedTypesDbg) == pRegField->theValueType); } } #endif if (pCurrentEntryDetails->theRegAccessType == eDeepGet) { if (bIsDataOK == TRUE) { if ((pRegField->theValueType & (REG_SZ | REG_EXPAND_SZ)) == pRegField->theValueType) { bGotData = GetUPSDataItemString(fieldID, upsDataBuffer, &upsDataBufSize); lppArgs[0] = (VOID *) (LPCTSTR) upsDataBuffer; } else { #ifdef _DEBUG { DWORD allowedTypesDbg = REG_ANY_DWORD_TYPE; _ASSERT((pRegField->theValueType & allowedTypesDbg) == pRegField->theValueType); } #endif if ((bGotData = GetUPSDataItemDWORD(fieldID, &dwordValue)) == TRUE) { //Need some special handling here if the if (pCurrentEntryDetails->theResourceStringType == RESOURCE_INCREMENT) { //This DWORD value represents an offset into the resource string table //to identify a string that is to be displayed, not a DWORD value //If the index is 0 then the value is unknown and the associated //fields are shown disabled. 0 is a special case that will do this //for all fields of this type. DWORD realResID = 0; //If the given value is greater than the given maximum value //then the field is "not supported" and the associated //fields are hidden. if (dwordValue > pCurrentEntryDetails->theResourceIndexMax) { bValueSupported = FALSE; bGotData = FALSE; } else if (dwordValue == 0) { bGotData = FALSE; } else { realResID = pCurrentEntryDetails->theResourceIndexID + dwordValue; if (LoadString(GetUPSModuleHandle(), realResID, upsDataBuffer, upsDataBufSize) > 0) { lppArgs[0] = (VOID *) (LPCTSTR) upsDataBuffer; } } } else { lppArgs[0] = IntToPtr(dwordValue); //If the value of a regular number field is 0 then it is not supported. if (dwordValue == 0) { bGotData = FALSE; } } } } }//end bIsDataOK } else { _ASSERT(pCurrentEntryDetails->theRegAccessType == eShallowGet); _ASSERT((pCurrentEntryDetails->theShallowAccessFunctionPtr == getDwordValue) || (pCurrentEntryDetails->theShallowAccessFunctionPtr == getStringValue)); _ASSERT(pCurrentEntryDetails->theRegEntryPtr != 0); if (pCurrentEntryDetails->theShallowAccessFunctionPtr == getDwordValue) { if (getDwordValue(pCurrentEntryDetails->theRegEntryPtr, &dwordValue) == ERROR_SUCCESS) { lppArgs[0] = IntToPtr(dwordValue); bGotData = TRUE; } } else { if (getStringValue(pCurrentEntryDetails->theRegEntryPtr, upsDataBuffer) == ERROR_SUCCESS) { lppArgs[0] = (VOID *) (LPCTSTR) upsDataBuffer; bGotData = TRUE; } } } //If bGotData == TRUE then the field was active in the registry and we react accordingly //by enabling the associated controls. firstControlID = pCurrentEntryDetails->theStaticFieldID; secondControlID = pCurrentEntryDetails->theDisplayControlID; hFirstControl = GetDlgItem(aDlgHWND, firstControlID); hSecondControl = GetDlgItem(aDlgHWND, secondControlID); _ASSERT(firstControlID > 0); _ASSERT(secondControlID > 0); _ASSERT(hFirstControl != NULL); _ASSERT(hSecondControl != NULL); EnableWindow(hFirstControl, bGotData); EnableWindow(hSecondControl, bGotData); if (bValueSupported == FALSE) { ShowWindow(hFirstControl, bValueSupported ? SW_SHOW : SW_HIDE); ShowWindow(hSecondControl, bValueSupported ? SW_SHOW : SW_HIDE); } if (aShowWindowBool == TRUE) { ShowWindow(hFirstControl, bGotData ? SW_SHOW : SW_HIDE); ShowWindow(hSecondControl, bGotData ? SW_SHOW : SW_HIDE); } if (bGotData == TRUE) { bShowField = TRUE; //Now we want to form the string to display. if (GetMessageFromStringTable(pCurrentEntryDetails->theResourceInsertID, lppArgs, resourceStringBuffer, &resStringBufSize) == ERROR_SUCCESS) { if (GetWindowText(hSecondControl, controlBuffer, DIMENSION_OF(controlBuffer)) > 0) { if (_tcscmp(controlBuffer, resourceStringBuffer) != 0) { SetWindowText(hSecondControl, resourceStringBuffer); } } else { SetWindowText(hSecondControl, resourceStringBuffer); } } #ifdef _DEBUG else { //An unexpected error occurred. The number of parameters identified //in the resource string and the number passed may not match _ASSERT(FALSE); } #endif } else { //Empty the contents of the second control SetWindowText(hSecondControl, TEXT("")); } } }//end for return(bShowField); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL IsDataOKToDisplay (void); // // Description: This function determines how suitable it is to display the // UPS status information. The UPS statius information is only // accurate if the service is running and communication exists // between the UPS service and the UPS. If this is not the // case then this function returns FALSE. // // Additional Information: // // Parameters: None // // Return Value: Returns TRUE if it is OK to display UPS status information. // BOOL IsDataOKToDisplay (void) { BOOL bIsRunning = IsServiceRunning(UPS_SERVICE_NAME); DWORD commStatus = 0; BOOL bIsCommEstablished = FALSE; BOOL bIsDataOK = bIsRunning; if (GetUPSDataItemDWORD(eREG_COMM_STATUS, &commStatus) == TRUE) { if (commStatus == 1) { bIsCommEstablished = TRUE; } bIsDataOK &= bIsCommEstablished; } return(bIsDataOK); } //////////////////////////////////////////////////////////////////////////_/_// //////////////////////////////////////////////////////////////////////////_/_// // BOOL IsDataUpToDate (void); // // Description: If the user changes the vendor, model or COM port then // the main UPS page should not display the UPS status // information. // // Additional Information: // // Parameters: None // // Return Value: This function returns FALSE if the values currently stored in // the registry for vendor, model, or port differs from the // "internal" values (that is the value stored in the upsreg // buffers, see upsreg.h and upsreg.c). // BOOL IsDataUpToDate (void) { //if the Vendor or Model Type or Port in the registry differs from //upsreg value then the data is out of sync. TCHAR vendorBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); DWORD vendorBufferSize = DIMENSION_OF(vendorBuffer); TCHAR modelBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); DWORD modelBufferSize = DIMENSION_OF(modelBuffer); TCHAR portBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); DWORD portBufferSize = DIMENSION_OF(portBuffer); TCHAR vendorOtherBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); TCHAR modelOtherBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); TCHAR portOtherBuffer[MAX_MESSAGE_LENGTH] = TEXT(""); GetUPSDataItemString(eREG_VENDOR_NAME, vendorBuffer, &vendorBufferSize); GetUPSConfigVendor(vendorOtherBuffer); GetUPSDataItemString(eREG_MODEL_TYPE, modelBuffer, &modelBufferSize); GetUPSConfigModel(modelOtherBuffer); GetUPSDataItemString(eREG_PORT, portBuffer, &portBufferSize); GetUPSConfigPort(portOtherBuffer); return((_tcscmp(vendorBuffer, vendorOtherBuffer) == 0) && (_tcscmp(modelOtherBuffer, modelBuffer) == 0) && (_tcscmp(portBuffer, portOtherBuffer) == 0)); } /******************************************************************************* * * IsUpsPresent * * DESCRIPTION: This function gets called to determine if UPS is present * and should be displayed in a tab. For now this functions * returns TRUE * * RETURNS: TRUE if UPS is present, FALSE if UPS is no present * * *******************************************************************************/ BOOLEAN IsUpsPresent(PSYSTEM_POWER_CAPABILITIES pspc) { BOOLEAN UpsPresent; DWORD dwShowTab; TCHAR szImagePath[MAX_PATH]; InitUPSConfigBlock(); if ((ERROR_SUCCESS == GetUPSConfigShowUPSTab(&dwShowTab)) && dwShowTab) { UpsPresent = TRUE; } else if (pspc->SystemBatteriesPresent) { UpsPresent = FALSE; } else if (!(ERROR_SUCCESS == GetUPSConfigImagePath(szImagePath))) { UpsPresent = TRUE; } else if (!_tcsicmp(DEFAULT_CONFIG_IMAGEPATH, szImagePath)) { UpsPresent = TRUE; } else { UpsPresent = FALSE; } return(UpsPresent); } // // Kill the 1-second update timer. // DWORD KillUpdateTimer(HWND hwnd) { if (0 != g_UpdateTimerID) { KillTimer(hwnd, g_UpdateTimerID); g_UpdateTimerID = 0; } return ERROR_SUCCESS; } // // Create the 1-second update timer. // DWORD SetUpdateTimer(HWND hwnd) { DWORD dwResult = ERROR_SUCCESS; KillUpdateTimer(hwnd); g_UpdateTimerID = SetTimer(hwnd, cUpdateTimerID, 1000, NULL); if (0 == g_UpdateTimerID) { dwResult = GetLastError(); } return dwResult; }