|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999.
//
// File: srchutil.cxx
//
// Contents:
//
// History: 15 Aug 1996 DLee Created
//
//--------------------------------------------------------------------------
#include "pch.cxx"
#pragma hdrstop
void SetReg( WCHAR const * pwcName, WCHAR const * pwcValue) { HKEY hKeyParent;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,CISEARCH_PARENT_REG_KEY,0, KEY_ALL_ACCESS,&hKeyParent)) { DWORD dwDisp; HKEY hKey;
if (ERROR_SUCCESS == RegCreateKeyEx(hKeyParent,CISEARCH_REG_SUBKEY,0,L"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,0,&hKey,&dwDisp)) { RegSetValueEx(hKey,pwcName,0,REG_SZ,(LPBYTE) pwcValue, sizeof(WCHAR) * (wcslen(pwcValue) + 1)); RegCloseKey(hKey); } RegCloseKey(hKeyParent); } } //SetReg
BOOL GetReg( WCHAR const * pwcName, WCHAR * pwcValue, DWORD * pdwSize) { BOOL fOk = FALSE; HKEY hKeyParent;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,CISEARCH_PARENT_REG_KEY,0, KEY_ALL_ACCESS,&hKeyParent)) { DWORD dwDisp; HKEY hKey;
if (ERROR_SUCCESS == RegCreateKeyEx(hKeyParent,CISEARCH_REG_SUBKEY,0,L"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,0,&hKey,&dwDisp)) { DWORD dwType; if (ERROR_SUCCESS == RegQueryValueEx(hKey,pwcName,0,&dwType, (LPBYTE) pwcValue,pdwSize)) fOk = TRUE;
RegCloseKey(hKey); } RegCloseKey(hKeyParent); }
return fOk; } //GetReg
LCID GetRegLCID( WCHAR const * pwcName, LCID defLCID ) { WCHAR awc[100]; DWORD dw = sizeof awc / sizeof awc[0];
if (GetReg(pwcName,awc,&dw)) return _wtoi(awc); else return defLCID; } //GetRegLCID
void SetRegLCID( WCHAR const * pwcName, LCID lcid ) { WCHAR awc[20];
// itow is not in all C runtimes _itow(iValue,awc,10);
swprintf( awc, L"%d", lcid ); SetReg( pwcName, awc ); } //SetRegLCID
int GetRegInt( WCHAR const * pwcName, int iDef) { WCHAR awc[100]; DWORD dw = sizeof awc / sizeof awc[0];
if (GetReg(pwcName,awc,&dw)) return _wtoi(awc); else return iDef; } //GetRegInt
void SetRegInt( WCHAR const * pwcName, int iValue) { WCHAR awc[20];
// itow is not in all C runtimes _itow(iValue,awc,10);
swprintf( awc, L"%d", iValue ); SetReg( pwcName, awc ); } //SetRegInt
BOOL IsSpecificClass( HWND hwnd, WCHAR const * pwcClass) { WCHAR awcClass[60];
GetClassName(hwnd,awcClass,(sizeof awcClass / sizeof WCHAR) - 1);
return !wcscmp( awcClass, pwcClass ); } //IsSpecificClass
int GetLineHeight( HWND hwnd, HFONT hFont) { if (hFont == 0) hFont = (HFONT) SendMessage(hwnd, WM_GETFONT, 0, 0);
HDC hdc; int iHeight=0;
if (hdc = GetDC(hwnd)) { HFONT hOldFont; if (hOldFont = (HFONT) SelectObject(hdc,hFont)) { TEXTMETRIC tm; GetTextMetrics(hdc,&tm); iHeight = (tm.tmHeight + 2 * tm.tmExternalLeading); SelectObject(hdc,hOldFont); } ReleaseDC(hwnd,hdc); }
return iHeight; } //GetLineHeight
int GetAvgWidth( HWND hwnd, HFONT hFont) { if (hFont == 0) hFont = (HFONT) SendMessage(hwnd, WM_GETFONT, 0, 0);
HDC hdc; LONG cpWidth = 0;
if (hdc = GetDC(hwnd)) { HFONT hOldFont; if (hOldFont = (HFONT) SelectObject(hdc,hFont)) { TEXTMETRIC tm; GetTextMetrics(hdc,&tm); cpWidth = tm.tmAveCharWidth; SelectObject(hdc,hOldFont); } ReleaseDC(hwnd,hdc); }
return cpWidth; } //GetAvgWidth
INT_PTR DoModalDialog( DLGPROC fp, HWND hParent, WCHAR * pwcName, LPARAM lParam) { return DialogBoxParam(MyGetWindowInstance(hParent), pwcName, hParent, fp, lParam); } //DoModalDialog
void SaveWindowRect( HWND hwnd, WCHAR const * pwc ) { if (! (IsZoomed(hwnd) || IsIconic(hwnd))) { RECT rc; GetWindowRect(hwnd,&rc);
WCHAR awc[100]; swprintf(awc,L"%d %d %d %d",rc.left,rc.top,rc.right,rc.bottom);
SetReg( pwc, awc ); } } //SaveWindowRect
BOOL LoadWindowRect( int * left, int * top, int * right, int * bottom, WCHAR const * pwc ) { WCHAR awc[100]; DWORD dw = sizeof awc / sizeof awc[0];
if ( GetReg( pwc, awc, &dw ) ) { swscanf(awc,L"%d %d %d %d",left,top,right,bottom); *right = *right - *left; *bottom = *bottom - *top; return TRUE; } else { *left = *top = *right = *bottom = CW_USEDEFAULT; return FALSE; } } //LoadWindowRect
int GetWindowState( BOOL bApp) { WCHAR awcValue[100],awcBuf[100];
if (bApp) wcscpy(awcBuf,L"main"); else wcscpy(awcBuf,L"mdi");
wcscat(awcBuf,L"-state");
DWORD dw = sizeof awcValue / sizeof awcValue[0]; int iState;
if (GetReg(awcBuf,awcValue,&dw)) iState = awcValue[0] - L'0'; else iState = 1;
return iState; } //GetWindowState
void PassOnToEdit( UINT msg, WPARAM wParam, LPARAM lParam) { HWND hwndActive = GetFocus();
if ( 0 != hwndActive ) { WCHAR awcBuf[60]; int r = GetClassName(hwndActive,awcBuf,(sizeof awcBuf / sizeof WCHAR) - 1);
if ( 0 == r ) return;
if ( ( !_wcsicmp( awcBuf, L"Edit" ) ) || ( !_wcsicmp( awcBuf, L"RichEdit" ) ) ) SendMessage( hwndActive, msg, wParam, lParam); } } //PassOnToEdit
void WINAPI CenterDialog( HWND hdlg) { RECT rcParent; RECT rc;
GetWindowRect(hdlg,(LPRECT) &rc); GetWindowRect(GetParent(hdlg),(LPRECT) &rcParent);
LONG xbias = rcParent.left + (rcParent.right - rcParent.left)/2; LONG ybias = rcParent.top + (rcParent.bottom - rcParent.top)/2; LONG lWidth = rc.right - rc.left; LONG lHeight = rc.bottom - rc.top;
MoveWindow(hdlg, xbias - lWidth/2, ybias - lHeight/2, lWidth,lHeight,FALSE); } //CenterDialog
//+---------------------------------------------------------------------------
//
// Function: ConvertGroupingStringToInt
//
// Synopsis: Converts a grouping string from the registry to an integer,
// as required by the Win32 number formatting API
//
// History: 5-Feb-99 dlee Stole from the Win32 implementation
//
//----------------------------------------------------------------------------
int ConvertGroupingStringToInt( WCHAR const * pwcGrouping ) { XGrowable<WCHAR> xDest( 1 + wcslen( pwcGrouping ) ); WCHAR * pDest = xDest.Get();
//
// Filter out all non-numeric values and all zero values.
// Store the result in the destination buffer.
//
WCHAR const * pSrc = pwcGrouping;
while (0 != *pSrc) { if ( ( *pSrc < L'1' ) || ( *pSrc > L'9' ) ) { pSrc++; } else { if (pSrc != pDest) *pDest = *pSrc;
pSrc++; pDest++; } }
//
// Make sure there is something in the destination buffer.
// Also, see if we need to add a zero in the case of 3;2 becomes 320.
//
if ( ( pDest == xDest.Get() ) || ( *(pSrc - 1) != L'0' ) ) { *pDest = L'0'; pDest++; }
// Null terminate the buffer.
*pDest = 0;
// Convert the string to an integer.
return _wtoi( xDest.Get() ); } //ConvertGroupingStringToInt
void LoadNumberFormatInfo( NUMBERFMT & rFormat) { LCID lcid = GetUserDefaultLCID();
WCHAR awcBuf[cwcBufSize];
// Get the number of decimal digits.
GetLocaleInfo(lcid,LOCALE_IDIGITS,awcBuf,cwcBufSize); rFormat.NumDigits = _wtoi(awcBuf);
// Get the leading zero in decimal fields option.
GetLocaleInfo(lcid,LOCALE_ILZERO,awcBuf,cwcBufSize); rFormat.LeadingZero = _wtoi(awcBuf);
// Get the negative ordering.
GetLocaleInfo(lcid,LOCALE_INEGNUMBER,awcBuf,cwcBufSize); rFormat.NegativeOrder = _wtoi(awcBuf);
// Get the grouping left of the decimal.
GetLocaleInfo(lcid,LOCALE_SGROUPING,awcBuf,cwcBufSize); rFormat.Grouping = ConvertGroupingStringToInt( awcBuf );
// Get the decimal separator.
GetLocaleInfo(lcid,LOCALE_SDECIMAL,awcBuf,cwcBufSize); rFormat.lpDecimalSep = new WCHAR[wcslen(awcBuf) + 1]; wcscpy(rFormat.lpDecimalSep,awcBuf);
// Get the thousand separator.
GetLocaleInfo(lcid,LOCALE_STHOUSAND,awcBuf,cwcBufSize); rFormat.lpThousandSep = new WCHAR[wcslen(awcBuf) + 1]; wcscpy(rFormat.lpThousandSep,awcBuf); } //LoadNumberFormatInfo
void FreeNumberFormatInfo( NUMBERFMT & rFormat) { delete rFormat.lpDecimalSep; delete rFormat.lpThousandSep; } //FreeNumberFormatInfo
void SearchError( HWND hParent, ULONG dwErrorID, WCHAR const * pwcTitle) { CResString str( dwErrorID ); MessageBox( hParent, str.Get(), pwcTitle, MB_OK | MB_ICONEXCLAMATION ); } //SearchError
void PutInClipboard( WCHAR const * pwcBuffer ) { if ( OpenClipboard( App.AppWindow() ) ) { EmptyClipboard();
HGLOBAL hglbCopy = GlobalAlloc( GMEM_DDESHARE, ( wcslen( pwcBuffer ) + 1 ) * sizeof WCHAR );
if ( 0 != hglbCopy ) { WCHAR *pwc = (WCHAR *) GlobalLock( hglbCopy ); wcscpy( pwc, pwcBuffer ); GlobalUnlock( hglbCopy ); SetClipboardData( CF_UNICODETEXT, hglbCopy ); }
CloseClipboard(); } } //PutInClipboard
BOOL GetRegEditor( WCHAR const * pwcName, WCHAR * pwcValue, DWORD * pdwSize) { BOOL fOk = FALSE; HKEY hKeyParent;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,L"software\\microsoft",0, KEY_ALL_ACCESS,&hKeyParent)) { DWORD dwDisp; HKEY hKey;
if (ERROR_SUCCESS == RegCreateKeyEx(hKeyParent,L"Windiff",0,L"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,0,&hKey,&dwDisp)) { DWORD dwType; if (ERROR_SUCCESS == RegQueryValueEx(hKey,pwcName,0,&dwType, (LPBYTE) pwcValue,pdwSize)) fOk = TRUE;
RegCloseKey(hKey); } RegCloseKey(hKeyParent); }
return fOk; } //GetRegEditor
void FormatSrchError( SCODE sc, WCHAR * pwc, LCID lcid ) { LCID SaveLCID = GetThreadLocale(); SetThreadLocale( lcid );
ULONG Win32status = sc; if ( (Win32status & (FACILITY_WIN32 << 16)) == (FACILITY_WIN32 << 16) ) Win32status &= ~( 0x80000000 | (FACILITY_WIN32 << 16) );
if ( ! FormatMessage( FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle(L"query.dll"), sc, 0, pwc, MAX_PATH, 0 ) ) { //
// Try looking up the error in the Win32 list of error codes
//
if ( ! FormatMessage( FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle(L"kernel32.dll"), Win32status, 0, pwc, MAX_PATH, 0 ) ) { swprintf( pwc, L"0x%x", sc ); } }
SetThreadLocale(SaveLCID); } //FormatSrchError
BOOL CopyURL( WCHAR const * pwcURL, WCHAR * awcTempName ) { WCHAR const * pwcSlash = wcsrchr( pwcURL, L'/' );
if ( 0 == pwcSlash ) return FALSE;
pwcSlash++;
DWORD cwc = GetTempPath( MAX_PATH, awcTempName );
if ( 0 == cwc || cwc > MAX_PATH ) return FALSE;
wcscat( awcTempName, pwcSlash );
XIHandle xhI( InternetOpenW( L"srch", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0 ) ); if ( xhI.IsNull() ) return FALSE;
XIHandle xhUrl( InternetOpenUrlW( xhI.Get(), pwcURL, 0, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI, 0 ) );
if ( xhUrl.IsNull() ) return FALSE;
FILE * fp = _wfopen( awcTempName, L"wb" );
if ( 0 == fp ) return FALSE;
char ac[ 1024 * 16 ];
do { DWORD cbRead = 0; BOOL fOK = InternetReadFile( xhUrl.Get(), ac, sizeof ac, &cbRead ); if ( !fOK ) { fclose( fp ); return FALSE; }
if ( 0 == cbRead ) break;
fwrite( ac, 1, cbRead, fp ); } while( TRUE );
fclose( fp );
return TRUE; } //CopyURL
BOOL InvokeBrowser( WCHAR const * pwcFilePath, DBCOMMANDTREE * prstQuery ) { WCHAR awcTempFile[MAX_PATH]; BOOL fDeleteWhenDone = FALSE;
if ( !_wcsnicmp( pwcFilePath, L"file:", 5 ) ) pwcFilePath += 5; else if ( !_wcsnicmp( pwcFilePath, L"http:", 5 ) ) { if ( !CopyURL( pwcFilePath, awcTempFile ) ) return FALSE;
pwcFilePath = awcTempFile; fDeleteWhenDone = TRUE; }
BOOL fOK = TRUE;
CQueryResult *pResult = new CQueryResult( pwcFilePath, prstQuery, fDeleteWhenDone );
// call internal mdi browser
if (pwcFilePath) { HWND h = App.CreateBrowser( pwcFilePath, (LPARAM) pResult ); if ( 0 == h ) { WCHAR awcError[ MAX_PATH ]; FormatSrchError( App.BrowseLastError(), awcError, App.GetLocale() ); WCHAR awcMsg[ MAX_PATH ]; CResString strErr( IDS_ERR_CANT_BROWSE_FILE ); swprintf( awcMsg, strErr.Get(), awcError ); MessageBox( App.AppWindow(), awcMsg, pwcFilePath, MB_OK|MB_ICONEXCLAMATION ); fOK = FALSE; } }
return fOK; } //InvokeBrowser
void ExecApp( WCHAR const * pwcCmd) { STARTUPINFO si; memset( &si, 0, sizeof si ); si.cb = sizeof si; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWDEFAULT;
PROCESS_INFORMATION pi;
CreateProcess( 0, (WCHAR *) pwcCmd, 0, 0, FALSE, 0, 0, 0, &si, &pi ); } //ExecApp
BOOL ViewFile( WCHAR const * pwcPath, enumViewFile eViewType, int iLineNumber, DBCOMMANDTREE * prstQuery ) { BOOL fOK = TRUE; WCHAR awcCmd[MAX_PATH + cwcBufSize]; DWORD cbCmd = sizeof awcCmd / sizeof awcCmd[0];
if ( fileOpen == eViewType ) { HINSTANCE hinst = ShellExecute( HWND_DESKTOP, 0, pwcPath, 0, 0, SW_SHOWNORMAL ); if ( 32 > (DWORD_PTR) hinst ) { // if no app is registered for this extension, use notepad
wcscpy( awcCmd, L"notepad " ); wcscat( awcCmd, pwcPath ); ExecApp( awcCmd ); } } else if ( fileBrowse == eViewType ) { fOK = InvokeBrowser( (WCHAR *) pwcPath, prstQuery ); } else if ( fileEdit == eViewType ) { WCHAR awcEditor[ MAX_PATH ];
if ( GetReg( CISEARCH_REG_EDITOR, awcEditor, &cbCmd ) ) { // cool -- use it.
} else { // try to use windiff's configuration
cbCmd = sizeof awcCmd; if ( GetRegEditor( L"Editor", awcEditor, &cbCmd ) ) {
WCHAR *p = wcsstr( awcEditor, L"%p" ); if ( p ) *(p+1) = L's'; p = wcsstr( awcEditor, L"%l" ); if ( p ) *(p+1) = L'd'; } else { //wcscpy( awcEditor, L"s %ws -#%d" );
// no editor configured -- open the file
return ViewFile( pwcPath, fileOpen, iLineNumber, prstQuery ); } }
TRY { swprintf( awcCmd, awcEditor, pwcPath, iLineNumber ); ExecApp( awcCmd ); } CATCH( CException, e ) { fOK = FALSE; } END_CATCH; }
return fOK; } //ViewFile
BOOL GetCatListItem( const XGrowable<WCHAR> & const_xCatList, unsigned iItem, WCHAR * pwszMachine, WCHAR * pwszCatalog, WCHAR * pwszScope, BOOL & fDeep ) { XGrowable<WCHAR> xCatList = const_xCatList;
Win4Assert( pwszMachine && pwszCatalog && pwszScope ); *pwszMachine = *pwszCatalog = *pwszScope = 0; fDeep = FALSE;
unsigned ii; WCHAR * pStart = xCatList.Get(); for( ii = 0; ii < iItem; ii++ ) { pStart = wcschr( pStart, L';' ); if ( pStart ) { pStart++; } else break;
if ( 0 == *pStart ) { break; } }
if ( 0 == pStart || 0 == *pStart ) { return FALSE; }
WCHAR * pEnd;
// machine
pEnd = wcschr( pStart, L',' ); if ( !pEnd ) { return FALSE; } *pEnd = 0; wcscpy( pwszMachine, pStart ); pStart = pEnd + 1;
// catalog
pEnd = wcschr( pStart, L',' ); if ( !pEnd ) { return FALSE; } *pEnd = 0; wcscpy( pwszCatalog, pStart ); pStart = pEnd + 1;
// scope
pEnd = wcschr( pStart, L',' ); if ( !pEnd ) { return FALSE; } *pEnd = 0; wcscpy( pwszScope, pStart ); pStart = pEnd + 1;
// depth
fDeep = ( L'd' == *pStart || L'D' == *pStart );
return TRUE; }
|