/* * CSTATHLP.CPP * * CStatusHelper class to assist managing the strings for the * status bar. Here we provide menu ID to string ID mapping * services using a mapping structure in the module's resources. * * This code assumes that the status bar is a standard Windows * status bar control as we use SetWindowText (WM_SETTEXT) to set * strings. This displays messages in the 0th pane of the bar, * which is all we need. * * with SCC Changes for SCC QuickView - SDN */ #include #include "cstrtabl.h" #include "cstathlp.h" #include "resource.h" /* * CStatusHelper::CStatusHelper * CStatusHelper::~CStatusHelper * * Constructor Parameters: * hWnd HWND of the Status Bar control to work with. * hInst HINSTANCE of the module we're in. */ CStatusHelper::CStatusHelper(HWND hWnd, HINSTANCE hInst) { m_hWnd=hWnd; m_hInst=hInst; m_uIDCur=0xFFFFFFFF; //Nothing shown yet. m_pST=NULL; m_pPMM=NULL; m_pSMM=NULL; m_hMemSMM=NULL; //With this FALSE, many other members are ignored. m_fMapped=FALSE; } CStatusHelper::~CStatusHelper(void) { //Free up anything from MessageMap if (NULL!=m_pPMM) { LocalFree((HLOCAL)m_pPMM); m_pPMM=NULL; } if (NULL!=m_pST) { delete m_pST; m_pST=NULL; } if (NULL!=m_pNewSMM) { // UnlockResource(m_hMemSMM); LocalFree ((HLOCAL)m_pNewSMM); m_pNewSMM = NULL; m_pSMM=NULL; } if (NULL!=m_hMemSMM) { //FreeResource(m_hMemSMM); m_hMemSMM=NULL; } return; } /* * CStatusHelper::MessageMap * * Purpose: * Initializes a CStatusHelper for automated processing of * WM_MENUSELECT messages as well as setting up a list of messages * that we can display using identifiers instead of string * pointers. See MenuSelect and MessageDisplay members. * * This function is the initializer for the CStatusHelper class. * If it fails, then the caller should delete the object. * * Parameters: * hWndOwner HWND of the window owning menus we're * interested in serving * uIDRMap UINT identifying a resource mapping ID values * to string ID values * idsMin UINT specifying the lowest string ID to load * idsMax UINT specifying the hightest string ID to load * cchMax UINT maximum string length * uIDPopupMin UINT of the lowest ID to assign to popup menus * uIDPopupMax UINT of the highest ID to assign to popup menus * uIDStatic UINT of the ID for the quiescent state message * uIDBlank UINT of the ID for a blank message * uIDSysMenu UINT of the ID for the system menu * * Return Value: * BOOL TRUE if the function was successful, * FALSE otherwise. */ BOOL CStatusHelper::MessageMap(HWND hWndOwner, UINT uIDRMap , UINT idsMin, UINT idsMax, UINT cchMax, UINT uIDPopupMin , UINT uIDPopupMax, UINT uIDStatic, UINT uIDBlank, UINT uIDSysMenu) { // HMENU hMenu; HRSRC hRes; UINT i; // USHORT uID; DWORD locSize; /* * Check if we even got a valid window in the constructor * or if we've already been called. */ if (!IsWindow(m_hWnd) || m_fMapped) return FALSE; //Parameter validation if (idsMax < idsMin || uIDPopupMax < uIDPopupMin) return FALSE; //Cache away all this vital information m_hWndOwner =hWndOwner; m_idsMin =idsMin; m_idsMax =idsMax; m_cMessages =(USHORT)(idsMax-idsMin+1); m_uIDPopupMin=uIDPopupMin; m_uIDPopupMax=uIDPopupMax; m_cPopups =(USHORT)(uIDPopupMax-uIDPopupMin+1); m_uIDStatic =uIDStatic; m_uIDBlank =uIDBlank; m_uIDSysMenu =uIDSysMenu; //Get a stringtable with all the messages m_pST=new CStringTable(m_hInst); if (NULL==m_pST) return FALSE; if (!m_pST->FInit(idsMin, idsMax, CCHSTATUSMSGMAX)) return FALSE; //Load the STATMESSAGEMAP array from resources hRes=FindResource(m_hInst, MAKEINTRESOURCE(uIDRMap), RT_RCDATA); if (NULL==hRes) return FALSE; m_hMemSMM=LoadResource(m_hInst, hRes); if (NULL==m_hMemSMM) return FALSE; m_pSMM=(PSTATMESSAGEMAP)LockResource(m_hMemSMM); if (NULL==m_pSMM) return FALSE; locSize = SizeofResource(m_hInst, hRes); if (locSize==0) locSize = 0x100; m_pNewSMM = (PSTATMESSAGEMAP)LocalAlloc(LPTR, locSize); for (i=0; iAppend (uID, lpStr); } /* | | CStatusHelper::Replace (UINT uID, LPSTR lpStr) | */ BOOL CStatusHelper::Replace (UINT uID, LPSTR lpStr) { /* Given an ID, add the lpstr to the entry indexed by uID */ /* To be used for adding the APPNAME to the msg strings.. */ if (NULL==m_pST) return FALSE; return m_pST->Replace (uID, lpStr); } /** ** Private members follow. **/ /* * CStatusHelper::Sort * (Private) * * Purpose: * Performs a selection sort on the STATMESSAGEMAP array that we * load from resources. Since we expect that the data is partially * sorted (we tend to place things in resources in groups of * seqential values), since the number of messages is usually * less than 200, and since we're usually doing this stuff on startup * (which takes a long time anyway), a cimple selection sort is a * better choice than a more complex qsort. * * Parameters: * None * * Return Value: * None */ void CStatusHelper::Sort(void) { UINT i, j, k; STATMESSAGEMAP smm; for (j=0; j < (UINT)(m_cMessages-1); j++) { k=j; smm.uID =m_pNewSMM[j].uID; smm.idsMsg=m_pNewSMM[j].idsMsg; for (i=j+1; i < (UINT)m_cMessages; i++) { if (m_pNewSMM[i].uID < smm.uID) { smm.uID =m_pNewSMM[i].uID; smm.idsMsg=m_pNewSMM[i].idsMsg; k=i; } } smm.uID =m_pNewSMM[j].uID; smm.idsMsg =m_pNewSMM[j].idsMsg; m_pNewSMM[j].uID =m_pNewSMM[k].uID; ; m_pNewSMM[j].idsMsg=m_pNewSMM[k].idsMsg;; m_pNewSMM[k].uID =smm.uID; m_pNewSMM[k].idsMsg=smm.idsMsg; } return; } /* * CStatusHelper::IDFromHMenu * (Private) * * Purpose: * Given a specific popup menu index, searches through m_pPMM for * a match and returns the ID associated with that menu. * * Parameters: * hMenu HMENU to of he popup menu. * * Return Value: * USHORT ID associated with the menu handle. */ USHORT CStatusHelper::IDFromHMenu(HMENU hMenu) { USHORT uID=m_uIDBlank; //Default is empty UINT i; i = (UINT) hMenu; switch ( i ) { case 0: //File uID = IDM_FILE; break; case 1: //View uID = IDM_VIEW; break; case 2: // Help uID = IDM_HELP; break; default: break; } // for (i=0; i < m_cPopups; i++) // { // if (m_pPMM[i].hMenu==hMenu) // { // uID=m_pPMM[i].uID; // break; // } // } return uID; } /* * CStatusHelper::IStringFromID * (Private) * * Purpose: * Performs a binary search in a STATMESSAGEMAP array looking for * a specific item ID returning the string ID for that item. * * Parameters: * uID USHORT item ID to locate. * * Return Value: * UINT String ID associated with wItem. */ UINT CStatusHelper::IStringFromID(USHORT uID) { UINT iLow =0; UINT iHigh=m_cMessages-1; UINT iMid; while (TRUE) { iMid=(iLow+iHigh) >> 1; if (uID < m_pNewSMM[iMid].uID) iHigh=iMid-1; else { if (uID > m_pNewSMM[iMid].uID) iLow=iMid+1; else break; //Equality } if (iHigh < iLow) break; } return m_pNewSMM[iMid].idsMsg; }