//+-------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1994 - 1998. // // File: util.cxx // // Contents: utility functions // // // History: 12-05-1997 SusiA // //--------------------------------------------------------------------------- #include "lib.h" #ifndef SECURITY_WIN32 #define SECURITY_WIN32 #endif #include "security.h" extern "C" CRITICAL_SECTION g_CritSectCommonLib; // initialized by InitCommonLib extern OSVERSIONINFOA g_OSVersionInfo; // osVersionInfo. typedef BOOLEAN (APIENTRY *PFNGETUSERNAMEEX) (EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize ); STRING_FILENAME(szSecur32Dll, "SECUR32.DLL"); STRING_INTERFACE(szGetUserNameEx,"GetUserNameExW"); BOOL g_fLoadedSecur32 = FALSE; HINSTANCE g_hinstSecur32 = NULL; PFNGETUSERNAMEEX g_pfGetUserNameEx = NULL; //-------------------------------------------------------------------------------- // // FUNCTION: RegGetCurrentUser(LPTSTR pszName, LPDWORD pdwCount) // // PURPOSE: Gets the currently logged on user name from the Reg // //-------------------------------------------------------------------------------- BOOL RegGetCurrentUser(LPTSTR pszName, LPDWORD pdwCount) { HRESULT hr = ERROR_SUCCESS; HKEY hkeyUser; DWORD dwDataSize = *pdwCount * sizeof(TCHAR); DWORD dwType = REG_SZ; // Get the current user name from the reg if (ERROR_SUCCESS == (hr = RegOpenKeyExXp(HKEY_CURRENT_USER, TOPLEVEL_REGKEY,0,KEY_QUERY_VALUE,&hkeyUser,FALSE /*fSetSecurity*/))) { hr = RegQueryValueEx(hkeyUser,TEXT("CurrentUserName"), NULL, &dwType , (LPBYTE) pszName, &dwDataSize); *pdwCount = dwDataSize; RegCloseKey(hkeyUser); } if (ERROR_SUCCESS == hr) { return TRUE; } else { return FALSE; } } //-------------------------------------------------------------------------------- // // FUNCTION: RegSetCurrentUser(LPTSTR pszName) // // PURPOSE: sets the current user name in the reg // //-------------------------------------------------------------------------------- BOOL RegSetCurrentUser(LPTSTR pszName) { HRESULT hr = ERROR_SUCCESS; HKEY hkeyUser; // write out the Handler to the Registry. if (ERROR_SUCCESS == (hr = RegCreateKeyEx(HKEY_CURRENT_USER, TOPLEVEL_REGKEY,0,NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL,&hkeyUser, NULL))) { hr = RegSetValueEx(hkeyUser,TEXT("CurrentUserName"), NULL, REG_SZ , (LPBYTE) pszName, UNLEN + 1); RegCloseKey(hkeyUser); } if (ERROR_SUCCESS == hr) { return TRUE; } else { return FALSE; } } //+--------------------------------------------------------------------------- // // Function: CenterDialog // // Synopsis: Helper to center a dialog on screen. // // Arguments: [hDlg] -- Dialog handle. // // Returns: None. // // Notes: None. // //---------------------------------------------------------------------------- void CenterDialog(HWND hDlg) { RECT rc; GetWindowRect(hDlg, &rc); SetWindowPos(hDlg, NULL, ((GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2), ((GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2), 0, 0, SWP_NOSIZE | SWP_NOACTIVATE); } //+-------------------------------------------------------------------------- // // Function: GetDomainAndMachineName // // Synopsis: Fill [ptszDomainAndMachineName] with "domain\machine" string // // Arguments: [ptszDomainAndMachineName] - buffer to receive string // [cchBuf] - should be at least UNLEN // // Modifies: *[ptszDomainAndMachineName]. // // History: 01-12-1998 SusiA Created // // Notes: If an error occurs while retrieving the domain name, only // the machine name is returned. If even that cannot be // retrieved, the buffer is set to an empty string. // //--------------------------------------------------------------------------- VOID GetDomainAndMachineName( LPTSTR ptszDomainAndMachineName, ULONG cchBuf) { HRESULT hr = E_FAIL; LONG lr; HKEY hkWinlogon = NULL; ULONG cchRemain = cchBuf; do { // // Get the domain name of the currently logged on user. Open the // winlogon key. // lr = RegOpenKeyExXp(HKEY_LOCAL_MACHINE, REGSTR_WINLOGON, 0, KEY_QUERY_VALUE, &hkWinlogon,FALSE /*fSetSecurity*/); if (lr != ERROR_SUCCESS) { break; } // // Query for the default domain, which is what the user logged on to. // ULONG cbBuf = cchBuf * sizeof(TCHAR); DWORD dwType; lr = RegQueryValueEx(hkWinlogon, REGSTR_DEFAULT_DOMAIN, NULL, &dwType, (LPBYTE) ptszDomainAndMachineName, &cbBuf); if (lr != ERROR_SUCCESS) { break; } Assert(dwType == REG_SZ); // // Account for the characters used up by the domain name, but // don't count the trailing NULL. // cchRemain -= (cbBuf / sizeof(TCHAR)) - 1; if (cchRemain < 2) { break; } lstrcat(ptszDomainAndMachineName, TEXT("/")); cchRemain--; hr = S_OK; } while (0); // // If there was any problem with the domain name, put only the user name // in the buffer. // if (FAILED(hr)) { *ptszDomainAndMachineName = TEXT('\0'); cchRemain = cchBuf; } // // Get the machine name, which is going either at the start of the buffer // or just after the backslash appended to the domain name. // lr = GetComputerName(&ptszDomainAndMachineName[cchBuf - cchRemain], &cchRemain); if (!lr) { *ptszDomainAndMachineName = TEXT('\0'); } if (hkWinlogon) { RegCloseKey(hkWinlogon); } } void LoadSecur32Dll() { if (g_fLoadedSecur32) return; CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId()); cCritSect.Enter(); // make sure not loaded again in case someone took lock first if (!g_fLoadedSecur32) { g_hinstSecur32 = LoadLibrary(szSecur32Dll); if (g_hinstSecur32) { g_pfGetUserNameEx = (PFNGETUSERNAMEEX) GetProcAddress(g_hinstSecur32, szGetUserNameEx); // won't get the export on NT 4.0 } g_fLoadedSecur32 = TRUE; } cCritSect.Leave(); } //+-------------------------------------------------------------------------- // // Function: GetNT4UserDomainName // // Synopsis: Fill [ptszDomainAndUserName] with "domain\user" string // // Arguments: [ptszDomainAndUserName] - buffer to receive string // [cchBuf] - should be at least UNLEN // // Modifies: *[ptszDomainAndUserName]. // // History: 06-03-1997 DavidMun Created // // Notes: If an error occurs while retrieving the domain name, only // the user name is returned. If even that cannot be // retrieved, the buffer is set to an empty string. // //--------------------------------------------------------------------------- BOOL GetNT4UserDomainName(LPTSTR ptszDomainAndUserName, LPTSTR ptszSeparator, ULONG cchBuf) { HKEY hkWinlogon = NULL; ULONG cchRemain = cchBuf; HRESULT hr = E_FAIL; LONG lr; ULONG cchTemp = UNLEN + DNLEN + 1; do { // // Get the domain name of the currently logged on user. Open the // winlogon key. // lr = RegOpenKeyExXp(HKEY_LOCAL_MACHINE, REGSTR_WINLOGON, 0, KEY_QUERY_VALUE, &hkWinlogon,FALSE /*fSetSecurity*/); if (lr != ERROR_SUCCESS) { break; } // // Query for the default domain, which is what the user logged on to. // ULONG cbBuf = cchBuf * sizeof(TCHAR); DWORD dwType; lr = RegQueryValueEx(hkWinlogon, REGSTR_DEFAULT_DOMAIN, NULL, &dwType, (LPBYTE) ptszDomainAndUserName, &cbBuf); if (lr != ERROR_SUCCESS) { break; } Assert(dwType == REG_SZ); // // Account for the characters used up by the domain name, but // don't count the trailing NULL. // cchRemain -= (cbBuf / sizeof(TCHAR)) - 1; if (cchRemain < 2) { break; } lstrcat(ptszDomainAndUserName, ptszSeparator); cchRemain--; hr = S_OK; } while (0); // // If there was any problem with the domain name, put only the user name // in the buffer. // if (FAILED(hr)) { *ptszDomainAndUserName = TEXT('\0'); cchRemain = cchBuf; } // // Get the user name, which is going either at the start of the buffer // or just after the backslash appended to the domain name. // cchTemp = cchRemain; lr = GetUserName(&ptszDomainAndUserName[cchBuf - cchTemp], &cchTemp); if (hkWinlogon) { RegCloseKey(hkWinlogon); } return (S_OK == hr) ? TRUE: FALSE; } //+-------------------------------------------------------------------------- // // Function: GetDefaultDomainAndUserName // // Synopsis: Fill [ptszDomainAndUserName] with "domain\user" string // // Arguments: [ptszDomainAndUserName] - buffer to receive string // [cchBuf] - should be at least UNLEN // // Modifies: *[ptszDomainAndUserName]. // // History: 06-03-1997 DavidMun Created // // Notes: If an error occurs while retrieving the domain name, only // the user name is returned. If even that cannot be // retrieved, the buffer is set to an empty string. // //--------------------------------------------------------------------------- // if output buffer is too small it gets truncated. VOID GetDefaultDomainAndUserName( LPTSTR ptszDomainAndUserName, LPTSTR ptszSeparator, ULONG cchBuf) { HRESULT hr = E_FAIL; LONG lr = 0; ULONG cchTemp = UNLEN + DNLEN + 1; BOOL fIsNT = (g_OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); if (fIsNT) { LoadSecur32Dll(); if (g_pfGetUserNameEx) { lr = g_pfGetUserNameEx(NameSamCompatible,ptszDomainAndUserName, &cchTemp); if (lr) { LPTSTR ptszWorker = ptszDomainAndUserName; while ( (TEXT('\0') != *ptszWorker) && *ptszWorker != TEXT('\\')) { ptszWorker++; } if ( TEXT('\0') != *ptszWorker) { *ptszWorker = ptszSeparator[0]; } } } if ((NULL == g_pfGetUserNameEx) || (0 == lr)) { GetNT4UserDomainName(ptszDomainAndUserName,ptszSeparator,cchBuf); } } else { // Win9x Stuff. cchTemp = cchBuf; if (!(lr = RegGetCurrentUser(ptszDomainAndUserName, &cchTemp))) { cchTemp = cchBuf; lr = GetUserName(ptszDomainAndUserName,&cchTemp); if (!lr || (*ptszDomainAndUserName == NULL)) { // on Win9x user can work without a user Name in this case // or any other GetUserName file the user is forced // to be called Default Assert(lstrlen(SZ_DEFAULTDOMAINANDUSERNAME) < cchBuf); lstrcpy(ptszDomainAndUserName,SZ_DEFAULTDOMAINANDUSERNAME); } // write out currentUser setting so can use next time. RegSetCurrentUser(ptszDomainAndUserName); } } Assert(NULL != *ptszDomainAndUserName); return; } //+------------------------------------------------------------------------------- // // FUNCTION: BOOL ConvertString(LPTSTR pszOut, LPWSTR pwszIn, DWORD dwSize) // // PURPOSE: utility function for ANSI/UNICODE conversion // // RETURN VALUE: return TRUE if we process it ok. // //+------------------------------------------------------------------------------- BOOL ConvertString(char * pszOut, LPWSTR pwszIn, DWORD dwSize) { if(WideCharToMultiByte( CP_ACP,0,pwszIn,-1,pszOut,dwSize,NULL,NULL)) { return TRUE; } return FALSE; } //+------------------------------------------------------------------------------- // // FUNCTION: BOOL ConvertString(LPWSTR pwszOut, LPTSTR pszIn, DWORD dwSize) // // PURPOSE: utility function for ANSI/UNICODE conversion // // RETURN VALUE: return TRUE if we process it ok. // //+------------------------------------------------------------------------------- BOOL ConvertString(LPWSTR pwszOut,char * pszIn, DWORD dwSize) { if(MultiByteToWideChar( CP_ACP,0,pszIn,-1,pwszOut,dwSize)) { return TRUE; } return FALSE; } //+------------------------------------------------------------------------------- // // FUNCTION: Bogus function temporary until get transitioned to unicode // so I don't have to fix up every existing converstring call. // // PURPOSE: utility function for ANSI/UNICODE conversion // // RETURN VALUE: return TRUE if we process it ok. // //+------------------------------------------------------------------------------- BOOL ConvertString(LPWSTR pszOut, LPWSTR pwszIn, DWORD dwSize) { #ifdef _UNICODE lstrcpy(pszOut,pwszIn); #else AssertSz(0,"Shouldn't be called in ASCII mode"); #endif // _UNICODE return TRUE; } //+------------------------------------------------------------------------------- // // Function: ConvertMultiByteToWideChar // // Synopsis: Converts multibyte strings to Unicode // /// Arguments: [pszBufIn] -- Input multibyte string // [cbBufIn] -- Count of chars/bytes in input buffer // [xwszBufOut] -- Smart pointer to output Unicode string // [fOem] -- If true use CP_OEMCP // // Returns: TRUE if we process it ok // // History: 14-Jul-98 SitaramR Created // //+------------------------------------------------------------------------------- BOOL ConvertMultiByteToWideChar( const char *pszBufIn, ULONG cbBufIn, XArray& xwszBufOut, BOOL fOem ) { Assert( pszBufIn != 0 ); if ( 0 == cbBufIn ) { xwszBufOut[0] = 0; return TRUE; } BOOL fOk; if ( xwszBufOut.Get() == 0 ) { ULONG cbBufOut; cbBufOut = (-1 == cbBufIn) ? lstrlenA(pszBufIn) + 1: cbBufIn; cbBufOut += 6; // give it a little extra room fOk = xwszBufOut.Init(cbBufOut); if ( !fOk ) return FALSE; } UINT codePage = CP_ACP; if ( fOem && !AreFileApisANSI() ) codePage = CP_OEMCP; ULONG cwcBufOut = (ULONG)xwszBufOut.Count(); ULONG cwcConvert = 0; do { cwcConvert = MultiByteToWideChar( codePage, MB_PRECOMPOSED, pszBufIn, cbBufIn, xwszBufOut.Get(), cwcBufOut - 1 ); if ( 0 == cwcConvert ) { if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { // // Double buffer size and then retry // delete xwszBufOut.Acquire(); cwcBufOut *= 2; fOk = xwszBufOut.Init( cwcBufOut ); if ( !fOk ) return FALSE; } else { // // Error during conversion // Assert( FALSE ); return FALSE; } } else xwszBufOut[cwcConvert] = 0; } while ( 0 == cwcConvert ); return TRUE; } //+------------------------------------------------------------------------------- // // Function: ConvertMultiByteToWideChar // // Synopsis: Converts multibyte strings to Unicode // /// Arguments: [pszBufIn] -- Input to null terminated multibyte string // [xwszBufOut] -- Smart pointer to output Unicode string // [fOem] -- If true use CP_OEMCP // // Returns: TRUE if we process it ok // // History: 14-Jul-98 SitaramR Created // //+------------------------------------------------------------------------------- BOOL ConvertMultiByteToWideChar( const char *pszBufIn, XArray& xwszBufOut, BOOL fOem ) { if ( pszBufIn == 0) { void *pBuf; if (pBuf = xwszBufOut.Acquire()) { delete pBuf; } return TRUE; } BOOL fRet = ConvertMultiByteToWideChar( pszBufIn, -1 /* lstrlenA(pszBufIn) + 1 */, xwszBufOut, fOem ); return fRet; } //+------------------------------------------------------------------------------- // // Function: ConvertWideCharToMultiByte // // Synopsis: Converts Unicode to multibyte strings // /// Arguments: [pwszBufIn] -- Input Unicode string // [cwcBufIn] -- Count of wide chars in input buffer // [xwszBufOut] -- Smart pointer to output multibyte string // [fOem] -- If true use CP_OEMCP // // Returns: TRUE if we process it ok // // History: 14-Jul-98 SitaramR Created // //+------------------------------------------------------------------------------- BOOL ConvertWideCharToMultiByte( const WCHAR *pwszBufIn, ULONG cwcBufIn, XArray& xszBufOut, BOOL fOem ) { Assert( pwszBufIn != 0 ); if ( 0 == cwcBufIn ) { xszBufOut[0] = 0; return TRUE; } BOOL fOk; if ( xszBufOut.Get() == 0 ) { ULONG cbBufOut; cbBufOut = (-1 == cwcBufIn) ? lstrlenX(pwszBufIn) + 1: cwcBufIn; cbBufOut += 6; // give it a little extra room. fOk = xszBufOut.Init(cbBufOut); if ( !fOk ) return FALSE; } UINT codePage = CP_ACP; if ( fOem && !AreFileApisANSI() ) codePage = CP_OEMCP; ULONG cbConvert; ULONG cbBufOut = (ULONG)xszBufOut.Count(); do { cbConvert = WideCharToMultiByte( codePage, WC_COMPOSITECHECK, pwszBufIn, cwcBufIn, xszBufOut.Get(), cbBufOut - 1, NULL, NULL ); if ( 0 == cbConvert ) { if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { // // Double buffer size and then retry // delete xszBufOut.Acquire(); cbBufOut *= 2; fOk = xszBufOut.Init( cbBufOut ); if ( !fOk ) return FALSE; } else { // // Error during conversion // Assert( FALSE ); return FALSE; } } else xszBufOut[cbConvert] = 0; } while ( 0 == cbConvert ); return TRUE; } //+------------------------------------------------------------------------------- // // Function: ConvertWideCharToMultiByte // // Synopsis: Converts Unicode to multibyte strings // /// Arguments: [pwszBufIn] -- Input to null terminated Unicode string // [xwszBufOut] -- Smart pointer to output multibyte string // [fOem] -- If true use CP_OEMCP // // Returns: TRUE if we process it ok // // History: 14-Jul-98 SitaramR Created // //+------------------------------------------------------------------------------- BOOL ConvertWideCharToMultiByte( const WCHAR *pwszBufIn, XArray& xszBufOut, BOOL fOem ) { if ( pwszBufIn == 0) { void *pBuf; if (pBuf = xszBufOut.Acquire()) { delete pBuf; } return TRUE; } BOOL fRet = ConvertWideCharToMultiByte( pwszBufIn, lstrlenX(pwszBufIn) + 1, xszBufOut, fOem ); return fRet; } // // Local constants // // DEFAULT_TIME_FORMAT - what to use if there's a problem getting format // from system. // #define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0])) #define DEFAULT_TIME_FORMAT TEXT("hh:mm tt") #define GET_LOCALE_INFO(lcid) \ { \ cch = GetLocaleInfo(LOCALE_USER_DEFAULT, \ (lcid), \ tszScratch, \ ARRAYLEN(tszScratch)); \ if (!cch) \ { \ break; \ } \ } //+-------------------------------------------------------------------------- // // Function: UpdateTimeFormat // // Synopsis: Construct a time format containing hour and minute for use // with the date picker control. // // Arguments: [tszTimeFormat] - buffer to fill with time format // [cchTimeFormat] - size in chars of buffer // // Modifies: *[tszTimeFormat] // // History: 11-18-1996 DavidMun Created // // Notes: This is called on initialization and for wininichange // processing. // //--------------------------------------------------------------------------- void UpdateTimeFormat( LPTSTR tszTimeFormat, ULONG cchTimeFormat) { ULONG cch; TCHAR tszScratch[80]; BOOL fAmPm; BOOL fAmPmPrefixes; BOOL fLeadingZero; do { GET_LOCALE_INFO(LOCALE_ITIME); fAmPm = (*tszScratch == TEXT('0')); if (fAmPm) { GET_LOCALE_INFO(LOCALE_ITIMEMARKPOSN); fAmPmPrefixes = (*tszScratch == TEXT('1')); } GET_LOCALE_INFO(LOCALE_ITLZERO); fLeadingZero = (*tszScratch == TEXT('1')); GET_LOCALE_INFO(LOCALE_STIME); // // See if there's enough room in destination string // cch = 1 + // terminating nul 1 + // first hour digit specifier "h" 2 + // minutes specifier "mm" (fLeadingZero != 0) + // leading hour digit specifier "h" lstrlen(tszScratch) + // separator string (fAmPm ? 3 : 0); // space and "tt" for AM/PM if (cch > cchTimeFormat) { cch = 0; // signal error } } while (0); // // If there was a problem in getting locale info for building time string // just use the default and bail. // if (!cch) { lstrcpy(tszTimeFormat, DEFAULT_TIME_FORMAT); return; } // // Build a time string that has hours and minutes but no seconds. // tszTimeFormat[0] = TEXT('\0'); if (fAmPm) { if (fAmPmPrefixes) { lstrcpy(tszTimeFormat, TEXT("tt ")); } lstrcat(tszTimeFormat, TEXT("h")); if (fLeadingZero) { lstrcat(tszTimeFormat, TEXT("h")); } } else { lstrcat(tszTimeFormat, TEXT("H")); if (fLeadingZero) { lstrcat(tszTimeFormat, TEXT("H")); } } lstrcat(tszTimeFormat, tszScratch); // separator lstrcat(tszTimeFormat, TEXT("mm")); if (fAmPm && !fAmPmPrefixes) { lstrcat(tszTimeFormat, TEXT(" tt")); } } //+-------------------------------------------------------------------------- // // Function: FillInStartDateTime // // Synopsis: Fill [pTrigger]'s starting date and time values from the // values in the date/time picker controls. // // Arguments: [hwndDatePick] - handle to control with start date // [hwndTimePick] - handle to control with start time // [pTrigger] - trigger to init // // Modifies: *[pTrigger] // // History: 12-08-1997 SusiA Stole from task scheduler // //--------------------------------------------------------------------------- VOID FillInStartDateTime( HWND hwndDatePick, HWND hwndTimePick,TASK_TRIGGER *pTrigger) { SYSTEMTIME st; DateTime_GetSystemtime(hwndDatePick, &st); pTrigger->wBeginYear = st.wYear; pTrigger->wBeginMonth = st.wMonth; pTrigger->wBeginDay = st.wDay; DateTime_GetSystemtime(hwndTimePick, &st); pTrigger->wStartHour = st.wHour; pTrigger->wStartMinute = st.wMinute; } //+--------------------------------------------------------------------------- // // function: InsertListViewColumn, private // // Synopsis: Inserts a column into the ListView.. // // Arguments: // // Returns: // // Modifies: // // History: 30-Jul-98 rogerg Created. // //---------------------------------------------------------------------------- BOOL InsertListViewColumn(CListView *pListView,int iColumnId,LPWSTR pszText,int fmt,int cx) { LV_COLUMN columnInfo; columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; columnInfo.fmt = fmt; columnInfo.cx = cx; columnInfo.pszText = pszText; columnInfo.iSubItem = 0; return pListView->InsertColumn(iColumnId,&columnInfo); } //+-------------------------------------------------------------------------- // // Function: InitResizeItem // // Synopsis: Setups the ResizeInfo Structure. // // !!Can either pass in a ParentScreenRect or // function will calculate. If passing in // make sure you don't include the NC area // of the window. See code below GetClientRect on parent // then ClientToScreen. // // Arguments: // // Modifies: // // History: 30-07-1998 rogerg // //--------------------------------------------------------------------------- BOOL InitResizeItem(int iCtrlId,DWORD dlgResizeFlags,HWND hwndParent, LPRECT pParentClientRect,DLGRESIZEINFO *pDlgResizeInfo) { RECT rectCtrl; RECT rectLocalParentScreenRect; Assert(pDlgResizeInfo); Assert(0 == pParentClientRect->left); // catch any case not handing in ClientRect. pDlgResizeInfo->iCtrlId = -1; // set ctrlId to -1 so GetDlgItem will fail in resize // if dont' have parentScreenRect get it ourselves if (!pParentClientRect) { pParentClientRect = &rectLocalParentScreenRect; if (!GetClientRect(hwndParent,&rectLocalParentScreenRect)) { AssertSz(0,"Unable to get Parent Rects"); return FALSE; } } Assert(pParentClientRect); if (!GetWindowRect(GetDlgItem(hwndParent,iCtrlId),&rectCtrl)) { AssertSz(0,"Failed to GetWindowRect"); return FALSE; } MapWindowPoints(NULL,hwndParent,(LPPOINT) &rectCtrl,2); pDlgResizeInfo->iCtrlId = iCtrlId; pDlgResizeInfo->hwndParent = hwndParent; pDlgResizeInfo->dlgResizeFlags = dlgResizeFlags; // calc the offsets pDlgResizeInfo->rectParentOffsets.left = rectCtrl.left - pParentClientRect->left; pDlgResizeInfo->rectParentOffsets.top = rectCtrl.top - pParentClientRect->top; pDlgResizeInfo->rectParentOffsets.right = pParentClientRect->right - rectCtrl.right; pDlgResizeInfo->rectParentOffsets.bottom = pParentClientRect->bottom - rectCtrl.bottom; return TRUE; } //+-------------------------------------------------------------------------- // // Function: ResizeItems // // Synopsis: Resizes the Item. // // // Arguments: // // Modifies: // // History: 30-07-1998 rogerg // //--------------------------------------------------------------------------- void ResizeItems(ULONG cbNumItems,DLGRESIZEINFO *pDlgResizeInfo) { RECT rectLocalParentClientCoord; // used if caller doesn't pass in parent coords. DWORD dlgResizeFlags; LPRECT prectOffsets; RECT rectClient; HWND hwndCtrl; HWND hwndLastParent = NULL; LPRECT prectParentClientCoords = NULL; ULONG ulCount; DLGRESIZEINFO *pCurDlgResizeInfo; int x,y,cx,cy; if (!pDlgResizeInfo) { Assert(pDlgResizeInfo); } for (ulCount = 0; ulCount < cbNumItems; ulCount++) { pCurDlgResizeInfo = &(pDlgResizeInfo[ulCount]); dlgResizeFlags = pCurDlgResizeInfo->dlgResizeFlags; prectOffsets = &(pCurDlgResizeInfo->rectParentOffsets); // if not pinright or pin bottom there is nothing // to do. if (!(dlgResizeFlags & DLGRESIZEFLAG_PINRIGHT) && !(dlgResizeFlags & DLGRESIZEFLAG_PINBOTTOM) ) { continue; } if (NULL == prectParentClientCoords || (hwndLastParent != pCurDlgResizeInfo->hwndParent)) { prectParentClientCoords = &rectLocalParentClientCoord; if (!GetClientRect(pCurDlgResizeInfo->hwndParent,&rectLocalParentClientCoord)) { prectParentClientCoords = NULL; // if GetClientRect failed for a recalc on next item continue; } hwndLastParent = pCurDlgResizeInfo->hwndParent; // set lastparent now that we calc'd the rect. } Assert(prectParentClientCoords); hwndCtrl = GetDlgItem(pCurDlgResizeInfo->hwndParent,pCurDlgResizeInfo->iCtrlId); if ( (NULL == hwndCtrl) || !(GetWindowRect(hwndCtrl,&rectClient)) ) { continue; } // get current values x = (prectParentClientCoords->left + prectOffsets->left); y = (prectParentClientCoords->top + prectOffsets->top); cx = WIDTH(rectClient); cy = HEIGHT(rectClient); // if pinned both right and left adjust the width if ((dlgResizeFlags & DLGRESIZEFLAG_PINLEFT) && (dlgResizeFlags & DLGRESIZEFLAG_PINRIGHT)) { cx = prectParentClientCoords->right - (prectOffsets->right + prectOffsets->left); } // if pinned both top and bottom adjust height if ((dlgResizeFlags & DLGRESIZEFLAG_PINTOP) && (dlgResizeFlags & DLGRESIZEFLAG_PINBOTTOM)) { cy = prectParentClientCoords->bottom - (prectOffsets->bottom + prectOffsets->top); } // adjust the x position if pin right if (dlgResizeFlags & DLGRESIZEFLAG_PINRIGHT) { x = (prectParentClientCoords->right - prectOffsets->right) - cx; } // adjust the y position if pin bottom if (dlgResizeFlags & DLGRESIZEFLAG_PINBOTTOM) { y = (prectParentClientCoords->bottom - prectOffsets->bottom) - cy; } SetWindowPos(hwndCtrl, 0,x,y,cx,cy,SWP_NOZORDER | SWP_NOACTIVATE); } // now that the items are moved, loop through them again invalidating // any items with the nocopy bits flag set for (ulCount = 0; ulCount < cbNumItems; ulCount++) { pCurDlgResizeInfo = &(pDlgResizeInfo[ulCount]); if (pCurDlgResizeInfo->dlgResizeFlags & DLGRESIZEFLAG_NOCOPYBITS) { hwndCtrl = GetDlgItem(pCurDlgResizeInfo->hwndParent,pCurDlgResizeInfo->iCtrlId); if (hwndCtrl && GetClientRect(hwndCtrl,&rectClient)) { InvalidateRect(hwndCtrl,&rectClient,FALSE); } } } } //+-------------------------------------------------------------------------- // // Function: CalcListViewWidth // // Synopsis: Calcs width of listview - scroll bars // // // Arguments: // // Modifies: // // History: 30-07-1998 rogerg // //--------------------------------------------------------------------------- int CalcListViewWidth(HWND hwndList,int iDefault) { NONCLIENTMETRICSA metrics; RECT rcClientRect; metrics.cbSize = sizeof(metrics); // explicitly ask for ANSI version of SystemParametersInfo since we just // care about the ScrollWidth and don't want to conver the LOGFONT info. if (GetClientRect(hwndList,&rcClientRect) && SystemParametersInfoA(SPI_GETNONCLIENTMETRICS,sizeof(metrics),(PVOID) &metrics,0)) { // subtract off scroll bar distance rcClientRect.right -= (metrics.iScrollWidth); } else { rcClientRect.right = iDefault; // if fail, use default } return rcClientRect.right; } //+-------------------------------------------------------------------------- // // Function: SetCtrlFont // // Synopsis: Sets the appropriate font on the hwnd // based on the platform and langID passed in. // // // Arguments: // // Modifies: // // History: 25-09-1998 rogerg // //--------------------------------------------------------------------------- // Example: SetCtrlFont(hwndList,g_OSVersionInfo.dwPlatformId,g_LangIdSystem); void SetCtrlFont(HWND hwnd,DWORD dwPlatformID,LANGID langId) { // IE is in the process of cleaning up their controls as // of 8/27/98 the controls we would need to set the font on are // Edit,Static and ListBox (listView is okay). Haven't tested the Combo Box // If want to turn this on need to make sure all the proper controls // are wrapped for now we don't do anything #if _SETFONTOURSELF // if on Win95J platform need to do font substitution ourselfs. // Review what we do on Win98 if ((VER_PLATFORM_WIN32_WINDOWS == dwPlatformID) && (LANG_JAPANESE == PRIMARYLANGID(langId)) ) { SendMessage(hwnd,WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT),0); } #endif // _SETFONTOURSELF return; } //+-------------------------------------------------------------------------- // // Function: IsHwndRightToLeft // // Synopsis: determine if hwnd is right to left. // // // Arguments: // // Modifies: // // History: 04-02-1999 rogerg // //--------------------------------------------------------------------------- BOOL IsHwndRightToLeft(HWND hwnd) { LONG_PTR ExStyles; if (NULL == hwnd) { Assert(hwnd); return FALSE; } ExStyles = GetWindowLongPtr(hwnd,GWL_EXSTYLE); if (WS_EX_LAYOUTRTL & ExStyles) { // this is righ to left return TRUE; } return FALSE; } //+-------------------------------------------------------------------------- // // Function: GetDateFormatReadingFlags // // Synopsis: returns necessary flags settings for passing proper // Reading order flags to GetDateFormat() // // // Arguments: // // Modifies: // // History: 09-07-1999 rogerg // //--------------------------------------------------------------------------- DWORD GetDateFormatReadingFlags(HWND hwnd) { DWORD dwDateReadingFlags = 0; LCID locale = GetUserDefaultLCID(); // only set on NT 5.0 or higher. if ( (VER_PLATFORM_WIN32_NT == g_OSVersionInfo.dwPlatformId) && ( 5 <= g_OSVersionInfo.dwMajorVersion) ) { if ((PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC) || (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW)) { LONG_PTR dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); if ((!!(dwExStyle & WS_EX_RTLREADING)) != (!!(dwExStyle & WS_EX_LAYOUTRTL))) { dwDateReadingFlags = DATE_RTLREADING; } else { dwDateReadingFlags = DATE_LTRREADING; } } } return dwDateReadingFlags; } #ifdef _SETSECURITY //+-------------------------------------------------------------------------- // // Function: SetRegKeySecurityEveryone // // Synopsis: Gives Everyone all access to the specified RegKey. // // // Arguments: // // Modifies: // // History: 01-19-1999 rogerg // //--------------------------------------------------------------------------- BOOL SetRegKeySecurityEveryone(HKEY hKeyParent,LPCWSTR lpSubKey) { BOOL fResult = FALSE; HKEY hKey = NULL; if (VER_PLATFORM_WIN32_NT != g_OSVersionInfo.dwPlatformId) { return TRUE; } // key must be openned with WRITE_DAC if (ERROR_SUCCESS != RegOpenKeyExXp(hKeyParent, lpSubKey, REG_OPTION_OPEN_LINK, WRITE_DAC,&hKey,FALSE /*fSetSecurity*/) ) { hKey = NULL; } if (hKey) { SECURITY_DESCRIPTOR SecurityDescriptor; // Initialize an empty security descriptor and use this to set DACL. Since // no DACL list in new Security Descriptor everyone will get access to the Key. if (InitializeSecurityDescriptor(&SecurityDescriptor,SECURITY_DESCRIPTOR_REVISION)) { if (ERROR_SUCCESS == RegSetKeySecurity(hKey, (SECURITY_INFORMATION) DACL_SECURITY_INFORMATION, &SecurityDescriptor) ) { fResult = TRUE; } } RegCloseKey(hKey); } Assert(TRUE == fResult); // debugging lets find out when this fails. return fResult; } #endif // _SETSECURITY //+-------------------------------------------------------------------------- // // Function: QueryHandleException // // Synopsis: in debug prompts user how to handle the exception // return always handle. // // // Arguments: // // Modifies: // // History: 01-04-1999 rogerg // //--------------------------------------------------------------------------- extern DWORD g_dwDebugLogAsserts; // conform to logAsserts BOOL QueryHandleException(void) { #ifndef _DEBUG return EXCEPTION_EXECUTE_HANDLER; #else // _DEBUG int iMsgResult = 0; BOOL fQueryResult = EXCEPTION_EXECUTE_HANDLER; // if logging asserts just execute the handler if (g_dwDebugLogAsserts) { return EXCEPTION_EXECUTE_HANDLER; } iMsgResult = MessageBoxA(NULL, "An Exception Occured.\nWould you like to Debug this Exception?", "Exception Failure.", MB_YESNO | MB_SYSTEMMODAL); if (iMsgResult == IDYES) { fQueryResult = EXCEPTION_CONTINUE_SEARCH; } // ask the User what they want to do return fQueryResult; #endif // _DEBUG } // convert a hex char to an int - used by str to guid conversion // we wrote our own, since the ole one is slow, and requires ole32.dll // we use ansi strings here, since guids won't get internationalized int GetDigit(LPSTR lpstr) { char ch = *lpstr; if (ch >= '0' && ch <= '9') return(ch - '0'); if (ch >= 'a' && ch <= 'f') return(ch - 'a' + 10); if (ch >= 'A' && ch <= 'F') return(ch - 'A' + 10); return(0); } // walk the string, writing pairs of bytes into the byte stream (guid) // we need to write the bytes into the byte stream from right to left // or left to right as indicated by fRightToLeft void ConvertField(LPBYTE lpByte,LPSTR * ppStr,int iFieldSize,BOOL fRightToLeft) { int i; for (i=0;i