// // CApplicationWindow.CPP // // Application Window Class // #include "stdafx.h" #include #include #include "commdlg.h" #include "resource.h" #include "CApplicationWindow.h" #include "CFindDialog.h" #define CAPPLICATIONWINDOWCLASS TEXT("CApplicationWindowClass") #define WINDOWMENU 1 BOOL g_fCApplicationWindowClassRegistered = FALSE; BOOL g_fCApplicationWindowDestroyed = FALSE; // these are used to track the next occurrence of the phrases LPTSTR g_pszDispatch; LPTSTR g_pszDispatch2; LPTSTR g_pszCompleted; // // Constructor // CApplicationWindow::CApplicationWindow( ) { BOOL b; LPTSTR psz; LONG sx = GetSystemMetrics( SM_CXFULLSCREEN ); LPTSTR lpCmdLine; Cleanup( TRUE ); if ( !g_fCApplicationWindowClassRegistered ) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)CApplicationWindow::WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = LoadIcon(g_hInstance, (LPCTSTR) IDI_CLUSLOG ); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH) COLOR_GRAYTEXT; //NULL; wcex.lpszMenuName = (LPCSTR)IDC_SOL; wcex.lpszClassName = CAPPLICATIONWINDOWCLASS; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR) IDI_SMALL ); RegisterClassEx(&wcex); } HANDLE hFile; hFile = CreateFile( "filter.txt", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if ( hFile != INVALID_HANDLE_VALUE ) { LONG nLength = GetFileSize( hFile, NULL ); nLength++; // one for NULL g_pszFilters = (LPTSTR) LocalAlloc( LPTR, nLength ); if ( g_pszFilters ) { DWORD dwRead; // dummy ReadFile( hFile, g_pszFilters, nLength, &dwRead, NULL ); g_pszFilters[nLength-1] = 0; CloseHandle( hFile ); g_nComponentFilters = 0; psz = g_pszFilters; while ( psz < &g_pszFilters[nLength-1] ) { LPTSTR pszStart = psz; while ( *psz && *psz != 13 ) { psz++; } psz += 2; g_nComponentFilters++; } g_pfSelectedComponent = (BOOL*) LocalAlloc( LPTR, g_nComponentFilters * sizeof(BOOL) ); } } _hWnd = CreateWindowEx( WS_EX_ACCEPTFILES, CAPPLICATIONWINDOWCLASS, TEXT("Cluster Log Analyzer"), WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, (LPVOID) this); if (!_hWnd) { return; } _hMenu = CreatePopupMenu( ); MENUITEMINFO mii; ZeroMemory( &mii, sizeof(mii) ); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID; mii.fState = MFS_CHECKED; mii.wID = IDM_FIRST_CS_FILTER ; psz = g_pszFilters; if ( psz ) { while ( *psz && mii.wID < IDM_LAST_CS_FILTER ) { mii.dwTypeData = psz; while ( *psz && *psz != 13 ) { psz++; } if ( *psz == 13 ) { *psz = 0; psz++; if ( *psz ) { psz++; } } mii.wID++; mii.cch = (UINT)(psz - mii.dwTypeData); b = InsertMenuItem( _hMenu, -1, TRUE, &mii ); } } HMENU hMenu = GetSubMenu( GetMenu( _hWnd ), 2 ); b = AppendMenu( hMenu, MF_POPUP, (UINT_PTR) _hMenu, "&Cluster Service" ); DrawMenuBar( _hWnd ); ShowWindow( _hWnd, SW_SHOW ); UpdateWindow( _hWnd ); lpCmdLine = GetCommandLine( ); if ( lpCmdLine ) { if ( lpCmdLine[0] == '\"' ) { lpCmdLine++; while ( *lpCmdLine && *lpCmdLine != '\"' ) { lpCmdLine++; } if ( *lpCmdLine ) { lpCmdLine++; } if ( *lpCmdLine ) { lpCmdLine++; } } else { while ( *lpCmdLine && *lpCmdLine != 32 ) { lpCmdLine++; } if ( *lpCmdLine ) { lpCmdLine++; } } while ( lpCmdLine[0] ) { LPSTR psz = strchr( lpCmdLine, 32 ); if ( psz ) { *psz = 0; } if ( lpCmdLine[1] != ':' && lpCmdLine[1] != '\\' ) { LPTSTR pszFilename = (LPTSTR) LocalAlloc( LMEM_FIXED, MAX_PATH * sizeof(TCHAR) ); if ( pszFilename ) { DWORD dwRead; dwRead = GetCurrentDirectory( MAX_PATH, pszFilename ); if ( dwRead >= MAX_PATH ) { LocalFree( pszFilename ); pszFilename = (LPTSTR) LocalAlloc( LMEM_FIXED, ( dwRead + MAX_PATH ) * sizeof(TCHAR) ); if ( pszFilename ) { dwRead = GetCurrentDirectory( MAX_PATH, pszFilename ); } } if ( pszFilename && dwRead != 0 ) { strcat( pszFilename, TEXT("\\") ); strcat( pszFilename, lpCmdLine ); _LoadFile( pszFilename ); } } else { break; } } if ( *lpCmdLine ) { _LoadFile( lpCmdLine ); } lpCmdLine += lstrlen( lpCmdLine ); if ( psz ) { lpCmdLine++; *psz = 32; } } } } // // Destructor // CApplicationWindow::~CApplicationWindow( ) { Cleanup( ); ShowWindow( _hWnd, SW_HIDE ); } // // // HRESULT CApplicationWindow::Cleanup( BOOL fInitializing // = FALSE ) { if ( !fInitializing ) { for( ULONG nFile = 0; nFile < _nFiles; nFile++ ) { LocalFree( _pFiles[ nFile ] ); LocalFree( _pszFilenames[ nFile ] ); LocalFree( _pNodes[ nFile ] ); } } _nFiles = 0; _cTotalLineCount = 0; _fVertSBVisible = FALSE; _uStartSelection = 0; _uEndSelection = 0; _uPointer = 0; _pLines = 0; ZeroMemory( &_LineFinder, sizeof(_LineFinder) ); _uFinderLength = 0; ShowScrollBar( _hWnd, SB_VERT, FALSE ); return S_OK; } // // _CalculateOffset( ) // HRESULT CApplicationWindow::_CalculateOffset( FILETIME * pftOper1, FILETIME * pftOper2, INT * pnDir, FILETIME * pftOffset ) { *pnDir = CompareFileTime( pftOper1, pftOper2 ); if ( *pnDir > 0 ) { pftOffset->dwHighDateTime = pftOper1->dwHighDateTime - pftOper2->dwHighDateTime; pftOffset->dwLowDateTime = pftOper1->dwLowDateTime - pftOper2->dwLowDateTime; if ( pftOper1->dwLowDateTime < pftOper2->dwLowDateTime ) { pftOffset->dwHighDateTime++; } } else if ( *pnDir < 0 ) { pftOffset->dwHighDateTime = pftOper2->dwHighDateTime - pftOper1->dwHighDateTime; pftOffset->dwLowDateTime = pftOper2->dwLowDateTime - pftOper1->dwLowDateTime; if ( pftOper1->dwLowDateTime > pftOper2->dwLowDateTime ) { pftOffset->dwHighDateTime--; } } return S_OK; } // // _FindSequencePoint( ) // BOOL CApplicationWindow::_FindSequencePoint( LPTSTR * ppszSequence, ULONG * pnSequence ) { while( *ppszSequence ) { if ( *ppszSequence > g_pszDispatch ) { g_pszDispatch = strstr( *ppszSequence, "dispatching seq " ) - 1; } if ( *ppszSequence > g_pszCompleted ) { g_pszCompleted = strstr( *ppszSequence, "completed update seq " ) - 1; } if ( *ppszSequence > g_pszDispatch2 ) { g_pszDispatch2 = strstr( *ppszSequence, "Dispatching seq " ) - 1; } if ( g_pszDispatch < g_pszCompleted ) { (*ppszSequence) = g_pszDispatch + sizeof("dispatching seq ") - 1; if ( pnSequence ) { *pnSequence = atol ( *ppszSequence ); (*pnSequence) *= 3; } break; } if ( g_pszDispatch2 < g_pszCompleted ) { (*ppszSequence) = g_pszDispatch2 + sizeof("Dispatching seq ") - 1; if ( pnSequence ) { *pnSequence = atol ( *ppszSequence ); (*pnSequence) *= 3; (*pnSequence)++; } break; } if ( g_pszCompleted + 1 != NULL ) { (*ppszSequence) = g_pszCompleted + sizeof("completed update seq ") - 1; if ( pnSequence ) { *pnSequence = atol ( *ppszSequence ); (*pnSequence) *= 3; (*pnSequence)++; (*pnSequence)++; } break; } *ppszSequence = NULL; return FALSE; } return TRUE; } // // _RetrieveTimeDate( ) // HRESULT CApplicationWindow::_RetrieveTimeDate( LPTSTR pszCurrent, SYSTEMTIME * pst, LPTSTR * ppszFinal ) { if ( ppszFinal ) { *ppszFinal = pszCurrent; } // Find the thread and process IDs while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent != 10 ) { pszCurrent++; } if ( *pszCurrent != ':' ) return S_FALSE; pszCurrent++; if ( *pszCurrent != ':' ) return S_FALSE; pszCurrent++; // Find Time/Date stamp which is: // ####/##/##-##:##:##.### pst->wYear = (WORD) atol( pszCurrent ); while ( *pszCurrent >= '0' && *pszCurrent <= '9' ) { pszCurrent++; } if ( *pszCurrent == '-' ) { // // The "year" we got above should really be the day. // We'll replace the year with zero and the month with one. // pst->wDay = pst->wYear; pst->wYear = 0; pst->wMonth = 1; goto SkipDate; } if ( *pszCurrent != '/' ) return S_FALSE; pszCurrent++; pst->wMonth = (WORD) atol( pszCurrent ); while ( *pszCurrent >= '0' && *pszCurrent <= '9' ) { pszCurrent++; } if ( *pszCurrent != '/' ) return S_FALSE; pszCurrent++; pst->wDay = (WORD) atol( pszCurrent ); while ( *pszCurrent >= '0' && *pszCurrent <= '9' ) { pszCurrent++; } if ( *pszCurrent != '-' ) return S_FALSE; SkipDate: pszCurrent++; pst->wHour = (WORD) atol( pszCurrent ); while ( *pszCurrent >= '0' && *pszCurrent <= '9' ) { pszCurrent++; } if ( *pszCurrent != ':' ) return S_FALSE; pszCurrent++; pst->wMinute = (WORD) atol( pszCurrent ); while ( *pszCurrent >= '0' && *pszCurrent <= '9' ) { pszCurrent++; } if ( *pszCurrent != ':' ) return S_FALSE; pszCurrent++; pst->wSecond = (WORD) atol( pszCurrent ); while ( *pszCurrent >= '0' && *pszCurrent <= '9' ) { pszCurrent++; } if ( *pszCurrent != '.' ) return S_FALSE; pszCurrent++; pst->wMilliseconds = (WORD) atol( pszCurrent ); while ( *pszCurrent >= '0' && *pszCurrent <= '9' ) { pszCurrent++; } if ( ppszFinal ) { *ppszFinal = pszCurrent; } return S_OK; } // // _GetFilename( ) // HRESULT CApplicationWindow::_GetFilename( LPTSTR pszFilename, LPTSTR pszFilenameOut, LONG * pcch ) { LONG cch = 0; if ( g_fShowServerNames && pszFilename[ 0 ] == '\\' && pszFilename[ 1 ] == '\\' ) { LPTSTR psz = &pszFilename[ 2 ]; while ( *psz && *psz != '\\' ) { psz++; cch++; } psz--; cch += 2; } else if ( strchr( pszFilename, '\\' ) ) { pszFilename = pszFilename + lstrlen( pszFilename ); while ( *pszFilename != '\\' ) { pszFilename--; cch++; } pszFilename++; cch--; } else { cch = lstrlen( pszFilename ); } if ( pszFilenameOut ) { if ( !pcch ) return E_POINTER; if ( cch >= *pcch ) { cch = *pcch - 1; } strncpy( pszFilenameOut, pszFilename, cch ); pszFilenameOut[ cch ] = 0; } if ( pcch ) { *pcch = cch; } return S_OK; } // // _StatusWndProc( ) // LRESULT CALLBACK CApplicationWindow::_StatusWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { return 0; } // // _CombineFiles( ) // HRESULT CApplicationWindow::_CombineFiles( ) { HRESULT hr; // general purpose HRESULT and return code BOOL b; // general purpose return BOOL ULONG nFileLineCount; // counter of the lines in the file ULONG nSequence; // ID of current sequence ULONG nNextSequence; // ID of the next squence LPTSTR pszSequence; // next sequence location LPTSTR pszCurrent; // current parse location within file BOOL fSyncPoint; // flag indicating a sync point was encountered SYSTEMTIME st; // used to convert "line time" to a filetime. FILETIME ft; // current lines filetime FILETIME ftOffset; // current filetime offset INT nDir; // offset direction MSG msg; // message pumping HWND hwndProcessing; // processing window handle HWND hwndStatus; // progress bar window handle SCROLLINFO si; // verticle scroll bar LINEPOINTER * pLastSyncPoint; // last place a sync point in other files was encountered LINEPOINTER * pInsertionPoint; // next place a node will be inserted LINEPOINTER * pNewLine; // next structure to be used as a node CWaitCursor Wait; // show the hour glass si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE; GetScrollInfo( _hWnd, SB_VERT, &si ); si.fMask = SIF_RANGE; ZeroMemory( &ftOffset, sizeof(ftOffset) ); nDir = 0; g_pszDispatch = NULL; g_pszDispatch2 = NULL; g_pszCompleted = NULL; // scan to figure out the line count of the new file nFileLineCount = 0; pszCurrent = _pFiles[ _nFiles ]; while ( *pszCurrent ) { if ( *pszCurrent == 10 ) { nFileLineCount++; } pszCurrent++; } if ( !_pLines ) { // add one more for the root node nFileLineCount++; } // allocate all the memory up front to avoid fragmenting memory as well as // descreasing the number of heap calls _pNodes[ _nFiles ] = (LINEPOINTER *) LocalAlloc( LMEM_FIXED, nFileLineCount * sizeof(LINEPOINTER) ); if ( !_pNodes[ _nFiles ] ) { return E_OUTOFMEMORY; } pNewLine = _pNodes[ _nFiles ]; if ( !_pLines ) { _pLines = pNewLine; ZeroMemory( _pLines, sizeof(LINEPOINTER) ); pNewLine++; } // Create wait modeless dialog hwndProcessing = CreateDialog( g_hInstance, MAKEINTRESOURCE(IDD_PROCESSING), _hWnd, (DLGPROC) CApplicationWindow::_StatusWndProc ); hwndStatus = GetDlgItem( hwndProcessing, IDC_P_STATUS ); SendMessage( hwndStatus, PBM_SETRANGE32, 0, nFileLineCount ); SendMessage( hwndStatus, PBM_SETPOS, 0, 0 ); SendMessage( hwndStatus, PBM_SETSTEP, 1, 0 ); SetWindowText( GetDlgItem( hwndProcessing, IDC_S_FILENAME ), _pszFilenames[ _nFiles ] ); // Find the first sync point nNextSequence = nSequence = 0; pszSequence = _pFiles[ _nFiles ]; if ( _FindSequencePoint( &pszSequence, &nNextSequence ) ) { RetrySequencing: if ( _nFiles ) { LINEPOINTER * lp = _pLines; while ( lp->pNext && nNextSequence != lp->uSequenceNumber ) { lp = lp->pNext; // pump some messages.... if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( !IsDialogMessage( g_hwndFind, &msg ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } if ( g_fCApplicationWindowDestroyed ) { return E_FAIL; // not break! } } } if ( nNextSequence == lp->uSequenceNumber ) { pszCurrent = pszSequence; while( pszCurrent >= _pFiles[ _nFiles ] && *pszCurrent != 10 ) { pszCurrent--; } pszCurrent++; hr = _RetrieveTimeDate( pszCurrent, &st, NULL ); b = SystemTimeToFileTime( &st, &ft ); _CalculateOffset( &ft, &lp->Time, &nDir, &ftOffset ); nSequence = nNextSequence - 1; } else { if ( _FindSequencePoint( &pszSequence, &nNextSequence ) ) goto RetrySequencing; nNextSequence = nSequence = 0; } } else { nSequence = nNextSequence - 1; } } nFileLineCount = 1; pszCurrent = _pFiles[ _nFiles ]; pInsertionPoint = _pLines; while ( *pszCurrent ) { LPTSTR pszStart = pszCurrent; // this will parse past the PID.TID and Time/Date hr = _RetrieveTimeDate( pszCurrent, &st, &pszCurrent ); b = SystemTimeToFileTime( &st, &ft ); // skip spaces while ( *pszCurrent == 32) { pszCurrent++; } // fill in preliminary info pNewLine->fFiltered = FALSE; pNewLine->nFile = _nFiles; pNewLine->nLine = nFileLineCount; pNewLine->psLine = pszStart; // note warning level of line // if ( _stricmp( "INFO", pszCurrent )) { pNewLine->WarnLevel = WarnLevelInfo; } else if ( _stricmp( "WARN", pszCurrent )) { pNewLine->WarnLevel = WarnLevelWarn; } else if ( _stricmp( "ERR ", pszCurrent )) { pNewLine->WarnLevel = WarnLevelError; } else { pNewLine->WarnLevel = WarnLevelUnknown; } if ( pNewLine->WarnLevel != WarnLevelUnknown ) { // skip chars, then spaces only if we found the tag while ( *pszCurrent != 32) { pszCurrent++; } while ( *pszCurrent == 32) { pszCurrent++; } } // [OPTIONAL] Cluster component which looks like: // [] if ( *pszCurrent == '[' ) { LPTSTR pszComponentTag = pszCurrent; while ( *pszCurrent && *pszCurrent != ']' && *pszCurrent >= 32 ) { pszCurrent++; } if ( *pszCurrent < 32 ) { pszCurrent = pszComponentTag; goto NoComponentTryResouce; } pszCurrent++; // found component USHORT nFilterId = 0; LONG nLen = (LONG)(pszCurrent - pszComponentTag - 2); LPTSTR psz = g_pszFilters; while ( nFilterId < g_nComponentFilters ) { if ( nLen == lstrlen( psz ) && _strnicmp( pszComponentTag + 1, psz, nLen ) == 0 ) { pNewLine->nFilterId = nFilterId + 1; if ( g_pfSelectedComponent[ nFilterId ] ) { pNewLine->fFiltered = TRUE; } break; } while ( *psz ) { psz++; } psz += 2; nFilterId++; } } else { // [OPTIONAL] If not a component, see if there is a res type NoComponentTryResouce: LPTSTR pszResType = pszCurrent; while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent >= 32 ) { pszCurrent++; } if ( *pszCurrent >= 32 ) { pszCurrent++; // found a restype pNewLine->nFilterId = g_nComponentFilters + 1; // TODO: make more dynamic if ( g_fResourceNoise ) { pNewLine->fFiltered = TRUE; } } } // Find the beggining of the next line while ( *pszCurrent && *pszCurrent != 10 ) { pszCurrent++; } if ( *pszCurrent ) { pszCurrent++; } // See if we just past a sync point if ( pszSequence && pszCurrent > pszSequence ) { fSyncPoint = TRUE; nSequence = nNextSequence; // find the next sync point _FindSequencePoint( &pszSequence, &nNextSequence ); if ( _nFiles ) { // if we are out of sync, move the insertion point ahead if ( pInsertionPoint->pNext != NULL && nSequence >= pInsertionPoint->uSequenceNumber ) { for( pLastSyncPoint = pInsertionPoint; pLastSyncPoint->pNext; pLastSyncPoint = pLastSyncPoint->pNext ) { if ( pLastSyncPoint->nFile != _nFiles && ( nSequence < pLastSyncPoint->uSequenceNumber || ( pLastSyncPoint->fSyncPoint && nSequence == pLastSyncPoint->uSequenceNumber ) ) ) { break; } } if ( pLastSyncPoint && pLastSyncPoint->pNext && nSequence == pLastSyncPoint->uSequenceNumber ) { pInsertionPoint = pLastSyncPoint; _CalculateOffset( &ft, &pInsertionPoint->Time, &nDir, &ftOffset ); } } } } else { fSyncPoint = FALSE; } // adjust time to compensate for time deviations if ( nDir > 0 ) { // if we are ahead, subtract if ( ft.dwLowDateTime - ftOffset.dwLowDateTime > ft.dwLowDateTime ) { ft.dwHighDateTime--; } ft.dwLowDateTime -= ftOffset.dwLowDateTime; ft.dwHighDateTime -= ftOffset.dwHighDateTime; } else if ( nDir < 0 ) { // if we are behind, add if ( ft.dwLowDateTime + ftOffset.dwLowDateTime < ft.dwLowDateTime ) { ft.dwHighDateTime++; } ft.dwLowDateTime += ftOffset.dwLowDateTime; ft.dwHighDateTime += ftOffset.dwHighDateTime; } // else if nDir == 0, nothing to do #if defined(_DEBUG) && defined(VERIFY_SYNC_POINTS) if ( fSyncPoint && _nFiles != 0 ) { INT n = CompareFileTime( &ft, &pInsertionPoint->Time ); if ( n != 0 ) { DebugBreak( ); } } #endif // defined(_DEBUG) && defined(VERIFY_SYNC_POINTS) // Find the place to insert it while( pInsertionPoint->pNext ) { if ( nSequence < pInsertionPoint->pNext->uSequenceNumber && pInsertionPoint->pNext->nFile != _nFiles ) { break; } INT n = CompareFileTime( &ft, &pInsertionPoint->pNext->Time ); if ( n < 0 ) break; pInsertionPoint = pInsertionPoint->pNext; } // fill-in rest of the LINEPOINTER structure pNewLine->Time = ft; pNewLine->fSyncPoint = fSyncPoint; pNewLine->uSequenceNumber = nSequence; // insert node into line list pNewLine->pNext = pInsertionPoint->pNext; pNewLine->pPrev = pInsertionPoint; if ( pInsertionPoint->pNext != NULL ) { pInsertionPoint->pNext->pPrev = pNewLine; } pInsertionPoint->pNext = pNewLine; pInsertionPoint = pNewLine; pNewLine++; // dump line counts nFileLineCount++; _cTotalLineCount++; // synchonize the scroll bar, don't redraw it if ( _cTotalLineCount > 100 && _cTotalLineCount > si.nPage ) { si.nMax = _cTotalLineCount; SetScrollInfo( _hWnd, SB_VERT, &si, FALSE ); } SendMessage( hwndStatus, PBM_STEPIT, 0, 0 ); #if defined(_DEBUG) && defined(SLOW_FILL) if ( _nFiles ) { InvalidateRect( _hWnd, NULL, TRUE ); for( ULONG a = 0; a < 999999 ; a++ ) { #endif // defined(_DEBUG) && defined(SLOW_FILL) // pump some messages.... if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( !IsDialogMessage( g_hwndFind, &msg ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } if ( g_fCApplicationWindowDestroyed ) { return E_FAIL; // not break! } } #if defined(_DEBUG) && defined(SLOW_FILL) } } #endif // defined(_DEBUG) && defined(SLOW_FILL) } DestroyWindow( hwndProcessing ); _nFiles++; if ( !_fVertSBVisible && _yWindow < (LONG)(_cTotalLineCount * _tm.tmHeight) ) { _fVertSBVisible = TRUE; EnableScrollBar( _hWnd, SB_VERT, ESB_ENABLE_BOTH ); ShowScrollBar( _hWnd, SB_VERT, TRUE ); } else if ( _fVertSBVisible && _yWindow >= (LONG)(_cTotalLineCount * _tm.tmHeight) ) { _fVertSBVisible = FALSE; //EnableScrollBar( _hWnd, SB_VERT, ESB_ENABLE_BOTH ); ShowScrollBar( _hWnd, SB_VERT, FALSE ); } si.cbSize = sizeof(si); si.fMask = SIF_RANGE; si.nMin = 0; si.nMax = _cTotalLineCount; SetScrollInfo( _hWnd, SB_VERT, &si, TRUE ); InvalidateRect( _hWnd, NULL, TRUE ); return S_OK; } // // _LoadFile( ) // HRESULT CApplicationWindow::_LoadFile( LPTSTR pszFilename ) { HRESULT hr; DWORD dwRead; HANDLE hFile; ULONG nLength; LONG xMargin; _pszFilenames[ _nFiles ] = (LPTSTR) LocalAlloc( LMEM_FIXED, ( lstrlen( pszFilename ) + 1 ) * sizeof(TCHAR) ); if ( !_pszFilenames[ _nFiles ] ) { hr = E_OUTOFMEMORY; goto Error; } strcpy( _pszFilenames[ _nFiles ], pszFilename ); _GetFilename( _pszFilenames[ _nFiles ], NULL, &xMargin ); xMargin += 7 + 2; // line number and file number xMargin *= _xSpace; if ( xMargin > _xMargin ) { _xMargin = xMargin; } hFile = CreateFile( _pszFilenames[ _nFiles ], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) { hr = HRESULT_FROM_WIN32( GetLastError( ) ); goto Error; } nLength = GetFileSize( hFile, NULL ); if ( nLength == 0xFFFFffff && GetLastError( ) != NO_ERROR ) { hr = HRESULT_FROM_WIN32( GetLastError( ) ); goto Error; } nLength++; // one for NULL #if defined(_DEBUG) _pFiles[ _nFiles ] = (LPTSTR) LocalAlloc( LPTR, nLength ); #else _pFiles[ _nFiles ] = (LPTSTR) LocalAlloc( LMEM_FIXED, nLength ); #endif if ( !_pFiles[ _nFiles ] ) { hr = E_OUTOFMEMORY; goto Error; } if ( !ReadFile( hFile, _pFiles[ _nFiles ], nLength, &dwRead, NULL ) ) { hr = HRESULT_FROM_WIN32( GetLastError( ) ); goto Error; } hr = _CombineFiles( ); Cleanup: if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); return hr; Error: if ( _pFiles[ _nFiles ] ) { LocalFree( _pFiles[ _nFiles ] ); _pFiles[ _nFiles ] = NULL; } MessageBox( _hWnd, pszFilename, TEXT("File Error"), MB_ICONEXCLAMATION | MB_OK ); goto Cleanup; } // // _PaintLine( ) // HRESULT CApplicationWindow::_PaintLine( PAINTSTRUCT * pps, LINEPOINTER * pCurrent, LONG wxStart, LONG wy, COLORREF crText, COLORREF crDark, COLORREF crNormal, COLORREF crHightlite ) { LPTSTR pszStartLine; // beginning of line (PID/TID) LPTSTR pszStartTimeDate; // beginning of time/data stamp LPTSTR pszStartComponent; // beginning of component name LPTSTR pszStartResType; // beginning of a resource component LPTSTR pszStartText; // beginning of text LPTSTR pszCurrent; // current position and beginning of text TCHAR szFilename[ 40 ]; LONG cchFilename; SIZE size; RECT rect; RECT rectResult; LONG wx = wxStart; LONG wxTextStart; if ( pCurrent->psLine ) { pszCurrent = pCurrent->psLine; // draw node number SetRect( &rect, wx, wy, wx + _xSpace * 2, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { TCHAR szBuf[ 2 ]; SetBkColor( pps->hdc, GetSysColor( COLOR_WINDOW ) ); SetTextColor( pps->hdc, GetSysColor( COLOR_WINDOWTEXT ) ); DrawText( pps->hdc, szBuf, wsprintf( szBuf, TEXT("%1u "), pCurrent->nFile ), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += 2 * _xSpace; // Draw Filename cchFilename = sizeof(szFilename)/sizeof(szFilename[0]); _GetFilename( _pszFilenames[ pCurrent->nFile ], szFilename, &cchFilename ); SetRect( &rect, wx, wy, _xMargin, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); HBRUSH hBrush; hBrush = CreateSolidBrush( crNormal ); FillRect( pps->hdc, &rect, hBrush ); DeleteObject( hBrush ); DrawText( pps->hdc, szFilename, cchFilename, &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += _xMargin - ( 7 * _xSpace - 2 * _xSpace ); // draw line number SetRect( &rect, wx, wy, wx + 7 * _xSpace, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { TCHAR szBuf[ 8 ]; SetTextColor( pps->hdc, crText ); SetBkColor( pps->hdc, crDark ); DrawText( pps->hdc, szBuf, wsprintf( szBuf, TEXT("%07.7u"), pCurrent->nLine ), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += 7 * _xSpace; SetRect( &rect, wx, wy, wx + _xSpace, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, " ", 1, &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += _xSpace; // // KB: This is what a typical cluster log line looks like. // 000003fc.00000268::1999/07/19-19:14:45.548 [EVT] Node up: 2, new UpNodeSet: 0002 // 000003fc.00000268::1999/07/19-19:14:45.548 [EVT] EvOnline : calling ElfRegisterClusterSvc // 000003fc.00000268::1999/07/19-19:14:45.548 [GUM] GumSendUpdate: queuing update type 2 context 19 // 000003fc.00000268::1999/07/19-19:14:45.548 [GUM] GumSendUpdate: Dispatching seq 2585 type 2 context 19 to node 1 // 000003fc.00000268::1999/07/19-19:14:45.548 [NM] Received update to set extended state for node 1 to 0 // 000003fc.00000268::1999/07/19-19:14:45.548 [NM] Issuing event 0. // 000003fc.00000268::1999/07/19-19:14:45.548 [GUM] GumSendUpdate: completed update seq 2585 type 2 context 19 // 0000037c.000003a0::1999/07/19-19:14:45.548 Physical Disk: AddVolume : \\?\Volume{99d8d508-39fa-11d3-a200-806d6172696f}\ 'C', 7 (11041600) // 0000037c.000003a0::1999/07/19-19:14:45.558 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d503-39fa-11d3-a200-806d6172696f}), error 170 // 0000037c.000003a0::1999/07/19-19:14:45.568 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d504-39fa-11d3-a200-806d6172696f}), error 170 // 0000037c.000003a0::1999/07/19-19:14:45.568 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d505-39fa-11d3-a200-806d6172696f}), error 170 // 0000037c.000003a0::1999/07/19-19:14:45.578 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d506-39fa-11d3-a200-806d6172696f}), error 170 // 0000037c.000003a0::1999/07/19-19:14:45.578 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d501-39fa-11d3-a200-806d6172696f}), error 1 // pszStartResType = pszStartComponent = NULL; pszStartLine = pszStartText = pszStartTimeDate = pszCurrent = pCurrent->psLine; // Find the thread and process IDs while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent >= 32 ) { pszCurrent++; } if ( *pszCurrent < 32 ) { goto DrawRestOfLine; } pszCurrent++; if ( *pszCurrent != ':' ) { goto DrawRestOfLine; } pszCurrent++; // Find Time/Date stamp which is: // ####/##/##-##:##:##.### pszStartTimeDate = pszCurrent; while ( *pszCurrent && *pszCurrent != ' ' && *pszCurrent >= 32 ) { pszCurrent++; } if ( *pszCurrent < 32 ) { goto DrawRestOfLine; } pszCurrent++; if ( pCurrent->WarnLevel != WarnLevelUnknown ) { // skip warn/info/err tag // while ( *pszCurrent != 32) { pszCurrent++; } while ( *pszCurrent == 32) { pszCurrent++; } } pszStartText = pszCurrent; // [OPTIONAL] Cluster component which looks like: // [] if ( *pszCurrent == '[' ) { while ( *pszCurrent && *pszCurrent != ']' && *pszCurrent >= 32 ) { pszCurrent++; } if ( *pszCurrent < 32 ) { goto NoComponentTryResouce; } pszCurrent++; pszStartComponent = pszStartText; pszStartText = pszCurrent; } else { // [OPTIONAL] If not a component, see if there is a res type NoComponentTryResouce: pszCurrent = pszStartText; while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent >= 32 ) { pszCurrent++; } if ( *pszCurrent >= 32 ) { pszCurrent++; pszStartResType = pszStartText; pszStartText = pszCurrent; } } // Draw PID and TID GetTextExtentPoint32( pps->hdc, pszStartLine, (int)(pszStartTimeDate - pszStartLine - 2), &size ); SetRect( &rect, wx, wy, wx + size.cx, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, pszStartLine, (int)(pszStartTimeDate - pszStartLine - 2), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += size.cx; GetTextExtentPoint32( pps->hdc, "::", 2, &size ); SetRect( &rect, wx, wy, wx + size.cx, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, "::", 2, &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += size.cx; // Draw Time/Date pszCurrent = ( pszStartComponent ? pszStartComponent : ( pszStartResType ? pszStartResType : pszStartText ) ) - 1; GetTextExtentPoint32( pps->hdc, pszStartTimeDate, (int)(pszCurrent - pszStartTimeDate), &size ); SetRect( &rect, wx, wy, wx + size.cx, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crDark ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, pszStartTimeDate, (int)(pszCurrent - pszStartTimeDate), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += size.cx; SetRect( &rect, wx, wy, wx + _xSpace, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, " ", 1, &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += _xSpace; #ifdef _DEBUG // draw sequence number SetRect( &rect, wx, wy, wx + 7 * _xSpace, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { TCHAR szBuf[ 8 ]; SetTextColor( pps->hdc, crText ); SetBkColor( pps->hdc, crNormal ); DrawText( pps->hdc, szBuf, wsprintf( szBuf, TEXT("#%7u%s"), pCurrent->uSequenceNumber,// / 2, pCurrent->fSyncPoint ? "*" : " " ), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += 9 * _xSpace; #endif // Draw component if ( pszStartComponent ) { SetRect( &rect, wx, wy, wx + 10 * _xSpace, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, " ", 10, &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } GetTextExtentPoint32( pps->hdc, pszStartComponent, (int)(pszStartText - pszStartComponent), &size ); SetRect( &rect, wx, wy, wx + size.cx, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, pszStartComponent, (int)(pszStartText - pszStartComponent), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += 10 * _xSpace; } if ( pszStartResType ) { GetTextExtentPoint32( pps->hdc, pszStartResType, (int)(pszStartText - pszStartResType), &size ); SetRect( &rect, wx, wy, wx + size.cx, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); DrawText( pps->hdc, pszStartResType, (int)(pszStartText - pszStartResType), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } wx += size.cx; } DrawRestOfLine: pszCurrent = pszStartText; wxTextStart = wx; while ( *pszCurrent && *pszCurrent != 13 ) { pszCurrent++; } SetRect( &rect, wx, wy, _xWindow, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); HBRUSH hBrush; hBrush = CreateSolidBrush( crNormal ); FillRect( pps->hdc, &rect, hBrush ); DeleteObject( hBrush ); DrawText( pps->hdc, pszStartText, (int)(pszCurrent - pszStartText), &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_EXPANDTABS ); } // See if "Finder" needs to paint on this line if ( pCurrent->nFile == _LineFinder.nFile && pCurrent->nLine == _LineFinder.nLine ) { wx = wxTextStart; if ( pszStartResType ) { GetTextExtentPoint32( pps->hdc, pszStartResType, (int)(_LineFinder.psLine - pszStartResType), &size ); wx += size.cx; } else { GetTextExtentPoint32( pps->hdc, pszStartText, (int)(_LineFinder.psLine - pszStartText), &size ); wx += size.cx; } GetTextExtentPoint32( pps->hdc, _LineFinder.psLine, _uFinderLength, &size ); SetRect( &rect, wx, wy, wx + size.cx, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crHightlite ); SetTextColor( pps->hdc, ~crHightlite ); DrawText( pps->hdc, _LineFinder.psLine, _uFinderLength, &rect, DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE ); } } wx = _xWindow; } // fill in the rest of the line SetRect( &rect, wx, wy, _xWindow, wy + _tm.tmHeight ); if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) ) { SetBkColor( pps->hdc, crNormal ); SetTextColor( pps->hdc, crText ); HBRUSH hBrush; hBrush = CreateSolidBrush( crNormal ); FillRect( pps->hdc, &rect, hBrush ); DeleteObject( hBrush ); } return S_OK; } // // _OnPaint( ) // LRESULT CApplicationWindow::_OnPaint( WPARAM wParam, LPARAM lParam ) { HDC hdc; LONG wxStart; LONG wy; RECT rect; RECT rectResult; ULONG nLineCount; LINEPOINTER * pCurrent; SCROLLINFO si; PAINTSTRUCT ps; static COLORREF crBkColor[ MAX_OPEN_FILES ] = { 0xFFE0E0, 0xE0FFE0, 0xE0E0FF, 0xFFFFE0, 0xE0FFFF, 0xFFE0FF, 0xE0E0E0, 0xC0C0C0, 0x909090, 0x000000 }; static COLORREF crBkColorDarker[ MAX_OPEN_FILES ] = { 0xFFC0C0, 0xC0FFC0, 0xC0C0FF, 0xFFFFC0, 0xC0FFFF, 0xFFC0FF, 0xC0C0C0, 0xA0A0A0, 0x707070, 0x101010 }; static COLORREF crBkColorHighlite[ MAX_OPEN_FILES ] = { 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF, 0x101010, 0x404040, 0x606060, 0xFFFFFF }; si.cbSize = sizeof(si); si.fMask = SIF_POS; GetScrollInfo( _hWnd, SB_HORZ, &si ); wxStart = si.nPos; si.cbSize = sizeof(si); si.fMask = SIF_POS | SIF_PAGE; GetScrollInfo( _hWnd, SB_VERT, &si ); hdc = BeginPaint( _hWnd, &ps); if ( !_pLines ) goto EndPaint; SetBkMode( hdc, OPAQUE ); SelectObject( hdc, g_hFont ); nLineCount = 0; pCurrent = _pLines; while ( pCurrent && nLineCount < (ULONG) si.nPos ) { if ( !pCurrent->fFiltered ) { nLineCount++; } pCurrent = pCurrent->pNext; } wy = 0; while ( pCurrent && nLineCount <= si.nPos + si.nPage + 1 ) { // ignore filtered lines if ( pCurrent->fFiltered ) { pCurrent = pCurrent->pNext; continue; } if ( nLineCount >= _uStartSelection && nLineCount <= _uEndSelection ) { _PaintLine( &ps, pCurrent, -wxStart, wy, GetSysColor( COLOR_WINDOWTEXT ), crBkColorHighlite[ pCurrent->nFile ], crBkColorHighlite[ pCurrent->nFile ], crBkColorDarker[ pCurrent->nFile ] ); } else { _PaintLine( &ps, pCurrent, -wxStart, wy, GetSysColor( COLOR_WINDOWTEXT ), crBkColorDarker[ pCurrent->nFile ], crBkColor[ pCurrent->nFile ], crBkColorHighlite[ pCurrent->nFile ] ); } wy += _tm.tmHeight; nLineCount++; pCurrent = pCurrent->pNext; } // Fill the rest with normal background color SetRect( &rect, 0, wy, _xWindow, _yWindow ); if ( IntersectRect( &rectResult, &ps.rcPaint, &rect ) ) { HBRUSH hBrush; hBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) ); FillRect( hdc, &rect, hBrush ); DeleteObject( hBrush ); } EndPaint: EndPaint(_hWnd, &ps); return 0; } // // _FindNext( ) // LRESULT CApplicationWindow::_FindNext( WPARAM wParam, LPARAM lParam ) { SCROLLINFO si; LPTSTR pszSearch; LPTSTR psz; ULONG n; // general counter LPTSTR pszSearchString = (LPTSTR) lParam; // NEEDS TO BE FREEd!!! WPARAM wFlags = wParam; CWaitCursor Wait; _uFinderLength = lstrlen( pszSearchString ); if( wFlags & FIND_UP ) { // // TODO: Make a better "up" search // if ( _LineFinder.pPrev ) { CopyMemory( &_LineFinder, _LineFinder.pPrev, sizeof(LINEPOINTER) ); } else { LINEPOINTER * lpLast; LINEPOINTER * lp = _pLines; while( lp ) { lpLast = lp; lp = lp->pNext; } CopyMemory( &_LineFinder, lpLast, sizeof(LINEPOINTER) ); } } else // find down { if ( _LineFinder.psLine ) { // see if there is another instance on the same line psz = _LineFinder.psLine; for( n = 0; n < _uFinderLength; n++ ) { if ( !*psz || *psz == 10 ) break; psz++; } if ( *psz && *psz != 10 ) goto ResumeSearch; } } if ( _LineFinder.psLine == NULL ) { CopyMemory( &_LineFinder, _pLines->pNext, sizeof(LINEPOINTER) ); } for(;;) { psz = _LineFinder.psLine; if ( !psz ) break; // skip PID/TID and time/date while ( *psz && *psz != 10 ) { if ( *psz == ':' ) { psz++; if ( *psz == ':' ) { break; } } psz++; } while ( *psz && *psz != 10 ) { if ( *psz == 32 ) { psz++; break; } psz++; } if ( _LineFinder.WarnLevel != WarnLevelUnknown ) { // skip info/warn/err tag while ( *psz != 32) { psz++; } while ( *psz == 32) { psz++; } } // skip components if ( *psz == '[' ) { while ( *psz && *psz != ']' ) { psz++; } } if ( *psz == 10 ) goto NextLine; if ( !*psz ) break; ResumeSearch: pszSearch = pszSearchString; while ( *psz != 10 ) { if ( ( wFlags & FIND_MATCHCASE ) && *psz != *pszSearch ) { goto ResetMatch; } if ( toupper( *psz ) == toupper( *pszSearch ) ) { pszSearch++; if ( !*pszSearch ) { ULONG cLine; LINEPOINTER * lp; if ( wFlags & FIND_WHOLE_WORD && isalnum( psz[ 1 ] ) ) { psz++; // need to bump goto ResetMatch; } _LineFinder.psLine = psz - _uFinderLength + 1; // find the line lp = _pLines; cLine = 0; while( lp ) { if ( lp->nFile == _LineFinder.nFile && lp->nLine == _LineFinder.nLine ) { break; } if ( !lp->fFiltered ) { cLine++; } lp = lp->pNext; } _uPointer = _uStartSelection = _uEndSelection = cLine; si.cbSize = sizeof(si); si.fMask = SIF_PAGE; GetScrollInfo( _hWnd, SB_VERT, &si ); si.fMask = SIF_POS; si.nPos = cLine - si.nPage / 2; SetScrollInfo( _hWnd, SB_VERT, &si, TRUE ); InvalidateRect( _hWnd, NULL, FALSE ); LocalFree( pszSearchString ); return 1; } } else { ResetMatch: psz -= ( pszSearch - pszSearchString ); pszSearch = pszSearchString; } if ( !*psz ) break; psz++; } NextLine: if ( wFlags & FIND_UP ) { if ( _LineFinder.pPrev != NULL ) { CopyMemory( &_LineFinder, _LineFinder.pPrev, sizeof(LINEPOINTER) ); } else { break; // end of search } } else // find down { if ( _LineFinder.pNext != NULL ) { CopyMemory( &_LineFinder, _LineFinder.pNext, sizeof(LINEPOINTER) ); } else { break; // end of search } } } // not found ZeroMemory( &_LineFinder, sizeof(LINEPOINTER) ); if ( wFlags & FIND_UP ) { _LineFinder.nLine = 0; } else { _LineFinder.nLine = _cTotalLineCount; } LocalFree( pszSearchString ); return 0; } // // _MarkAll( ) // LRESULT CApplicationWindow::_MarkAll( WPARAM wParam, LPARAM lParam ) { WPARAM wFlags = wParam; LPTSTR pszSearchString = (LPTSTR) lParam; LocalFree( pszSearchString ); return 0; } // // _OnSize( ) // LRESULT CApplicationWindow::_OnSize( LPARAM lParam ) { HDC hdc; SIZE size; HGDIOBJ hObj; TCHAR szSpace[ 1 ] = { TEXT(' ') }; SCROLLINFO si; _xWindow = LOWORD( lParam ); _yWindow = HIWORD( lParam ); hdc = GetDC( _hWnd ); hObj = SelectObject( hdc, g_hFont ); GetTextMetrics( hdc, &_tm ); GetTextExtentPoint32( hdc, szSpace, 1, &size ); _xSpace = size.cx; si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE; si.nMin = 0; si.nMax = _cTotalLineCount; si.nPage = _yWindow / _tm.tmHeight; SetScrollInfo( _hWnd, SB_VERT, &si, FALSE ); si.fMask = SIF_RANGE | SIF_PAGE; si.nMin = 0; si.nMax = 1000; si.nPage = _xWindow / _tm.tmHeight; SetScrollInfo( _hWnd, SB_HORZ, &si, FALSE ); // cleanup the HDC SelectObject( hdc, hObj ); ReleaseDC( _hWnd, hdc ); return 0; } // // _OnMouseWheel( ) // LRESULT CApplicationWindow::_OnMouseWheel( SHORT iDelta ) { if ( iDelta > 0 ) { SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 ); SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 ); SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 ); } else if ( iDelta < 0 ) { SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 ); SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 ); SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 ); } return 0; } // // _OnVerticalScroll( ) // LRESULT CApplicationWindow::_OnVerticalScroll( WPARAM wParam, LPARAM lParam ) { SCROLLINFO si; RECT rect; INT nScrollCode = LOWORD(wParam); // scroll bar value INT nPos; //INT nPos = HIWORD(wParam); // scroll box position //HWND hwndScrollBar = (HWND) lParam; // handle to scroll bar si.cbSize = sizeof(si); si.fMask = SIF_ALL; GetScrollInfo( _hWnd, SB_VERT, &si ); nPos = si.nPos; switch( nScrollCode ) { case SB_BOTTOM: si.nPos = si.nMax; break; case SB_THUMBPOSITION: si.nPos = nPos; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; case SB_TOP: si.nPos = si.nMin; break; case SB_LINEDOWN: si.nPos += 1; break; case SB_LINEUP: si.nPos -= 1; break; case SB_PAGEDOWN: si.nPos += si.nPage; InvalidateRect( _hWnd, NULL, FALSE ); break; case SB_PAGEUP: si.nPos -= si.nPage; InvalidateRect( _hWnd, NULL, FALSE ); break; } si.fMask = SIF_POS; SetScrollInfo( _hWnd, SB_VERT, &si, TRUE ); GetScrollInfo( _hWnd, SB_VERT, &si ); if ( si.nPos != nPos ) { ScrollWindowEx( _hWnd, 0, (nPos - si.nPos) * _tm.tmHeight, NULL, NULL, NULL, NULL, SW_INVALIDATE ); SetRect( &rect, 0, ( _uPointer - si.nPos - 1 ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 2 ) * _tm.tmHeight ); InvalidateRect( _hWnd, &rect, FALSE ); } return 0; } // // _OnHorizontalScroll( ) // LRESULT CApplicationWindow::_OnHorizontalScroll( WPARAM wParam, LPARAM lParam ) { SCROLLINFO si; INT nScrollCode = LOWORD(wParam); // scroll bar value INT nPos; //INT nPos = HIWORD(wParam); // scroll box position //HWND hwndScrollBar = (HWND) lParam; // handle to scroll bar si.cbSize = sizeof(si); si.fMask = SIF_ALL; GetScrollInfo( _hWnd, SB_HORZ, &si ); nPos = si.nPos; switch( nScrollCode ) { case SB_BOTTOM: si.nPos = si.nMax; break; case SB_THUMBPOSITION: si.nPos = nPos; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; case SB_TOP: si.nPos = si.nMin; break; case SB_LINEDOWN: si.nPos += 1; break; case SB_LINEUP: si.nPos -= 1; break; case SB_PAGEDOWN: si.nPos += si.nPage; break; case SB_PAGEUP: si.nPos -= si.nPage; break; } si.fMask = SIF_POS; SetScrollInfo( _hWnd, SB_HORZ, &si, TRUE ); GetScrollInfo( _hWnd, SB_HORZ, &si ); if ( si.nPos != nPos ) { ScrollWindowEx( _hWnd, (nPos - si.nPos), 0, NULL, NULL, NULL, NULL, SW_INVALIDATE ); } return 0; } // // _FillClipboard( ) // HRESULT CApplicationWindow::_FillClipboard( ) { HANDLE hClip; LPTSTR pszClip; LPTSTR psz; ULONG dwSize; ULONG nLine; TCHAR szFilename[ 40 ]; LONG cchFilename; LINEPOINTER * pCurLine; LINEPOINTER * pSelectionStart; LONG cchMargin = ( _xMargin / _xSpace ) + 2; //0 cluster1.log 0000006 5c4.57c::1999/07/26-21:56:24.682 [EP] Initialization... static TCHAR szHeader[] = " Log/Nodename"; static TCHAR szHeader2[] = "Line### PIDxxxxx.TIDxxxxx Year/MM/DD-HH-MM-SS.HsS Log Entry\n\n"; if ( cchMargin < sizeof(szHeader) + 8 ) { cchMargin = sizeof(szHeader) + 8; } // // Find the start of the line // pSelectionStart = _pLines; for( nLine = 0; nLine < _uStartSelection; nLine++ ) { pSelectionStart = pSelectionStart->pNext; } // // Tally up the line sizes // dwSize = cchMargin - 8; dwSize += sizeof(szHeader2) - 1; pCurLine = pSelectionStart; for( ; nLine <= _uEndSelection; nLine++ ) { psz = pCurLine->psLine; if ( psz == NULL ) break; while( *psz && *psz != 10 ) { psz++; } if ( *psz ) { psz++; // inlude LF } dwSize += (ULONG)(psz - pCurLine->psLine); pCurLine = pCurLine->pNext; } // Add file and line number for every line dwSize += ( _uEndSelection - _uStartSelection + 1 ) * cchMargin; dwSize++; // add one for NULL terminator hClip = (LPTSTR) GlobalAlloc( LMEM_MOVEABLE | GMEM_DDESHARE, dwSize * sizeof(*pszClip) ); if ( !hClip ) return E_OUTOFMEMORY; pszClip = (LPTSTR) GlobalLock( hClip ); for ( LONG n = 0; n < cchMargin; n++ ) { pszClip[ n ] = 32; } CopyMemory( pszClip, szHeader, sizeof(szHeader) - 1 ); pszClip += cchMargin - 8; CopyMemory( pszClip, szHeader2, sizeof(szHeader2) - 1 ); pszClip += sizeof(szHeader2) - 1; pCurLine = pSelectionStart; for( nLine = _uStartSelection; nLine <= _uEndSelection; nLine++ ) { for ( LONG n = 0; n < cchMargin; n++ ) { pszClip[ n ] = 32; } // file number _snprintf( pszClip, 1, "%1u", pCurLine->nFile ); pszClip += 2; // filename cchFilename = cchMargin - 10; _GetFilename( _pszFilenames[ pCurLine->nFile ], szFilename, &cchFilename ); _snprintf( pszClip, cchFilename, "%s", szFilename ); pszClip += cchMargin - 10; // line number _snprintf( pszClip, 7, "%07.7u", pCurLine->nLine ); pszClip += 7; pszClip++; psz = pCurLine->psLine; if ( psz == NULL ) break; while( *psz && *psz != 10 ) { psz++; } if ( *psz ) { psz++; // inlude LF } CopyMemory( pszClip, pCurLine->psLine, psz - pCurLine->psLine ); pszClip += psz - pCurLine->psLine; pCurLine = pCurLine->pNext; } *pszClip = 0; // terminate GlobalUnlock( hClip ); if ( OpenClipboard( _hWnd ) ) { SetClipboardData( CF_TEXT, hClip ); CloseClipboard( ); } return S_OK; } // // _ApplyFilters( ) // HRESULT CApplicationWindow::_ApplyFilters( ) { SCROLLINFO si; ULONG nLineCount = 0; LINEPOINTER * lp = _pLines; while( lp ) { lp->fFiltered = FALSE; if ( lp->nFilterId == g_nComponentFilters + 1 ) { if ( g_fResourceNoise ) { lp->fFiltered = TRUE; } } else if ( lp->nFilterId !=0 && lp->nFilterId <= g_nComponentFilters ) { if ( g_pfSelectedComponent[ lp->nFilterId - 1 ] ) { lp->fFiltered = TRUE; } } if ( ! lp->fFiltered ) { nLineCount++; } lp = lp->pNext; } InvalidateRect( _hWnd, NULL, FALSE ); // Update scroll bar si.cbSize = sizeof(si); si.fMask = SIF_RANGE; GetScrollInfo( _hWnd, SB_VERT, &si ); si.nMax = nLineCount; SetScrollInfo( _hWnd, SB_VERT, &si, TRUE ); return S_OK; } // // _OnCommand( ) // LRESULT CApplicationWindow::_OnCommand( WPARAM wParam, LPARAM lParam ) { INT wmId = LOWORD(wParam); INT wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox( g_hInstance, (LPCTSTR)IDD_ABOUTBOX, _hWnd, (DLGPROC)About); break; case IDM_EXIT: { DestroyWindow( _hWnd ); } break; case IDM_FILE_REFRESH: { ULONG n; ULONG nFiles = _nFiles; LPTSTR pszFilenames[ MAX_OPEN_FILES ]; for( n = 0; n < nFiles; n++ ) { pszFilenames[ n ] = _pszFilenames[ n ]; _pszFilenames[ n ] = NULL; } Cleanup( ); for( n = 0; n < nFiles; n++ ) { _LoadFile( pszFilenames[ n ] ); LocalFree( pszFilenames[ n ] ); } } break; case IDM_NEW_FILE: { Cleanup( ); InvalidateRect( _hWnd, NULL, TRUE ); } break; case IDM_OPEN_FILE: { LPTSTR psz; TCHAR szFilters[ MAX_PATH ]; TCHAR szFilename[ MAX_PATH ]; LPTSTR pszFilenameBuffer = (LPTSTR) LocalAlloc( LPTR, 8 * MAX_PATH ); ZeroMemory( szFilters, sizeof(szFilters) ); ZeroMemory( _szOpenFileNameFilter, sizeof(_szOpenFileNameFilter) ); LoadString( g_hInstance, IDS_OPEN_FILE_FILTERS, szFilters, MAX_PATH ); for ( psz = szFilters; *psz; psz++ ) { if ( *psz == TEXT(',') ) { *psz = TEXT('\0'); } } OPENFILENAME ofn; ZeroMemory( &ofn, sizeof(ofn) ); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = _hWnd; ofn.hInstance = g_hInstance; ofn.lpstrFilter = szFilters; // ofn.lpfnHook = NULL; ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ALLOWMULTISELECT; // ofn.lCustData = 0; ofn.lpstrCustomFilter = _szOpenFileNameFilter; // ofn.lpstrDefExt = NULL; ofn.lpstrFile = pszFilenameBuffer; // ofn.lpstrFileTitle = NULL; // ofn.lpstrInitialDir = NULL; // ofn.lpstrTitle = NULL; // ofn.lpTemplateName = NULL; // ofn.nFileExtension = 0; // ofn.nFileOffset = 0; // ofn.nFilterIndex = 1; ofn.nMaxCustFilter = MAX_PATH; ofn.nMaxFile = 8 * MAX_PATH; // ofn.nMaxFileTitle = 0; if ( GetOpenFileName( &ofn ) ) { LPTSTR pszFilename = pszFilenameBuffer + ofn.nFileOffset; strcpy( szFilename, pszFilenameBuffer ); szFilename[ ofn.nFileOffset - 1] = '\\'; while ( *pszFilename ) { strcpy( &szFilename[ ofn.nFileOffset ], pszFilename ); _LoadFile( szFilename ); pszFilename += lstrlen( pszFilename ) + 1; } } else { DWORD dwErr = GetLastError( ); } LocalFree( pszFilenameBuffer ); } break; case IDM_ALL_ON: { ULONG nItems = GetMenuItemCount( _hMenu ); for( ULONG n = 0; n < nItems; n++ ) { MENUITEMINFO mii; ZeroMemory( &mii, sizeof(mii) ); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; mii.fState = MFS_CHECKED; SetMenuItemInfo( _hMenu, n, TRUE, &mii ); g_pfSelectedComponent[ n ] = FALSE; } LINEPOINTER * lp = _pLines; while( lp ) { lp->fFiltered = FALSE; lp = lp->pNext; } _ApplyFilters( ); } break; case IDM_EDIT_COPY: { _FillClipboard( ); } break; case IDM_FILTER_SHOWSERVERNAME: { HMENU hMenu = GetSubMenu( GetMenu( _hWnd ), 2 ); MENUITEMINFO mii; ZeroMemory( &mii, sizeof(mii) ); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; GetMenuItemInfo( hMenu, IDM_FILTER_SHOWSERVERNAME, FALSE, &mii ); g_fShowServerNames = ( ( mii.fState & MFS_CHECKED ) == MFS_CHECKED ); mii.fState = g_fShowServerNames ? 0 : MFS_CHECKED; SetMenuItemInfo( hMenu, IDM_FILTER_SHOWSERVERNAME, FALSE, &mii ); } break; case IDM_FILTER_RESOURCENOISE: { HMENU hMenu = GetSubMenu( GetMenu( _hWnd ), 2 ); MENUITEMINFO mii; ZeroMemory( &mii, sizeof(mii) ); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; GetMenuItemInfo( hMenu, IDM_FILTER_RESOURCENOISE, FALSE, &mii ); g_fResourceNoise = ( ( mii.fState & MFS_CHECKED ) == MFS_CHECKED ); mii.fState = g_fResourceNoise ? 0 : MFS_CHECKED; SetMenuItemInfo( hMenu, IDM_FILTER_RESOURCENOISE, FALSE, &mii ); _ApplyFilters( ); } break; case IDM_EDIT_FIND: if ( !g_hwndFind ) { new CFindDialog( _hWnd ); } else { ShowWindow( g_hwndFind, SW_SHOW ); } break; case IDM_ALL_OFF: { ULONG nItems = GetMenuItemCount( _hMenu ); for( ULONG n = 0; n < nItems; n++ ) { MENUITEMINFO mii; ZeroMemory( &mii, sizeof(mii) ); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; mii.fState = 0; SetMenuItemInfo( _hMenu, n, TRUE, &mii ); g_pfSelectedComponent[ n ] = TRUE; } _ApplyFilters( ); } break; default: if ( wmId >= IDM_FIRST_CS_FILTER && wmId <= IDM_LAST_CS_FILTER ) { MENUITEMINFO mii; ZeroMemory( &mii, sizeof(mii) ); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STATE; GetMenuItemInfo( _hMenu, wmId, FALSE, &mii ); g_pfSelectedComponent[ wmId - IDM_FIRST_CS_FILTER - 1 ] = ( ( mii.fState & MFS_CHECKED ) == MFS_CHECKED ); mii.fState = g_pfSelectedComponent[ wmId - IDM_FIRST_CS_FILTER - 1 ] ? 0 : MFS_CHECKED; SetMenuItemInfo( _hMenu, wmId, FALSE, &mii ); _ApplyFilters( ); } break; } return 0; } // // _OnDestroyWindow( ) // LRESULT CApplicationWindow::_OnDestroyWindow( ) { g_fCApplicationWindowDestroyed = TRUE; PostQuitMessage(0); delete this; return 0; } // // _OnCreate( ) // LRESULT CApplicationWindow::_OnCreate( HWND hwnd, LPCREATESTRUCT pcs ) { _hWnd = hwnd; SetWindowLongPtr( _hWnd, GWLP_USERDATA, (LONG_PTR)this ); return 0; } // // _OnKeyDown( ) // // Returns FALSE is the default window proc should also // take a crack at it. // // Returns TRUE to stop processing the message. // BOOL CApplicationWindow::_OnKeyDown( WPARAM wParam, LPARAM lParam ) { RECT rect; SCROLLINFO si; ULONG uOldPointer = _uPointer; BOOL lResult = FALSE; si.cbSize = sizeof(si); si.fMask = SIF_POS | SIF_PAGE; GetScrollInfo( _hWnd, SB_VERT, &si ); SetRect( &rect, 0, ( _uPointer - si.nPos ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 1 ) * _tm.tmHeight ); if ( wParam == VK_PRIOR || wParam == VK_UP || wParam == VK_HOME || wParam == VK_END || wParam == VK_NEXT || wParam == VK_DOWN ) { if ( _fSelection ) { if ( GetKeyState( VK_SHIFT ) >= 0 ) { _fSelection = FALSE; InvalidateRect( _hWnd, NULL, FALSE ); } } else { if ( GetKeyState( VK_SHIFT ) < 0 ) { _fSelection = TRUE; InvalidateRect( _hWnd, NULL, FALSE ); } } } switch ( wParam ) { case VK_PRIOR: _uPointer -= si.nPage - 1; case VK_UP: _uPointer--; if ( _uPointer >= _cTotalLineCount ) { _uPointer = _cTotalLineCount - 1; } if ( GetKeyState( VK_SHIFT ) < 0 ) { if ( uOldPointer == _uStartSelection ) { _uStartSelection = _uPointer; } else { _uEndSelection = _uPointer; } InvalidateRect( _hWnd, NULL, FALSE ); } else { _uStartSelection = _uEndSelection = _uPointer; if ( _uPointer < (ULONG) si.nPos ) { if ( wParam == VK_UP ) { SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 ); GetScrollInfo( _hWnd, SB_VERT, &si ); } } else { rect.top -= _tm.tmHeight; InvalidateRect( _hWnd, &rect, FALSE ); } } if ( wParam == VK_PRIOR ) { SendMessage( _hWnd, WM_VSCROLL, SB_PAGEUP, 0 ); } else if ( _uPointer < (ULONG) si.nPos ) { si.fMask = SIF_POS; si.nPos = _uPointer; SetScrollInfo( _hWnd, SB_VERT, &si, TRUE ); InvalidateRect( _hWnd, NULL, FALSE ); } lResult = TRUE; break; case VK_NEXT: _uPointer += si.nPage - 1; case VK_DOWN: _uPointer++; if ( _uPointer >= _cTotalLineCount ) { _uPointer = _cTotalLineCount - 1; } if ( GetKeyState( VK_SHIFT ) < 0 ) { if ( uOldPointer == _uEndSelection ) { _uEndSelection = _uPointer; } else { _uStartSelection = _uPointer; } InvalidateRect( _hWnd, NULL, FALSE ); } else { _uStartSelection = _uEndSelection = _uPointer; if ( _uPointer > si.nPos + si.nPage ) { if ( wParam == VK_DOWN ) { SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 ); GetScrollInfo( _hWnd, SB_VERT, &si ); } } else { rect.bottom += _tm.tmHeight; InvalidateRect( _hWnd, &rect, FALSE ); } } if ( wParam == VK_NEXT ) { SendMessage( _hWnd, WM_VSCROLL, SB_PAGEDOWN, 0 ); } else if ( _uPointer > si.nPos + si.nPage ) { si.fMask = SIF_POS; si.nPos = _uPointer; SetScrollInfo( _hWnd, SB_VERT, &si, TRUE ); InvalidateRect( _hWnd, NULL, FALSE ); } lResult = TRUE; break; case VK_HOME: _LineFinder.nLine = 0; _LineFinder.psLine = NULL; _uPointer = 0; if ( GetKeyState( VK_SHIFT ) < 0 ) { if ( uOldPointer == _uEndSelection ) { _uEndSelection = _uStartSelection; } _uStartSelection = 0; } else { _uEndSelection = _uStartSelection = _uPointer; } if ( uOldPointer < si.nPage ) { InvalidateRect( _hWnd, &rect, FALSE ); SetRect( &rect, 0, ( _uPointer - si.nPos ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 1 ) * _tm.tmHeight ); InvalidateRect( _hWnd, &rect, FALSE ); } else { SendMessage( _hWnd, WM_VSCROLL, SB_TOP, 0 ); } lResult = TRUE; break; case VK_END: _LineFinder.nLine = _cTotalLineCount; _LineFinder.psLine = NULL; _uPointer = _cTotalLineCount - 1; if ( GetKeyState( VK_SHIFT ) < 0 ) { if ( uOldPointer == _uStartSelection ) { _uStartSelection = _uEndSelection; } _uEndSelection = 0; } else { _uEndSelection = _uStartSelection = _uPointer; } if ( uOldPointer > _cTotalLineCount - si.nPage ) { InvalidateRect( _hWnd, &rect, FALSE ); SetRect( &rect, 0, ( _uPointer - si.nPos ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 1 ) * _tm.tmHeight ); InvalidateRect( _hWnd, &rect, FALSE ); } else { SendMessage( _hWnd, WM_VSCROLL, SB_BOTTOM, 0 ); } lResult = TRUE; break; case VK_LEFT: SendMessage( _hWnd, WM_HSCROLL, SB_PAGEUP, 0 ); break; case VK_RIGHT: SendMessage( _hWnd, WM_HSCROLL, SB_PAGEDOWN, 0 ); break; case VK_F5: // refresh PostMessage( _hWnd, WM_COMMAND, IDM_FILE_REFRESH, 0 ); break; case 'F': if ( GetKeyState( VK_CONTROL ) < 0 ) { PostMessage( _hWnd, WM_COMMAND, IDM_EDIT_FIND, 0 ); } break; case 'A': if ( GetKeyState( VK_CONTROL ) < 0 ) { PostMessage( _hWnd, WM_COMMAND, IDM_OPEN_FILE, 0 ); } break; case 'C': if ( GetKeyState( VK_CONTROL ) < 0 ) { PostMessage( _hWnd, WM_COMMAND, IDM_EDIT_COPY, 0 ); } break; } return lResult; } // // _OnLeftButtonDown( ) // LRESULT CApplicationWindow::_OnLeftButtonDown( WPARAM wParam, LPARAM lParam ) { SCROLLINFO si; DWORD fwKeys = (DWORD) wParam; DWORD x = GET_X_LPARAM( lParam ); DWORD y = GET_Y_LPARAM( lParam ); si.cbSize = sizeof(si); si.fMask = SIF_POS; GetScrollInfo( _hWnd, SB_VERT, &si ); _uPointer = si.nPos + y / _tm.tmHeight; InvalidateRect( _hWnd, NULL, FALSE ); if ( fwKeys & MK_SHIFT ) { if ( _uPointer < _uStartSelection ) { _uStartSelection = _uPointer; } else if ( _uPointer > _uEndSelection ) { _uEndSelection = _uPointer; } } else { _uStartSelection = _uEndSelection = _uPointer; } return FALSE; } // // WndProc( ) // LRESULT CALLBACK CApplicationWindow::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { CApplicationWindow * paw = (CApplicationWindow *) GetWindowLongPtr( hWnd, GWLP_USERDATA ); if ( paw != NULL ) { switch( uMsg ) { case WM_COMMAND: return paw->_OnCommand( wParam, lParam ); case WM_PAINT: return paw->_OnPaint( wParam, lParam ); case WM_DESTROY: SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)NULL ); return paw->_OnDestroyWindow( ); case WM_SIZE: return paw->_OnSize( lParam ); case WM_KEYDOWN: case WM_SYSKEYDOWN: if ( paw->_OnKeyDown( wParam, lParam ) ) return 0; break; // do default as well case WM_VSCROLL: return paw->_OnVerticalScroll( wParam, lParam ); case WM_HSCROLL: return paw->_OnHorizontalScroll( wParam, lParam ); case WM_MOUSEWHEEL: return paw->_OnMouseWheel( HIWORD(wParam) ); case WM_FIND_NEXT: return paw->_FindNext( wParam, lParam ); case WM_MARK_ALL: return paw->_MarkAll( wParam, lParam ); case WM_ERASEBKGND: goto EraseBackground; case WM_LBUTTONDOWN: return paw->_OnLeftButtonDown( wParam, lParam ); } return DefWindowProc( hWnd, uMsg, wParam, lParam ); } if ( uMsg == WM_CREATE ) { LPCREATESTRUCT pcs = (LPCREATESTRUCT) lParam; paw = (CApplicationWindow *) pcs->lpCreateParams; return paw->_OnCreate( hWnd, pcs ); } if ( uMsg == WM_ERASEBKGND ) { EraseBackground: RECT rectWnd; HBRUSH hBrush; HDC hdc = (HDC) wParam; GetClientRect( hWnd, &rectWnd ); #if defined(DEBUG_PAINT) hBrush = CreateSolidBrush( 0xFF00FF ); #else hBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) ); #endif FillRect( hdc, &rectWnd, hBrush ); DeleteObject( hBrush ); return TRUE; } return DefWindowProc( hWnd, uMsg, wParam, lParam ); } // Mesage handler for about box. LRESULT CALLBACK CApplicationWindow::About( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; }