Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3154 lines
81 KiB

  1. //
  2. // CApplicationWindow.CPP
  3. //
  4. // Application Window Class
  5. //
  6. #include "stdafx.h"
  7. #include <commctrl.h>
  8. #include <shellapi.h>
  9. #include "commdlg.h"
  10. #include "resource.h"
  11. #include "CApplicationWindow.h"
  12. #include "CFindDialog.h"
  13. #define CAPPLICATIONWINDOWCLASS TEXT("CApplicationWindowClass")
  14. #define WINDOWMENU 1
  15. BOOL g_fCApplicationWindowClassRegistered = FALSE;
  16. BOOL g_fCApplicationWindowDestroyed = FALSE;
  17. // these are used to track the next occurrence of the phrases
  18. LPTSTR g_pszDispatch;
  19. LPTSTR g_pszDispatch2;
  20. LPTSTR g_pszCompleted;
  21. //
  22. // Constructor
  23. //
  24. CApplicationWindow::CApplicationWindow( )
  25. {
  26. BOOL b;
  27. LPTSTR psz;
  28. LONG sx = GetSystemMetrics( SM_CXFULLSCREEN );
  29. LPTSTR lpCmdLine;
  30. Cleanup( TRUE );
  31. if ( !g_fCApplicationWindowClassRegistered )
  32. {
  33. WNDCLASSEX wcex;
  34. wcex.cbSize = sizeof(WNDCLASSEX);
  35. wcex.style = CS_HREDRAW | CS_VREDRAW;
  36. wcex.lpfnWndProc = (WNDPROC)CApplicationWindow::WndProc;
  37. wcex.cbClsExtra = 0;
  38. wcex.cbWndExtra = 0;
  39. wcex.hInstance = g_hInstance;
  40. wcex.hIcon = LoadIcon(g_hInstance, (LPCTSTR) IDI_CLUSLOG );
  41. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  42. wcex.hbrBackground = (HBRUSH) COLOR_GRAYTEXT; //NULL;
  43. wcex.lpszMenuName = (LPCSTR)IDC_SOL;
  44. wcex.lpszClassName = CAPPLICATIONWINDOWCLASS;
  45. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR) IDI_SMALL );
  46. RegisterClassEx(&wcex);
  47. }
  48. HANDLE hFile;
  49. hFile = CreateFile( "filter.txt",
  50. GENERIC_READ,
  51. FILE_SHARE_READ | FILE_SHARE_WRITE,
  52. NULL,
  53. OPEN_EXISTING,
  54. 0,
  55. NULL );
  56. if ( hFile != INVALID_HANDLE_VALUE )
  57. {
  58. LONG nLength = GetFileSize( hFile, NULL );
  59. nLength++; // one for NULL
  60. g_pszFilters = (LPTSTR) LocalAlloc( LPTR, nLength );
  61. if ( g_pszFilters )
  62. {
  63. DWORD dwRead; // dummy
  64. ReadFile( hFile, g_pszFilters, nLength, &dwRead, NULL );
  65. g_pszFilters[nLength-1] = 0;
  66. CloseHandle( hFile );
  67. g_nComponentFilters = 0;
  68. psz = g_pszFilters;
  69. while ( psz < &g_pszFilters[nLength-1] )
  70. {
  71. LPTSTR pszStart = psz;
  72. while ( *psz && *psz != 13 )
  73. {
  74. psz++;
  75. }
  76. psz += 2;
  77. g_nComponentFilters++;
  78. }
  79. g_pfSelectedComponent = (BOOL*) LocalAlloc( LPTR, g_nComponentFilters * sizeof(BOOL) );
  80. }
  81. }
  82. _hWnd = CreateWindowEx( WS_EX_ACCEPTFILES,
  83. CAPPLICATIONWINDOWCLASS,
  84. TEXT("Cluster Log Analyzer"),
  85. WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS,
  86. CW_USEDEFAULT,
  87. CW_USEDEFAULT,
  88. CW_USEDEFAULT,
  89. CW_USEDEFAULT,
  90. NULL,
  91. NULL,
  92. g_hInstance,
  93. (LPVOID) this);
  94. if (!_hWnd)
  95. {
  96. return;
  97. }
  98. _hMenu = CreatePopupMenu( );
  99. MENUITEMINFO mii;
  100. ZeroMemory( &mii, sizeof(mii) );
  101. mii.cbSize = sizeof(mii);
  102. mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID;
  103. mii.fState = MFS_CHECKED;
  104. mii.wID = IDM_FIRST_CS_FILTER ;
  105. psz = g_pszFilters;
  106. if ( psz )
  107. {
  108. while ( *psz && mii.wID < IDM_LAST_CS_FILTER )
  109. {
  110. mii.dwTypeData = psz;
  111. while ( *psz && *psz != 13 )
  112. {
  113. psz++;
  114. }
  115. if ( *psz == 13 )
  116. {
  117. *psz = 0;
  118. psz++;
  119. if ( *psz )
  120. {
  121. psz++;
  122. }
  123. }
  124. mii.wID++;
  125. mii.cch = (UINT)(psz - mii.dwTypeData);
  126. b = InsertMenuItem( _hMenu, -1, TRUE, &mii );
  127. }
  128. }
  129. HMENU hMenu = GetSubMenu( GetMenu( _hWnd ), 2 );
  130. b = AppendMenu( hMenu, MF_POPUP, (UINT_PTR) _hMenu, "&Cluster Service" );
  131. DrawMenuBar( _hWnd );
  132. ShowWindow( _hWnd, SW_SHOW );
  133. UpdateWindow( _hWnd );
  134. lpCmdLine = GetCommandLine( );
  135. if ( lpCmdLine )
  136. {
  137. if ( lpCmdLine[0] == '\"' )
  138. {
  139. lpCmdLine++;
  140. while ( *lpCmdLine && *lpCmdLine != '\"' )
  141. {
  142. lpCmdLine++;
  143. }
  144. if ( *lpCmdLine )
  145. {
  146. lpCmdLine++;
  147. }
  148. if ( *lpCmdLine )
  149. {
  150. lpCmdLine++;
  151. }
  152. }
  153. else
  154. {
  155. while ( *lpCmdLine && *lpCmdLine != 32 )
  156. {
  157. lpCmdLine++;
  158. }
  159. if ( *lpCmdLine )
  160. {
  161. lpCmdLine++;
  162. }
  163. }
  164. while ( lpCmdLine[0] )
  165. {
  166. LPSTR psz = strchr( lpCmdLine, 32 );
  167. if ( psz )
  168. {
  169. *psz = 0;
  170. }
  171. if ( lpCmdLine[1] != ':'
  172. && lpCmdLine[1] != '\\' )
  173. {
  174. LPTSTR pszFilename = (LPTSTR)
  175. LocalAlloc( LMEM_FIXED, MAX_PATH * sizeof(TCHAR) );
  176. if ( pszFilename )
  177. {
  178. DWORD dwRead;
  179. dwRead = GetCurrentDirectory( MAX_PATH, pszFilename );
  180. if ( dwRead >= MAX_PATH )
  181. {
  182. LocalFree( pszFilename );
  183. pszFilename = (LPTSTR)
  184. LocalAlloc( LMEM_FIXED,
  185. ( dwRead + MAX_PATH ) * sizeof(TCHAR) );
  186. if ( pszFilename )
  187. {
  188. dwRead = GetCurrentDirectory( MAX_PATH, pszFilename );
  189. }
  190. }
  191. if ( pszFilename
  192. && dwRead != 0 )
  193. {
  194. strcat( pszFilename, TEXT("\\") );
  195. strcat( pszFilename, lpCmdLine );
  196. _LoadFile( pszFilename );
  197. }
  198. }
  199. else
  200. {
  201. break;
  202. }
  203. }
  204. if ( *lpCmdLine )
  205. {
  206. _LoadFile( lpCmdLine );
  207. }
  208. lpCmdLine += lstrlen( lpCmdLine );
  209. if ( psz )
  210. {
  211. lpCmdLine++;
  212. *psz = 32;
  213. }
  214. }
  215. }
  216. }
  217. //
  218. // Destructor
  219. //
  220. CApplicationWindow::~CApplicationWindow( )
  221. {
  222. Cleanup( );
  223. ShowWindow( _hWnd, SW_HIDE );
  224. }
  225. //
  226. //
  227. //
  228. HRESULT
  229. CApplicationWindow::Cleanup(
  230. BOOL fInitializing // = FALSE
  231. )
  232. {
  233. if ( !fInitializing )
  234. {
  235. for( ULONG nFile = 0; nFile < _nFiles; nFile++ )
  236. {
  237. LocalFree( _pFiles[ nFile ] );
  238. LocalFree( _pszFilenames[ nFile ] );
  239. LocalFree( _pNodes[ nFile ] );
  240. }
  241. }
  242. _nFiles = 0;
  243. _cTotalLineCount = 0;
  244. _fVertSBVisible = FALSE;
  245. _uStartSelection = 0;
  246. _uEndSelection = 0;
  247. _uPointer = 0;
  248. _pLines = 0;
  249. ZeroMemory( &_LineFinder, sizeof(_LineFinder) );
  250. _uFinderLength = 0;
  251. ShowScrollBar( _hWnd, SB_VERT, FALSE );
  252. return S_OK;
  253. }
  254. //
  255. // _CalculateOffset( )
  256. //
  257. HRESULT
  258. CApplicationWindow::_CalculateOffset(
  259. FILETIME * pftOper1,
  260. FILETIME * pftOper2,
  261. INT * pnDir,
  262. FILETIME * pftOffset
  263. )
  264. {
  265. *pnDir = CompareFileTime( pftOper1, pftOper2 );
  266. if ( *pnDir > 0 )
  267. {
  268. pftOffset->dwHighDateTime = pftOper1->dwHighDateTime - pftOper2->dwHighDateTime;
  269. pftOffset->dwLowDateTime = pftOper1->dwLowDateTime - pftOper2->dwLowDateTime;
  270. if ( pftOper1->dwLowDateTime < pftOper2->dwLowDateTime )
  271. {
  272. pftOffset->dwHighDateTime++;
  273. }
  274. }
  275. else if ( *pnDir < 0 )
  276. {
  277. pftOffset->dwHighDateTime = pftOper2->dwHighDateTime - pftOper1->dwHighDateTime;
  278. pftOffset->dwLowDateTime = pftOper2->dwLowDateTime - pftOper1->dwLowDateTime;
  279. if ( pftOper1->dwLowDateTime > pftOper2->dwLowDateTime )
  280. {
  281. pftOffset->dwHighDateTime--;
  282. }
  283. }
  284. return S_OK;
  285. }
  286. //
  287. // _FindSequencePoint( )
  288. //
  289. BOOL
  290. CApplicationWindow::_FindSequencePoint(
  291. LPTSTR * ppszSequence,
  292. ULONG * pnSequence
  293. )
  294. {
  295. while( *ppszSequence )
  296. {
  297. if ( *ppszSequence > g_pszDispatch )
  298. {
  299. g_pszDispatch = strstr( *ppszSequence, "dispatching seq " ) - 1;
  300. }
  301. if ( *ppszSequence > g_pszCompleted )
  302. {
  303. g_pszCompleted = strstr( *ppszSequence, "completed update seq " ) - 1;
  304. }
  305. if ( *ppszSequence > g_pszDispatch2 )
  306. {
  307. g_pszDispatch2 = strstr( *ppszSequence, "Dispatching seq " ) - 1;
  308. }
  309. if ( g_pszDispatch < g_pszCompleted )
  310. {
  311. (*ppszSequence) = g_pszDispatch + sizeof("dispatching seq ") - 1;
  312. if ( pnSequence )
  313. {
  314. *pnSequence = atol ( *ppszSequence );
  315. (*pnSequence) *= 3;
  316. }
  317. break;
  318. }
  319. if ( g_pszDispatch2 < g_pszCompleted )
  320. {
  321. (*ppszSequence) = g_pszDispatch2 + sizeof("Dispatching seq ") - 1;
  322. if ( pnSequence )
  323. {
  324. *pnSequence = atol ( *ppszSequence );
  325. (*pnSequence) *= 3;
  326. (*pnSequence)++;
  327. }
  328. break;
  329. }
  330. if ( g_pszCompleted + 1 != NULL )
  331. {
  332. (*ppszSequence) = g_pszCompleted + sizeof("completed update seq ") - 1;
  333. if ( pnSequence )
  334. {
  335. *pnSequence = atol ( *ppszSequence );
  336. (*pnSequence) *= 3;
  337. (*pnSequence)++;
  338. (*pnSequence)++;
  339. }
  340. break;
  341. }
  342. *ppszSequence = NULL;
  343. return FALSE;
  344. }
  345. return TRUE;
  346. }
  347. //
  348. // _RetrieveTimeDate( )
  349. //
  350. HRESULT
  351. CApplicationWindow::_RetrieveTimeDate(
  352. LPTSTR pszCurrent,
  353. SYSTEMTIME * pst,
  354. LPTSTR * ppszFinal
  355. )
  356. {
  357. if ( ppszFinal )
  358. {
  359. *ppszFinal = pszCurrent;
  360. }
  361. // Find the thread and process IDs
  362. while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent != 10 )
  363. {
  364. pszCurrent++;
  365. }
  366. if ( *pszCurrent != ':' )
  367. return S_FALSE;
  368. pszCurrent++;
  369. if ( *pszCurrent != ':' )
  370. return S_FALSE;
  371. pszCurrent++;
  372. // Find Time/Date stamp which is:
  373. // ####/##/##-##:##:##.###<space>
  374. pst->wYear = (WORD) atol( pszCurrent );
  375. while ( *pszCurrent >= '0' && *pszCurrent <= '9' )
  376. {
  377. pszCurrent++;
  378. }
  379. if ( *pszCurrent == '-' )
  380. {
  381. //
  382. // The "year" we got above should really be the day.
  383. // We'll replace the year with zero and the month with one.
  384. //
  385. pst->wDay = pst->wYear;
  386. pst->wYear = 0;
  387. pst->wMonth = 1;
  388. goto SkipDate;
  389. }
  390. if ( *pszCurrent != '/' )
  391. return S_FALSE;
  392. pszCurrent++;
  393. pst->wMonth = (WORD) atol( pszCurrent );
  394. while ( *pszCurrent >= '0' && *pszCurrent <= '9' )
  395. {
  396. pszCurrent++;
  397. }
  398. if ( *pszCurrent != '/' )
  399. return S_FALSE;
  400. pszCurrent++;
  401. pst->wDay = (WORD) atol( pszCurrent );
  402. while ( *pszCurrent >= '0' && *pszCurrent <= '9' )
  403. {
  404. pszCurrent++;
  405. }
  406. if ( *pszCurrent != '-' )
  407. return S_FALSE;
  408. SkipDate:
  409. pszCurrent++;
  410. pst->wHour = (WORD) atol( pszCurrent );
  411. while ( *pszCurrent >= '0' && *pszCurrent <= '9' )
  412. {
  413. pszCurrent++;
  414. }
  415. if ( *pszCurrent != ':' )
  416. return S_FALSE;
  417. pszCurrent++;
  418. pst->wMinute = (WORD) atol( pszCurrent );
  419. while ( *pszCurrent >= '0' && *pszCurrent <= '9' )
  420. {
  421. pszCurrent++;
  422. }
  423. if ( *pszCurrent != ':' )
  424. return S_FALSE;
  425. pszCurrent++;
  426. pst->wSecond = (WORD) atol( pszCurrent );
  427. while ( *pszCurrent >= '0' && *pszCurrent <= '9' )
  428. {
  429. pszCurrent++;
  430. }
  431. if ( *pszCurrent != '.' )
  432. return S_FALSE;
  433. pszCurrent++;
  434. pst->wMilliseconds = (WORD) atol( pszCurrent );
  435. while ( *pszCurrent >= '0' && *pszCurrent <= '9' )
  436. {
  437. pszCurrent++;
  438. }
  439. if ( ppszFinal )
  440. {
  441. *ppszFinal = pszCurrent;
  442. }
  443. return S_OK;
  444. }
  445. //
  446. // _GetFilename( )
  447. //
  448. HRESULT
  449. CApplicationWindow::_GetFilename(
  450. LPTSTR pszFilename,
  451. LPTSTR pszFilenameOut,
  452. LONG * pcch
  453. )
  454. {
  455. LONG cch = 0;
  456. if ( g_fShowServerNames && pszFilename[ 0 ] == '\\' && pszFilename[ 1 ] == '\\' )
  457. {
  458. LPTSTR psz = &pszFilename[ 2 ];
  459. while ( *psz && *psz != '\\' )
  460. {
  461. psz++;
  462. cch++;
  463. }
  464. psz--;
  465. cch += 2;
  466. }
  467. else if ( strchr( pszFilename, '\\' ) )
  468. {
  469. pszFilename = pszFilename + lstrlen( pszFilename );
  470. while ( *pszFilename != '\\' )
  471. {
  472. pszFilename--;
  473. cch++;
  474. }
  475. pszFilename++;
  476. cch--;
  477. }
  478. else
  479. {
  480. cch = lstrlen( pszFilename );
  481. }
  482. if ( pszFilenameOut )
  483. {
  484. if ( !pcch )
  485. return E_POINTER;
  486. if ( cch >= *pcch )
  487. {
  488. cch = *pcch - 1;
  489. }
  490. strncpy( pszFilenameOut, pszFilename, cch );
  491. pszFilenameOut[ cch ] = 0;
  492. }
  493. if ( pcch )
  494. {
  495. *pcch = cch;
  496. }
  497. return S_OK;
  498. }
  499. //
  500. // _StatusWndProc( )
  501. //
  502. LRESULT CALLBACK
  503. CApplicationWindow::_StatusWndProc(
  504. HWND hWnd,
  505. UINT uMsg,
  506. WPARAM wParam,
  507. LPARAM lParam
  508. )
  509. {
  510. return 0;
  511. }
  512. //
  513. // _CombineFiles( )
  514. //
  515. HRESULT
  516. CApplicationWindow::_CombineFiles( )
  517. {
  518. HRESULT hr; // general purpose HRESULT and return code
  519. BOOL b; // general purpose return BOOL
  520. ULONG nFileLineCount; // counter of the lines in the file
  521. ULONG nSequence; // ID of current sequence
  522. ULONG nNextSequence; // ID of the next squence
  523. LPTSTR pszSequence; // next sequence location
  524. LPTSTR pszCurrent; // current parse location within file
  525. BOOL fSyncPoint; // flag indicating a sync point was encountered
  526. SYSTEMTIME st; // used to convert "line time" to a filetime.
  527. FILETIME ft; // current lines filetime
  528. FILETIME ftOffset; // current filetime offset
  529. INT nDir; // offset direction
  530. MSG msg; // message pumping
  531. HWND hwndProcessing; // processing window handle
  532. HWND hwndStatus; // progress bar window handle
  533. SCROLLINFO si; // verticle scroll bar
  534. LINEPOINTER * pLastSyncPoint; // last place a sync point in other files was encountered
  535. LINEPOINTER * pInsertionPoint; // next place a node will be inserted
  536. LINEPOINTER * pNewLine; // next structure to be used as a node
  537. CWaitCursor Wait; // show the hour glass
  538. si.cbSize = sizeof(si);
  539. si.fMask = SIF_RANGE | SIF_PAGE;
  540. GetScrollInfo( _hWnd, SB_VERT, &si );
  541. si.fMask = SIF_RANGE;
  542. ZeroMemory( &ftOffset, sizeof(ftOffset) );
  543. nDir = 0;
  544. g_pszDispatch = NULL;
  545. g_pszDispatch2 = NULL;
  546. g_pszCompleted = NULL;
  547. // scan to figure out the line count of the new file
  548. nFileLineCount = 0;
  549. pszCurrent = _pFiles[ _nFiles ];
  550. while ( *pszCurrent )
  551. {
  552. if ( *pszCurrent == 10 )
  553. {
  554. nFileLineCount++;
  555. }
  556. pszCurrent++;
  557. }
  558. if ( !_pLines )
  559. {
  560. // add one more for the root node
  561. nFileLineCount++;
  562. }
  563. // allocate all the memory up front to avoid fragmenting memory as well as
  564. // descreasing the number of heap calls
  565. _pNodes[ _nFiles ] = (LINEPOINTER *) LocalAlloc( LMEM_FIXED, nFileLineCount * sizeof(LINEPOINTER) );
  566. if ( !_pNodes[ _nFiles ] )
  567. {
  568. return E_OUTOFMEMORY;
  569. }
  570. pNewLine = _pNodes[ _nFiles ];
  571. if ( !_pLines )
  572. {
  573. _pLines = pNewLine;
  574. ZeroMemory( _pLines, sizeof(LINEPOINTER) );
  575. pNewLine++;
  576. }
  577. // Create wait modeless dialog
  578. hwndProcessing = CreateDialog( g_hInstance,
  579. MAKEINTRESOURCE(IDD_PROCESSING),
  580. _hWnd,
  581. (DLGPROC) CApplicationWindow::_StatusWndProc );
  582. hwndStatus = GetDlgItem( hwndProcessing, IDC_P_STATUS );
  583. SendMessage( hwndStatus, PBM_SETRANGE32, 0, nFileLineCount );
  584. SendMessage( hwndStatus, PBM_SETPOS, 0, 0 );
  585. SendMessage( hwndStatus, PBM_SETSTEP, 1, 0 );
  586. SetWindowText( GetDlgItem( hwndProcessing, IDC_S_FILENAME ), _pszFilenames[ _nFiles ] );
  587. // Find the first sync point
  588. nNextSequence = nSequence = 0;
  589. pszSequence = _pFiles[ _nFiles ];
  590. if ( _FindSequencePoint( &pszSequence, &nNextSequence ) )
  591. {
  592. RetrySequencing:
  593. if ( _nFiles )
  594. {
  595. LINEPOINTER * lp = _pLines;
  596. while ( lp->pNext
  597. && nNextSequence != lp->uSequenceNumber )
  598. {
  599. lp = lp->pNext;
  600. // pump some messages....
  601. if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  602. {
  603. if ( !IsDialogMessage( g_hwndFind, &msg ) )
  604. {
  605. TranslateMessage( &msg );
  606. DispatchMessage( &msg );
  607. }
  608. if ( g_fCApplicationWindowDestroyed )
  609. {
  610. return E_FAIL; // not break!
  611. }
  612. }
  613. }
  614. if ( nNextSequence == lp->uSequenceNumber )
  615. {
  616. pszCurrent = pszSequence;
  617. while( pszCurrent >= _pFiles[ _nFiles ] && *pszCurrent != 10 )
  618. {
  619. pszCurrent--;
  620. }
  621. pszCurrent++;
  622. hr = _RetrieveTimeDate( pszCurrent, &st, NULL );
  623. b = SystemTimeToFileTime( &st, &ft );
  624. _CalculateOffset( &ft, &lp->Time, &nDir, &ftOffset );
  625. nSequence = nNextSequence - 1;
  626. }
  627. else
  628. {
  629. if ( _FindSequencePoint( &pszSequence, &nNextSequence ) )
  630. goto RetrySequencing;
  631. nNextSequence = nSequence = 0;
  632. }
  633. }
  634. else
  635. {
  636. nSequence = nNextSequence - 1;
  637. }
  638. }
  639. nFileLineCount = 1;
  640. pszCurrent = _pFiles[ _nFiles ];
  641. pInsertionPoint = _pLines;
  642. while ( *pszCurrent )
  643. {
  644. LPTSTR pszStart = pszCurrent;
  645. // this will parse past the PID.TID and Time/Date
  646. hr = _RetrieveTimeDate( pszCurrent, &st, &pszCurrent );
  647. b = SystemTimeToFileTime( &st, &ft );
  648. // skip spaces
  649. while ( *pszCurrent == 32)
  650. {
  651. pszCurrent++;
  652. }
  653. // fill in preliminary info
  654. pNewLine->fFiltered = FALSE;
  655. pNewLine->nFile = _nFiles;
  656. pNewLine->nLine = nFileLineCount;
  657. pNewLine->psLine = pszStart;
  658. // note warning level of line
  659. //
  660. if ( _stricmp( "INFO", pszCurrent ))
  661. {
  662. pNewLine->WarnLevel = WarnLevelInfo;
  663. }
  664. else if ( _stricmp( "WARN", pszCurrent ))
  665. {
  666. pNewLine->WarnLevel = WarnLevelWarn;
  667. }
  668. else if ( _stricmp( "ERR ", pszCurrent ))
  669. {
  670. pNewLine->WarnLevel = WarnLevelError;
  671. }
  672. else
  673. {
  674. pNewLine->WarnLevel = WarnLevelUnknown;
  675. }
  676. if ( pNewLine->WarnLevel != WarnLevelUnknown )
  677. {
  678. // skip chars, then spaces only if we found the tag
  679. while ( *pszCurrent != 32)
  680. {
  681. pszCurrent++;
  682. }
  683. while ( *pszCurrent == 32)
  684. {
  685. pszCurrent++;
  686. }
  687. }
  688. // [OPTIONAL] Cluster component which looks like:
  689. // [<id...>]
  690. if ( *pszCurrent == '[' )
  691. {
  692. LPTSTR pszComponentTag = pszCurrent;
  693. while ( *pszCurrent && *pszCurrent != ']' && *pszCurrent >= 32 )
  694. {
  695. pszCurrent++;
  696. }
  697. if ( *pszCurrent < 32 )
  698. {
  699. pszCurrent = pszComponentTag;
  700. goto NoComponentTryResouce;
  701. }
  702. pszCurrent++;
  703. // found component
  704. USHORT nFilterId = 0;
  705. LONG nLen = (LONG)(pszCurrent - pszComponentTag - 2);
  706. LPTSTR psz = g_pszFilters;
  707. while ( nFilterId < g_nComponentFilters )
  708. {
  709. if ( nLen == lstrlen( psz )
  710. && _strnicmp( pszComponentTag + 1, psz, nLen ) == 0 )
  711. {
  712. pNewLine->nFilterId = nFilterId + 1;
  713. if ( g_pfSelectedComponent[ nFilterId ] )
  714. {
  715. pNewLine->fFiltered = TRUE;
  716. }
  717. break;
  718. }
  719. while ( *psz )
  720. {
  721. psz++;
  722. }
  723. psz += 2;
  724. nFilterId++;
  725. }
  726. }
  727. else
  728. {
  729. // [OPTIONAL] If not a component, see if there is a res type
  730. NoComponentTryResouce:
  731. LPTSTR pszResType = pszCurrent;
  732. while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent >= 32 )
  733. {
  734. pszCurrent++;
  735. }
  736. if ( *pszCurrent >= 32 )
  737. {
  738. pszCurrent++;
  739. // found a restype
  740. pNewLine->nFilterId = g_nComponentFilters + 1; // TODO: make more dynamic
  741. if ( g_fResourceNoise )
  742. {
  743. pNewLine->fFiltered = TRUE;
  744. }
  745. }
  746. }
  747. // Find the beggining of the next line
  748. while ( *pszCurrent && *pszCurrent != 10 )
  749. {
  750. pszCurrent++;
  751. }
  752. if ( *pszCurrent )
  753. {
  754. pszCurrent++;
  755. }
  756. // See if we just past a sync point
  757. if ( pszSequence && pszCurrent > pszSequence )
  758. {
  759. fSyncPoint = TRUE;
  760. nSequence = nNextSequence;
  761. // find the next sync point
  762. _FindSequencePoint( &pszSequence, &nNextSequence );
  763. if ( _nFiles )
  764. {
  765. // if we are out of sync, move the insertion point ahead
  766. if ( pInsertionPoint->pNext != NULL
  767. && nSequence >= pInsertionPoint->uSequenceNumber )
  768. {
  769. for( pLastSyncPoint = pInsertionPoint; pLastSyncPoint->pNext; pLastSyncPoint = pLastSyncPoint->pNext )
  770. {
  771. if ( pLastSyncPoint->nFile != _nFiles
  772. && ( nSequence < pLastSyncPoint->uSequenceNumber
  773. || ( pLastSyncPoint->fSyncPoint
  774. && nSequence == pLastSyncPoint->uSequenceNumber ) ) )
  775. {
  776. break;
  777. }
  778. }
  779. if ( pLastSyncPoint
  780. && pLastSyncPoint->pNext
  781. && nSequence == pLastSyncPoint->uSequenceNumber )
  782. {
  783. pInsertionPoint = pLastSyncPoint;
  784. _CalculateOffset( &ft, &pInsertionPoint->Time, &nDir, &ftOffset );
  785. }
  786. }
  787. }
  788. }
  789. else
  790. {
  791. fSyncPoint = FALSE;
  792. }
  793. // adjust time to compensate for time deviations
  794. if ( nDir > 0 )
  795. { // if we are ahead, subtract
  796. if ( ft.dwLowDateTime - ftOffset.dwLowDateTime > ft.dwLowDateTime )
  797. {
  798. ft.dwHighDateTime--;
  799. }
  800. ft.dwLowDateTime -= ftOffset.dwLowDateTime;
  801. ft.dwHighDateTime -= ftOffset.dwHighDateTime;
  802. }
  803. else if ( nDir < 0 )
  804. { // if we are behind, add
  805. if ( ft.dwLowDateTime + ftOffset.dwLowDateTime < ft.dwLowDateTime )
  806. {
  807. ft.dwHighDateTime++;
  808. }
  809. ft.dwLowDateTime += ftOffset.dwLowDateTime;
  810. ft.dwHighDateTime += ftOffset.dwHighDateTime;
  811. }
  812. // else if nDir == 0, nothing to do
  813. #if defined(_DEBUG) && defined(VERIFY_SYNC_POINTS)
  814. if ( fSyncPoint && _nFiles != 0 )
  815. {
  816. INT n = CompareFileTime( &ft, &pInsertionPoint->Time );
  817. if ( n != 0 )
  818. {
  819. DebugBreak( );
  820. }
  821. }
  822. #endif // defined(_DEBUG) && defined(VERIFY_SYNC_POINTS)
  823. // Find the place to insert it
  824. while( pInsertionPoint->pNext )
  825. {
  826. if ( nSequence < pInsertionPoint->pNext->uSequenceNumber
  827. && pInsertionPoint->pNext->nFile != _nFiles )
  828. {
  829. break;
  830. }
  831. INT n = CompareFileTime( &ft, &pInsertionPoint->pNext->Time );
  832. if ( n < 0 )
  833. break;
  834. pInsertionPoint = pInsertionPoint->pNext;
  835. }
  836. // fill-in rest of the LINEPOINTER structure
  837. pNewLine->Time = ft;
  838. pNewLine->fSyncPoint = fSyncPoint;
  839. pNewLine->uSequenceNumber = nSequence;
  840. // insert node into line list
  841. pNewLine->pNext = pInsertionPoint->pNext;
  842. pNewLine->pPrev = pInsertionPoint;
  843. if ( pInsertionPoint->pNext != NULL )
  844. {
  845. pInsertionPoint->pNext->pPrev = pNewLine;
  846. }
  847. pInsertionPoint->pNext = pNewLine;
  848. pInsertionPoint = pNewLine;
  849. pNewLine++;
  850. // dump line counts
  851. nFileLineCount++;
  852. _cTotalLineCount++;
  853. // synchonize the scroll bar, don't redraw it
  854. if ( _cTotalLineCount > 100 && _cTotalLineCount > si.nPage )
  855. {
  856. si.nMax = _cTotalLineCount;
  857. SetScrollInfo( _hWnd, SB_VERT, &si, FALSE );
  858. }
  859. SendMessage( hwndStatus, PBM_STEPIT, 0, 0 );
  860. #if defined(_DEBUG) && defined(SLOW_FILL)
  861. if ( _nFiles )
  862. {
  863. InvalidateRect( _hWnd, NULL, TRUE );
  864. for( ULONG a = 0; a < 999999 ; a++ )
  865. {
  866. #endif // defined(_DEBUG) && defined(SLOW_FILL)
  867. // pump some messages....
  868. if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  869. {
  870. if ( !IsDialogMessage( g_hwndFind, &msg ) )
  871. {
  872. TranslateMessage( &msg );
  873. DispatchMessage( &msg );
  874. }
  875. if ( g_fCApplicationWindowDestroyed )
  876. {
  877. return E_FAIL; // not break!
  878. }
  879. }
  880. #if defined(_DEBUG) && defined(SLOW_FILL)
  881. }
  882. }
  883. #endif // defined(_DEBUG) && defined(SLOW_FILL)
  884. }
  885. DestroyWindow( hwndProcessing );
  886. _nFiles++;
  887. if ( !_fVertSBVisible
  888. && _yWindow < (LONG)(_cTotalLineCount * _tm.tmHeight) )
  889. {
  890. _fVertSBVisible = TRUE;
  891. EnableScrollBar( _hWnd, SB_VERT, ESB_ENABLE_BOTH );
  892. ShowScrollBar( _hWnd, SB_VERT, TRUE );
  893. }
  894. else if ( _fVertSBVisible
  895. && _yWindow >= (LONG)(_cTotalLineCount * _tm.tmHeight) )
  896. {
  897. _fVertSBVisible = FALSE;
  898. //EnableScrollBar( _hWnd, SB_VERT, ESB_ENABLE_BOTH );
  899. ShowScrollBar( _hWnd, SB_VERT, FALSE );
  900. }
  901. si.cbSize = sizeof(si);
  902. si.fMask = SIF_RANGE;
  903. si.nMin = 0;
  904. si.nMax = _cTotalLineCount;
  905. SetScrollInfo( _hWnd, SB_VERT, &si, TRUE );
  906. InvalidateRect( _hWnd, NULL, TRUE );
  907. return S_OK;
  908. }
  909. //
  910. // _LoadFile( )
  911. //
  912. HRESULT
  913. CApplicationWindow::_LoadFile(
  914. LPTSTR pszFilename )
  915. {
  916. HRESULT hr;
  917. DWORD dwRead;
  918. HANDLE hFile;
  919. ULONG nLength;
  920. LONG xMargin;
  921. _pszFilenames[ _nFiles ] = (LPTSTR) LocalAlloc( LMEM_FIXED, ( lstrlen( pszFilename ) + 1 ) * sizeof(TCHAR) );
  922. if ( !_pszFilenames[ _nFiles ] )
  923. {
  924. hr = E_OUTOFMEMORY;
  925. goto Error;
  926. }
  927. strcpy( _pszFilenames[ _nFiles ], pszFilename );
  928. _GetFilename( _pszFilenames[ _nFiles ], NULL, &xMargin );
  929. xMargin += 7 + 2; // line number and file number
  930. xMargin *= _xSpace;
  931. if ( xMargin > _xMargin )
  932. {
  933. _xMargin = xMargin;
  934. }
  935. hFile = CreateFile( _pszFilenames[ _nFiles ],
  936. GENERIC_READ,
  937. FILE_SHARE_READ | FILE_SHARE_WRITE,
  938. NULL,
  939. OPEN_EXISTING,
  940. 0,
  941. NULL );
  942. if ( hFile == INVALID_HANDLE_VALUE )
  943. {
  944. hr = HRESULT_FROM_WIN32( GetLastError( ) );
  945. goto Error;
  946. }
  947. nLength = GetFileSize( hFile, NULL );
  948. if ( nLength == 0xFFFFffff && GetLastError( ) != NO_ERROR )
  949. {
  950. hr = HRESULT_FROM_WIN32( GetLastError( ) );
  951. goto Error;
  952. }
  953. nLength++; // one for NULL
  954. #if defined(_DEBUG)
  955. _pFiles[ _nFiles ] = (LPTSTR) LocalAlloc( LPTR, nLength );
  956. #else
  957. _pFiles[ _nFiles ] = (LPTSTR) LocalAlloc( LMEM_FIXED, nLength );
  958. #endif
  959. if ( !_pFiles[ _nFiles ] )
  960. {
  961. hr = E_OUTOFMEMORY;
  962. goto Error;
  963. }
  964. if ( !ReadFile( hFile, _pFiles[ _nFiles ], nLength, &dwRead, NULL ) )
  965. {
  966. hr = HRESULT_FROM_WIN32( GetLastError( ) );
  967. goto Error;
  968. }
  969. hr = _CombineFiles( );
  970. Cleanup:
  971. if ( hFile != INVALID_HANDLE_VALUE )
  972. CloseHandle( hFile );
  973. return hr;
  974. Error:
  975. if ( _pFiles[ _nFiles ] )
  976. {
  977. LocalFree( _pFiles[ _nFiles ] );
  978. _pFiles[ _nFiles ] = NULL;
  979. }
  980. MessageBox( _hWnd, pszFilename, TEXT("File Error"), MB_ICONEXCLAMATION | MB_OK );
  981. goto Cleanup;
  982. }
  983. //
  984. // _PaintLine( )
  985. //
  986. HRESULT
  987. CApplicationWindow::_PaintLine(
  988. PAINTSTRUCT * pps,
  989. LINEPOINTER * pCurrent,
  990. LONG wxStart,
  991. LONG wy,
  992. COLORREF crText,
  993. COLORREF crDark,
  994. COLORREF crNormal,
  995. COLORREF crHightlite
  996. )
  997. {
  998. LPTSTR pszStartLine; // beginning of line (PID/TID)
  999. LPTSTR pszStartTimeDate; // beginning of time/data stamp
  1000. LPTSTR pszStartComponent; // beginning of component name
  1001. LPTSTR pszStartResType; // beginning of a resource component
  1002. LPTSTR pszStartText; // beginning of text
  1003. LPTSTR pszCurrent; // current position and beginning of text
  1004. TCHAR szFilename[ 40 ];
  1005. LONG cchFilename;
  1006. SIZE size;
  1007. RECT rect;
  1008. RECT rectResult;
  1009. LONG wx = wxStart;
  1010. LONG wxTextStart;
  1011. if ( pCurrent->psLine )
  1012. {
  1013. pszCurrent = pCurrent->psLine;
  1014. // draw node number
  1015. SetRect( &rect,
  1016. wx,
  1017. wy,
  1018. wx + _xSpace * 2,
  1019. wy + _tm.tmHeight );
  1020. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1021. {
  1022. TCHAR szBuf[ 2 ];
  1023. SetBkColor( pps->hdc, GetSysColor( COLOR_WINDOW ) );
  1024. SetTextColor( pps->hdc, GetSysColor( COLOR_WINDOWTEXT ) );
  1025. DrawText( pps->hdc,
  1026. szBuf,
  1027. wsprintf( szBuf, TEXT("%1u "), pCurrent->nFile ),
  1028. &rect,
  1029. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1030. }
  1031. wx += 2 * _xSpace;
  1032. // Draw Filename
  1033. cchFilename = sizeof(szFilename)/sizeof(szFilename[0]);
  1034. _GetFilename( _pszFilenames[ pCurrent->nFile ], szFilename, &cchFilename );
  1035. SetRect( &rect,
  1036. wx,
  1037. wy,
  1038. _xMargin,
  1039. wy + _tm.tmHeight );
  1040. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1041. {
  1042. SetBkColor( pps->hdc, crNormal );
  1043. SetTextColor( pps->hdc, crText );
  1044. HBRUSH hBrush;
  1045. hBrush = CreateSolidBrush( crNormal );
  1046. FillRect( pps->hdc, &rect, hBrush );
  1047. DeleteObject( hBrush );
  1048. DrawText( pps->hdc,
  1049. szFilename,
  1050. cchFilename,
  1051. &rect,
  1052. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1053. }
  1054. wx += _xMargin - ( 7 * _xSpace - 2 * _xSpace );
  1055. // draw line number
  1056. SetRect( &rect,
  1057. wx,
  1058. wy,
  1059. wx + 7 * _xSpace,
  1060. wy + _tm.tmHeight );
  1061. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1062. {
  1063. TCHAR szBuf[ 8 ];
  1064. SetTextColor( pps->hdc, crText );
  1065. SetBkColor( pps->hdc, crDark );
  1066. DrawText( pps->hdc,
  1067. szBuf,
  1068. wsprintf( szBuf, TEXT("%07.7u"), pCurrent->nLine ),
  1069. &rect,
  1070. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1071. }
  1072. wx += 7 * _xSpace;
  1073. SetRect( &rect,
  1074. wx,
  1075. wy,
  1076. wx + _xSpace,
  1077. wy + _tm.tmHeight );
  1078. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1079. {
  1080. SetBkColor( pps->hdc, crNormal );
  1081. SetTextColor( pps->hdc, crText );
  1082. DrawText( pps->hdc,
  1083. " ",
  1084. 1,
  1085. &rect,
  1086. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1087. }
  1088. wx += _xSpace;
  1089. //
  1090. // KB: This is what a typical cluster log line looks like.
  1091. // 000003fc.00000268::1999/07/19-19:14:45.548 [EVT] Node up: 2, new UpNodeSet: 0002
  1092. // 000003fc.00000268::1999/07/19-19:14:45.548 [EVT] EvOnline : calling ElfRegisterClusterSvc
  1093. // 000003fc.00000268::1999/07/19-19:14:45.548 [GUM] GumSendUpdate: queuing update type 2 context 19
  1094. // 000003fc.00000268::1999/07/19-19:14:45.548 [GUM] GumSendUpdate: Dispatching seq 2585 type 2 context 19 to node 1
  1095. // 000003fc.00000268::1999/07/19-19:14:45.548 [NM] Received update to set extended state for node 1 to 0
  1096. // 000003fc.00000268::1999/07/19-19:14:45.548 [NM] Issuing event 0.
  1097. // 000003fc.00000268::1999/07/19-19:14:45.548 [GUM] GumSendUpdate: completed update seq 2585 type 2 context 19
  1098. // 0000037c.000003a0::1999/07/19-19:14:45.548 Physical Disk: AddVolume : \\?\Volume{99d8d508-39fa-11d3-a200-806d6172696f}\ 'C', 7 (11041600)
  1099. // 0000037c.000003a0::1999/07/19-19:14:45.558 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d503-39fa-11d3-a200-806d6172696f}), error 170
  1100. // 0000037c.000003a0::1999/07/19-19:14:45.568 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d504-39fa-11d3-a200-806d6172696f}), error 170
  1101. // 0000037c.000003a0::1999/07/19-19:14:45.568 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d505-39fa-11d3-a200-806d6172696f}), error 170
  1102. // 0000037c.000003a0::1999/07/19-19:14:45.578 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d506-39fa-11d3-a200-806d6172696f}), error 170
  1103. // 0000037c.000003a0::1999/07/19-19:14:45.578 Physical Disk: AddVolume: GetPartitionInfo(\??\Volume{99d8d501-39fa-11d3-a200-806d6172696f}), error 1
  1104. //
  1105. pszStartResType =
  1106. pszStartComponent = NULL;
  1107. pszStartLine =
  1108. pszStartText =
  1109. pszStartTimeDate =
  1110. pszCurrent = pCurrent->psLine;
  1111. // Find the thread and process IDs
  1112. while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent >= 32 )
  1113. {
  1114. pszCurrent++;
  1115. }
  1116. if ( *pszCurrent < 32 )
  1117. {
  1118. goto DrawRestOfLine;
  1119. }
  1120. pszCurrent++;
  1121. if ( *pszCurrent != ':' )
  1122. {
  1123. goto DrawRestOfLine;
  1124. }
  1125. pszCurrent++;
  1126. // Find Time/Date stamp which is:
  1127. // ####/##/##-##:##:##.###<space>
  1128. pszStartTimeDate = pszCurrent;
  1129. while ( *pszCurrent && *pszCurrent != ' ' && *pszCurrent >= 32 )
  1130. {
  1131. pszCurrent++;
  1132. }
  1133. if ( *pszCurrent < 32 )
  1134. {
  1135. goto DrawRestOfLine;
  1136. }
  1137. pszCurrent++;
  1138. if ( pCurrent->WarnLevel != WarnLevelUnknown )
  1139. {
  1140. // skip warn/info/err tag
  1141. //
  1142. while ( *pszCurrent != 32)
  1143. {
  1144. pszCurrent++;
  1145. }
  1146. while ( *pszCurrent == 32)
  1147. {
  1148. pszCurrent++;
  1149. }
  1150. }
  1151. pszStartText = pszCurrent;
  1152. // [OPTIONAL] Cluster component which looks like:
  1153. // [<id...>]
  1154. if ( *pszCurrent == '[' )
  1155. {
  1156. while ( *pszCurrent && *pszCurrent != ']' && *pszCurrent >= 32 )
  1157. {
  1158. pszCurrent++;
  1159. }
  1160. if ( *pszCurrent < 32 )
  1161. {
  1162. goto NoComponentTryResouce;
  1163. }
  1164. pszCurrent++;
  1165. pszStartComponent = pszStartText;
  1166. pszStartText = pszCurrent;
  1167. }
  1168. else
  1169. {
  1170. // [OPTIONAL] If not a component, see if there is a res type
  1171. NoComponentTryResouce:
  1172. pszCurrent = pszStartText;
  1173. while ( *pszCurrent && *pszCurrent != ':' && *pszCurrent >= 32 )
  1174. {
  1175. pszCurrent++;
  1176. }
  1177. if ( *pszCurrent >= 32 )
  1178. {
  1179. pszCurrent++;
  1180. pszStartResType = pszStartText;
  1181. pszStartText = pszCurrent;
  1182. }
  1183. }
  1184. // Draw PID and TID
  1185. GetTextExtentPoint32( pps->hdc,
  1186. pszStartLine,
  1187. (int)(pszStartTimeDate - pszStartLine - 2),
  1188. &size );
  1189. SetRect( &rect,
  1190. wx,
  1191. wy,
  1192. wx + size.cx,
  1193. wy + _tm.tmHeight );
  1194. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1195. {
  1196. SetBkColor( pps->hdc, crNormal );
  1197. SetTextColor( pps->hdc, crText );
  1198. DrawText( pps->hdc,
  1199. pszStartLine,
  1200. (int)(pszStartTimeDate - pszStartLine - 2),
  1201. &rect,
  1202. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1203. }
  1204. wx += size.cx;
  1205. GetTextExtentPoint32( pps->hdc,
  1206. "::",
  1207. 2,
  1208. &size );
  1209. SetRect( &rect,
  1210. wx,
  1211. wy,
  1212. wx + size.cx,
  1213. wy + _tm.tmHeight );
  1214. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1215. {
  1216. SetBkColor( pps->hdc, crNormal );
  1217. SetTextColor( pps->hdc, crText );
  1218. DrawText( pps->hdc,
  1219. "::",
  1220. 2,
  1221. &rect,
  1222. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1223. }
  1224. wx += size.cx;
  1225. // Draw Time/Date
  1226. pszCurrent = ( pszStartComponent ?
  1227. pszStartComponent :
  1228. ( pszStartResType ?
  1229. pszStartResType :
  1230. pszStartText )
  1231. ) - 1;
  1232. GetTextExtentPoint32( pps->hdc,
  1233. pszStartTimeDate,
  1234. (int)(pszCurrent - pszStartTimeDate),
  1235. &size );
  1236. SetRect( &rect,
  1237. wx,
  1238. wy,
  1239. wx + size.cx,
  1240. wy + _tm.tmHeight );
  1241. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1242. {
  1243. SetBkColor( pps->hdc, crDark );
  1244. SetTextColor( pps->hdc, crText );
  1245. DrawText( pps->hdc,
  1246. pszStartTimeDate,
  1247. (int)(pszCurrent - pszStartTimeDate),
  1248. &rect,
  1249. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1250. }
  1251. wx += size.cx;
  1252. SetRect( &rect,
  1253. wx,
  1254. wy,
  1255. wx + _xSpace,
  1256. wy + _tm.tmHeight );
  1257. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1258. {
  1259. SetBkColor( pps->hdc, crNormal );
  1260. SetTextColor( pps->hdc, crText );
  1261. DrawText( pps->hdc,
  1262. " ",
  1263. 1,
  1264. &rect,
  1265. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1266. }
  1267. wx += _xSpace;
  1268. #ifdef _DEBUG
  1269. // draw sequence number
  1270. SetRect( &rect,
  1271. wx,
  1272. wy,
  1273. wx + 7 * _xSpace,
  1274. wy + _tm.tmHeight );
  1275. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1276. {
  1277. TCHAR szBuf[ 8 ];
  1278. SetTextColor( pps->hdc, crText );
  1279. SetBkColor( pps->hdc, crNormal );
  1280. DrawText( pps->hdc,
  1281. szBuf,
  1282. wsprintf( szBuf, TEXT("#%7u%s"),
  1283. pCurrent->uSequenceNumber,// / 2,
  1284. pCurrent->fSyncPoint ? "*" : " " ),
  1285. &rect,
  1286. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1287. }
  1288. wx += 9 * _xSpace;
  1289. #endif
  1290. // Draw component
  1291. if ( pszStartComponent )
  1292. {
  1293. SetRect( &rect,
  1294. wx,
  1295. wy,
  1296. wx + 10 * _xSpace,
  1297. wy + _tm.tmHeight );
  1298. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1299. {
  1300. SetBkColor( pps->hdc, crNormal );
  1301. SetTextColor( pps->hdc, crText );
  1302. DrawText( pps->hdc,
  1303. " ",
  1304. 10,
  1305. &rect,
  1306. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1307. }
  1308. GetTextExtentPoint32( pps->hdc,
  1309. pszStartComponent,
  1310. (int)(pszStartText - pszStartComponent),
  1311. &size );
  1312. SetRect( &rect,
  1313. wx,
  1314. wy,
  1315. wx + size.cx,
  1316. wy + _tm.tmHeight );
  1317. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1318. {
  1319. SetBkColor( pps->hdc, crNormal );
  1320. SetTextColor( pps->hdc, crText );
  1321. DrawText( pps->hdc,
  1322. pszStartComponent,
  1323. (int)(pszStartText - pszStartComponent),
  1324. &rect,
  1325. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1326. }
  1327. wx += 10 * _xSpace;
  1328. }
  1329. if ( pszStartResType )
  1330. {
  1331. GetTextExtentPoint32( pps->hdc,
  1332. pszStartResType,
  1333. (int)(pszStartText - pszStartResType),
  1334. &size );
  1335. SetRect( &rect,
  1336. wx,
  1337. wy,
  1338. wx + size.cx,
  1339. wy + _tm.tmHeight );
  1340. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1341. {
  1342. SetBkColor( pps->hdc, crNormal );
  1343. SetTextColor( pps->hdc, crText );
  1344. DrawText( pps->hdc,
  1345. pszStartResType,
  1346. (int)(pszStartText - pszStartResType),
  1347. &rect,
  1348. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1349. }
  1350. wx += size.cx;
  1351. }
  1352. DrawRestOfLine:
  1353. pszCurrent = pszStartText;
  1354. wxTextStart = wx;
  1355. while ( *pszCurrent && *pszCurrent != 13 )
  1356. {
  1357. pszCurrent++;
  1358. }
  1359. SetRect( &rect,
  1360. wx,
  1361. wy,
  1362. _xWindow,
  1363. wy + _tm.tmHeight );
  1364. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1365. {
  1366. SetBkColor( pps->hdc, crNormal );
  1367. SetTextColor( pps->hdc, crText );
  1368. HBRUSH hBrush;
  1369. hBrush = CreateSolidBrush( crNormal );
  1370. FillRect( pps->hdc, &rect, hBrush );
  1371. DeleteObject( hBrush );
  1372. DrawText( pps->hdc,
  1373. pszStartText,
  1374. (int)(pszCurrent - pszStartText),
  1375. &rect,
  1376. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_EXPANDTABS );
  1377. }
  1378. // See if "Finder" needs to paint on this line
  1379. if ( pCurrent->nFile == _LineFinder.nFile
  1380. && pCurrent->nLine == _LineFinder.nLine )
  1381. {
  1382. wx = wxTextStart;
  1383. if ( pszStartResType )
  1384. {
  1385. GetTextExtentPoint32( pps->hdc,
  1386. pszStartResType,
  1387. (int)(_LineFinder.psLine - pszStartResType),
  1388. &size );
  1389. wx += size.cx;
  1390. }
  1391. else
  1392. {
  1393. GetTextExtentPoint32( pps->hdc,
  1394. pszStartText,
  1395. (int)(_LineFinder.psLine - pszStartText),
  1396. &size );
  1397. wx += size.cx;
  1398. }
  1399. GetTextExtentPoint32( pps->hdc,
  1400. _LineFinder.psLine,
  1401. _uFinderLength,
  1402. &size
  1403. );
  1404. SetRect( &rect,
  1405. wx,
  1406. wy,
  1407. wx + size.cx,
  1408. wy + _tm.tmHeight );
  1409. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1410. {
  1411. SetBkColor( pps->hdc, crHightlite );
  1412. SetTextColor( pps->hdc, ~crHightlite );
  1413. DrawText( pps->hdc,
  1414. _LineFinder.psLine,
  1415. _uFinderLength,
  1416. &rect,
  1417. DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE );
  1418. }
  1419. }
  1420. wx = _xWindow;
  1421. }
  1422. // fill in the rest of the line
  1423. SetRect( &rect,
  1424. wx,
  1425. wy,
  1426. _xWindow,
  1427. wy + _tm.tmHeight );
  1428. if ( IntersectRect( &rectResult, &pps->rcPaint, &rect ) )
  1429. {
  1430. SetBkColor( pps->hdc, crNormal );
  1431. SetTextColor( pps->hdc, crText );
  1432. HBRUSH hBrush;
  1433. hBrush = CreateSolidBrush( crNormal );
  1434. FillRect( pps->hdc, &rect, hBrush );
  1435. DeleteObject( hBrush );
  1436. }
  1437. return S_OK;
  1438. }
  1439. //
  1440. // _OnPaint( )
  1441. //
  1442. LRESULT
  1443. CApplicationWindow::_OnPaint(
  1444. WPARAM wParam,
  1445. LPARAM lParam )
  1446. {
  1447. HDC hdc;
  1448. LONG wxStart;
  1449. LONG wy;
  1450. RECT rect;
  1451. RECT rectResult;
  1452. ULONG nLineCount;
  1453. LINEPOINTER * pCurrent;
  1454. SCROLLINFO si;
  1455. PAINTSTRUCT ps;
  1456. static COLORREF crBkColor[ MAX_OPEN_FILES ] = {
  1457. 0xFFE0E0,
  1458. 0xE0FFE0,
  1459. 0xE0E0FF,
  1460. 0xFFFFE0,
  1461. 0xE0FFFF,
  1462. 0xFFE0FF,
  1463. 0xE0E0E0,
  1464. 0xC0C0C0,
  1465. 0x909090,
  1466. 0x000000
  1467. };
  1468. static COLORREF crBkColorDarker[ MAX_OPEN_FILES ] = {
  1469. 0xFFC0C0,
  1470. 0xC0FFC0,
  1471. 0xC0C0FF,
  1472. 0xFFFFC0,
  1473. 0xC0FFFF,
  1474. 0xFFC0FF,
  1475. 0xC0C0C0,
  1476. 0xA0A0A0,
  1477. 0x707070,
  1478. 0x101010
  1479. };
  1480. static COLORREF crBkColorHighlite[ MAX_OPEN_FILES ] = {
  1481. 0xFF0000,
  1482. 0x00FF00,
  1483. 0x0000FF,
  1484. 0xFFFF00,
  1485. 0x00FFFF,
  1486. 0xFF00FF,
  1487. 0x101010,
  1488. 0x404040,
  1489. 0x606060,
  1490. 0xFFFFFF
  1491. };
  1492. si.cbSize = sizeof(si);
  1493. si.fMask = SIF_POS;
  1494. GetScrollInfo( _hWnd, SB_HORZ, &si );
  1495. wxStart = si.nPos;
  1496. si.cbSize = sizeof(si);
  1497. si.fMask = SIF_POS | SIF_PAGE;
  1498. GetScrollInfo( _hWnd, SB_VERT, &si );
  1499. hdc = BeginPaint( _hWnd, &ps);
  1500. if ( !_pLines )
  1501. goto EndPaint;
  1502. SetBkMode( hdc, OPAQUE );
  1503. SelectObject( hdc, g_hFont );
  1504. nLineCount = 0;
  1505. pCurrent = _pLines;
  1506. while ( pCurrent && nLineCount < (ULONG) si.nPos )
  1507. {
  1508. if ( !pCurrent->fFiltered )
  1509. {
  1510. nLineCount++;
  1511. }
  1512. pCurrent = pCurrent->pNext;
  1513. }
  1514. wy = 0;
  1515. while ( pCurrent
  1516. && nLineCount <= si.nPos + si.nPage + 1 )
  1517. {
  1518. // ignore filtered lines
  1519. if ( pCurrent->fFiltered )
  1520. {
  1521. pCurrent = pCurrent->pNext;
  1522. continue;
  1523. }
  1524. if ( nLineCount >= _uStartSelection
  1525. && nLineCount <= _uEndSelection )
  1526. {
  1527. _PaintLine( &ps,
  1528. pCurrent,
  1529. -wxStart,
  1530. wy,
  1531. GetSysColor( COLOR_WINDOWTEXT ),
  1532. crBkColorHighlite[ pCurrent->nFile ],
  1533. crBkColorHighlite[ pCurrent->nFile ],
  1534. crBkColorDarker[ pCurrent->nFile ]
  1535. );
  1536. }
  1537. else
  1538. {
  1539. _PaintLine( &ps,
  1540. pCurrent,
  1541. -wxStart,
  1542. wy,
  1543. GetSysColor( COLOR_WINDOWTEXT ),
  1544. crBkColorDarker[ pCurrent->nFile ],
  1545. crBkColor[ pCurrent->nFile ],
  1546. crBkColorHighlite[ pCurrent->nFile ]
  1547. );
  1548. }
  1549. wy += _tm.tmHeight;
  1550. nLineCount++;
  1551. pCurrent = pCurrent->pNext;
  1552. }
  1553. // Fill the rest with normal background color
  1554. SetRect( &rect,
  1555. 0,
  1556. wy,
  1557. _xWindow,
  1558. _yWindow );
  1559. if ( IntersectRect( &rectResult, &ps.rcPaint, &rect ) )
  1560. {
  1561. HBRUSH hBrush;
  1562. hBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
  1563. FillRect( hdc, &rect, hBrush );
  1564. DeleteObject( hBrush );
  1565. }
  1566. EndPaint:
  1567. EndPaint(_hWnd, &ps);
  1568. return 0;
  1569. }
  1570. //
  1571. // _FindNext( )
  1572. //
  1573. LRESULT
  1574. CApplicationWindow::_FindNext(
  1575. WPARAM wParam,
  1576. LPARAM lParam
  1577. )
  1578. {
  1579. SCROLLINFO si;
  1580. LPTSTR pszSearch;
  1581. LPTSTR psz;
  1582. ULONG n; // general counter
  1583. LPTSTR pszSearchString = (LPTSTR) lParam; // NEEDS TO BE FREEd!!!
  1584. WPARAM wFlags = wParam;
  1585. CWaitCursor Wait;
  1586. _uFinderLength = lstrlen( pszSearchString );
  1587. if( wFlags & FIND_UP )
  1588. {
  1589. //
  1590. // TODO: Make a better "up" search
  1591. //
  1592. if ( _LineFinder.pPrev )
  1593. {
  1594. CopyMemory( &_LineFinder, _LineFinder.pPrev, sizeof(LINEPOINTER) );
  1595. }
  1596. else
  1597. {
  1598. LINEPOINTER * lpLast;
  1599. LINEPOINTER * lp = _pLines;
  1600. while( lp )
  1601. {
  1602. lpLast = lp;
  1603. lp = lp->pNext;
  1604. }
  1605. CopyMemory( &_LineFinder, lpLast, sizeof(LINEPOINTER) );
  1606. }
  1607. }
  1608. else // find down
  1609. {
  1610. if ( _LineFinder.psLine )
  1611. {
  1612. // see if there is another instance on the same line
  1613. psz = _LineFinder.psLine;
  1614. for( n = 0; n < _uFinderLength; n++ )
  1615. {
  1616. if ( !*psz || *psz == 10 )
  1617. break;
  1618. psz++;
  1619. }
  1620. if ( *psz && *psz != 10 )
  1621. goto ResumeSearch;
  1622. }
  1623. }
  1624. if ( _LineFinder.psLine == NULL )
  1625. {
  1626. CopyMemory( &_LineFinder, _pLines->pNext, sizeof(LINEPOINTER) );
  1627. }
  1628. for(;;)
  1629. {
  1630. psz = _LineFinder.psLine;
  1631. if ( !psz )
  1632. break;
  1633. // skip PID/TID and time/date
  1634. while ( *psz && *psz != 10 )
  1635. {
  1636. if ( *psz == ':' )
  1637. {
  1638. psz++;
  1639. if ( *psz == ':' )
  1640. {
  1641. break;
  1642. }
  1643. }
  1644. psz++;
  1645. }
  1646. while ( *psz && *psz != 10 )
  1647. {
  1648. if ( *psz == 32 )
  1649. {
  1650. psz++;
  1651. break;
  1652. }
  1653. psz++;
  1654. }
  1655. if ( _LineFinder.WarnLevel != WarnLevelUnknown )
  1656. {
  1657. // skip info/warn/err tag
  1658. while ( *psz != 32)
  1659. {
  1660. psz++;
  1661. }
  1662. while ( *psz == 32)
  1663. {
  1664. psz++;
  1665. }
  1666. }
  1667. // skip components
  1668. if ( *psz == '[' )
  1669. {
  1670. while ( *psz && *psz != ']' )
  1671. {
  1672. psz++;
  1673. }
  1674. }
  1675. if ( *psz == 10 )
  1676. goto NextLine;
  1677. if ( !*psz )
  1678. break;
  1679. ResumeSearch:
  1680. pszSearch = pszSearchString;
  1681. while ( *psz != 10 )
  1682. {
  1683. if ( ( wFlags & FIND_MATCHCASE )
  1684. && *psz != *pszSearch )
  1685. {
  1686. goto ResetMatch;
  1687. }
  1688. if ( toupper( *psz ) == toupper( *pszSearch ) )
  1689. {
  1690. pszSearch++;
  1691. if ( !*pszSearch )
  1692. {
  1693. ULONG cLine;
  1694. LINEPOINTER * lp;
  1695. if ( wFlags & FIND_WHOLE_WORD
  1696. && isalnum( psz[ 1 ] ) )
  1697. {
  1698. psz++; // need to bump
  1699. goto ResetMatch;
  1700. }
  1701. _LineFinder.psLine = psz - _uFinderLength + 1;
  1702. // find the line
  1703. lp = _pLines;
  1704. cLine = 0;
  1705. while( lp )
  1706. {
  1707. if ( lp->nFile == _LineFinder.nFile
  1708. && lp->nLine == _LineFinder.nLine )
  1709. {
  1710. break;
  1711. }
  1712. if ( !lp->fFiltered )
  1713. {
  1714. cLine++;
  1715. }
  1716. lp = lp->pNext;
  1717. }
  1718. _uPointer = _uStartSelection = _uEndSelection = cLine;
  1719. si.cbSize = sizeof(si);
  1720. si.fMask = SIF_PAGE;
  1721. GetScrollInfo( _hWnd, SB_VERT, &si );
  1722. si.fMask = SIF_POS;
  1723. si.nPos = cLine - si.nPage / 2;
  1724. SetScrollInfo( _hWnd, SB_VERT, &si, TRUE );
  1725. InvalidateRect( _hWnd, NULL, FALSE );
  1726. LocalFree( pszSearchString );
  1727. return 1;
  1728. }
  1729. }
  1730. else
  1731. {
  1732. ResetMatch:
  1733. psz -= ( pszSearch - pszSearchString );
  1734. pszSearch = pszSearchString;
  1735. }
  1736. if ( !*psz )
  1737. break;
  1738. psz++;
  1739. }
  1740. NextLine:
  1741. if ( wFlags & FIND_UP )
  1742. {
  1743. if ( _LineFinder.pPrev != NULL )
  1744. {
  1745. CopyMemory( &_LineFinder, _LineFinder.pPrev, sizeof(LINEPOINTER) );
  1746. }
  1747. else
  1748. {
  1749. break; // end of search
  1750. }
  1751. }
  1752. else // find down
  1753. {
  1754. if ( _LineFinder.pNext != NULL )
  1755. {
  1756. CopyMemory( &_LineFinder, _LineFinder.pNext, sizeof(LINEPOINTER) );
  1757. }
  1758. else
  1759. {
  1760. break; // end of search
  1761. }
  1762. }
  1763. }
  1764. // not found
  1765. ZeroMemory( &_LineFinder, sizeof(LINEPOINTER) );
  1766. if ( wFlags & FIND_UP )
  1767. {
  1768. _LineFinder.nLine = 0;
  1769. }
  1770. else
  1771. {
  1772. _LineFinder.nLine = _cTotalLineCount;
  1773. }
  1774. LocalFree( pszSearchString );
  1775. return 0;
  1776. }
  1777. //
  1778. // _MarkAll( )
  1779. //
  1780. LRESULT
  1781. CApplicationWindow::_MarkAll(
  1782. WPARAM wParam,
  1783. LPARAM lParam
  1784. )
  1785. {
  1786. WPARAM wFlags = wParam;
  1787. LPTSTR pszSearchString = (LPTSTR) lParam;
  1788. LocalFree( pszSearchString );
  1789. return 0;
  1790. }
  1791. //
  1792. // _OnSize( )
  1793. //
  1794. LRESULT
  1795. CApplicationWindow::_OnSize(
  1796. LPARAM lParam )
  1797. {
  1798. HDC hdc;
  1799. SIZE size;
  1800. HGDIOBJ hObj;
  1801. TCHAR szSpace[ 1 ] = { TEXT(' ') };
  1802. SCROLLINFO si;
  1803. _xWindow = LOWORD( lParam );
  1804. _yWindow = HIWORD( lParam );
  1805. hdc = GetDC( _hWnd );
  1806. hObj = SelectObject( hdc, g_hFont );
  1807. GetTextMetrics( hdc, &_tm );
  1808. GetTextExtentPoint32( hdc, szSpace, 1, &size );
  1809. _xSpace = size.cx;
  1810. si.cbSize = sizeof(si);
  1811. si.fMask = SIF_RANGE | SIF_PAGE;
  1812. si.nMin = 0;
  1813. si.nMax = _cTotalLineCount;
  1814. si.nPage = _yWindow / _tm.tmHeight;
  1815. SetScrollInfo( _hWnd, SB_VERT, &si, FALSE );
  1816. si.fMask = SIF_RANGE | SIF_PAGE;
  1817. si.nMin = 0;
  1818. si.nMax = 1000;
  1819. si.nPage = _xWindow / _tm.tmHeight;
  1820. SetScrollInfo( _hWnd, SB_HORZ, &si, FALSE );
  1821. // cleanup the HDC
  1822. SelectObject( hdc, hObj );
  1823. ReleaseDC( _hWnd, hdc );
  1824. return 0;
  1825. }
  1826. //
  1827. // _OnMouseWheel( )
  1828. //
  1829. LRESULT
  1830. CApplicationWindow::_OnMouseWheel( SHORT iDelta )
  1831. {
  1832. if ( iDelta > 0 )
  1833. {
  1834. SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 );
  1835. SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 );
  1836. SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 );
  1837. }
  1838. else if ( iDelta < 0 )
  1839. {
  1840. SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 );
  1841. SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 );
  1842. SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 );
  1843. }
  1844. return 0;
  1845. }
  1846. //
  1847. // _OnVerticalScroll( )
  1848. //
  1849. LRESULT
  1850. CApplicationWindow::_OnVerticalScroll(
  1851. WPARAM wParam,
  1852. LPARAM lParam )
  1853. {
  1854. SCROLLINFO si;
  1855. RECT rect;
  1856. INT nScrollCode = LOWORD(wParam); // scroll bar value
  1857. INT nPos;
  1858. //INT nPos = HIWORD(wParam); // scroll box position
  1859. //HWND hwndScrollBar = (HWND) lParam; // handle to scroll bar
  1860. si.cbSize = sizeof(si);
  1861. si.fMask = SIF_ALL;
  1862. GetScrollInfo( _hWnd, SB_VERT, &si );
  1863. nPos = si.nPos;
  1864. switch( nScrollCode )
  1865. {
  1866. case SB_BOTTOM:
  1867. si.nPos = si.nMax;
  1868. break;
  1869. case SB_THUMBPOSITION:
  1870. si.nPos = nPos;
  1871. break;
  1872. case SB_THUMBTRACK:
  1873. si.nPos = si.nTrackPos;
  1874. break;
  1875. case SB_TOP:
  1876. si.nPos = si.nMin;
  1877. break;
  1878. case SB_LINEDOWN:
  1879. si.nPos += 1;
  1880. break;
  1881. case SB_LINEUP:
  1882. si.nPos -= 1;
  1883. break;
  1884. case SB_PAGEDOWN:
  1885. si.nPos += si.nPage;
  1886. InvalidateRect( _hWnd, NULL, FALSE );
  1887. break;
  1888. case SB_PAGEUP:
  1889. si.nPos -= si.nPage;
  1890. InvalidateRect( _hWnd, NULL, FALSE );
  1891. break;
  1892. }
  1893. si.fMask = SIF_POS;
  1894. SetScrollInfo( _hWnd, SB_VERT, &si, TRUE );
  1895. GetScrollInfo( _hWnd, SB_VERT, &si );
  1896. if ( si.nPos != nPos )
  1897. {
  1898. ScrollWindowEx( _hWnd,
  1899. 0,
  1900. (nPos - si.nPos) * _tm.tmHeight,
  1901. NULL,
  1902. NULL,
  1903. NULL,
  1904. NULL,
  1905. SW_INVALIDATE );
  1906. SetRect( &rect, 0, ( _uPointer - si.nPos - 1 ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 2 ) * _tm.tmHeight );
  1907. InvalidateRect( _hWnd, &rect, FALSE );
  1908. }
  1909. return 0;
  1910. }
  1911. //
  1912. // _OnHorizontalScroll( )
  1913. //
  1914. LRESULT
  1915. CApplicationWindow::_OnHorizontalScroll(
  1916. WPARAM wParam,
  1917. LPARAM lParam )
  1918. {
  1919. SCROLLINFO si;
  1920. INT nScrollCode = LOWORD(wParam); // scroll bar value
  1921. INT nPos;
  1922. //INT nPos = HIWORD(wParam); // scroll box position
  1923. //HWND hwndScrollBar = (HWND) lParam; // handle to scroll bar
  1924. si.cbSize = sizeof(si);
  1925. si.fMask = SIF_ALL;
  1926. GetScrollInfo( _hWnd, SB_HORZ, &si );
  1927. nPos = si.nPos;
  1928. switch( nScrollCode )
  1929. {
  1930. case SB_BOTTOM:
  1931. si.nPos = si.nMax;
  1932. break;
  1933. case SB_THUMBPOSITION:
  1934. si.nPos = nPos;
  1935. break;
  1936. case SB_THUMBTRACK:
  1937. si.nPos = si.nTrackPos;
  1938. break;
  1939. case SB_TOP:
  1940. si.nPos = si.nMin;
  1941. break;
  1942. case SB_LINEDOWN:
  1943. si.nPos += 1;
  1944. break;
  1945. case SB_LINEUP:
  1946. si.nPos -= 1;
  1947. break;
  1948. case SB_PAGEDOWN:
  1949. si.nPos += si.nPage;
  1950. break;
  1951. case SB_PAGEUP:
  1952. si.nPos -= si.nPage;
  1953. break;
  1954. }
  1955. si.fMask = SIF_POS;
  1956. SetScrollInfo( _hWnd, SB_HORZ, &si, TRUE );
  1957. GetScrollInfo( _hWnd, SB_HORZ, &si );
  1958. if ( si.nPos != nPos )
  1959. {
  1960. ScrollWindowEx( _hWnd,
  1961. (nPos - si.nPos),
  1962. 0,
  1963. NULL,
  1964. NULL,
  1965. NULL,
  1966. NULL,
  1967. SW_INVALIDATE );
  1968. }
  1969. return 0;
  1970. }
  1971. //
  1972. // _FillClipboard( )
  1973. //
  1974. HRESULT
  1975. CApplicationWindow::_FillClipboard( )
  1976. {
  1977. HANDLE hClip;
  1978. LPTSTR pszClip;
  1979. LPTSTR psz;
  1980. ULONG dwSize;
  1981. ULONG nLine;
  1982. TCHAR szFilename[ 40 ];
  1983. LONG cchFilename;
  1984. LINEPOINTER * pCurLine;
  1985. LINEPOINTER * pSelectionStart;
  1986. LONG cchMargin = ( _xMargin / _xSpace ) + 2;
  1987. //0 cluster1.log 0000006 5c4.57c::1999/07/26-21:56:24.682 [EP] Initialization...
  1988. static TCHAR szHeader[] = " Log/Nodename";
  1989. static TCHAR szHeader2[] = "Line### PIDxxxxx.TIDxxxxx Year/MM/DD-HH-MM-SS.HsS Log Entry\n\n";
  1990. if ( cchMargin < sizeof(szHeader) + 8 )
  1991. {
  1992. cchMargin = sizeof(szHeader) + 8;
  1993. }
  1994. //
  1995. // Find the start of the line
  1996. //
  1997. pSelectionStart = _pLines;
  1998. for( nLine = 0; nLine < _uStartSelection; nLine++ )
  1999. {
  2000. pSelectionStart = pSelectionStart->pNext;
  2001. }
  2002. //
  2003. // Tally up the line sizes
  2004. //
  2005. dwSize = cchMargin - 8;
  2006. dwSize += sizeof(szHeader2) - 1;
  2007. pCurLine = pSelectionStart;
  2008. for( ; nLine <= _uEndSelection; nLine++ )
  2009. {
  2010. psz = pCurLine->psLine;
  2011. if ( psz == NULL )
  2012. break;
  2013. while( *psz && *psz != 10 )
  2014. {
  2015. psz++;
  2016. }
  2017. if ( *psz )
  2018. {
  2019. psz++; // inlude LF
  2020. }
  2021. dwSize += (ULONG)(psz - pCurLine->psLine);
  2022. pCurLine = pCurLine->pNext;
  2023. }
  2024. // Add file and line number for every line
  2025. dwSize += ( _uEndSelection - _uStartSelection + 1 ) * cchMargin;
  2026. dwSize++; // add one for NULL terminator
  2027. hClip = (LPTSTR) GlobalAlloc( LMEM_MOVEABLE | GMEM_DDESHARE, dwSize * sizeof(*pszClip) );
  2028. if ( !hClip )
  2029. return E_OUTOFMEMORY;
  2030. pszClip = (LPTSTR) GlobalLock( hClip );
  2031. for ( LONG n = 0; n < cchMargin; n++ )
  2032. {
  2033. pszClip[ n ] = 32;
  2034. }
  2035. CopyMemory( pszClip, szHeader, sizeof(szHeader) - 1 );
  2036. pszClip += cchMargin - 8;
  2037. CopyMemory( pszClip, szHeader2, sizeof(szHeader2) - 1 );
  2038. pszClip += sizeof(szHeader2) - 1;
  2039. pCurLine = pSelectionStart;
  2040. for( nLine = _uStartSelection; nLine <= _uEndSelection; nLine++ )
  2041. {
  2042. for ( LONG n = 0; n < cchMargin; n++ )
  2043. {
  2044. pszClip[ n ] = 32;
  2045. }
  2046. // file number
  2047. _snprintf( pszClip, 1, "%1u", pCurLine->nFile );
  2048. pszClip += 2;
  2049. // filename
  2050. cchFilename = cchMargin - 10;
  2051. _GetFilename( _pszFilenames[ pCurLine->nFile ], szFilename, &cchFilename );
  2052. _snprintf( pszClip, cchFilename, "%s", szFilename );
  2053. pszClip += cchMargin - 10;
  2054. // line number
  2055. _snprintf( pszClip, 7, "%07.7u", pCurLine->nLine );
  2056. pszClip += 7;
  2057. pszClip++;
  2058. psz = pCurLine->psLine;
  2059. if ( psz == NULL )
  2060. break;
  2061. while( *psz && *psz != 10 )
  2062. {
  2063. psz++;
  2064. }
  2065. if ( *psz )
  2066. {
  2067. psz++; // inlude LF
  2068. }
  2069. CopyMemory( pszClip, pCurLine->psLine, psz - pCurLine->psLine );
  2070. pszClip += psz - pCurLine->psLine;
  2071. pCurLine = pCurLine->pNext;
  2072. }
  2073. *pszClip = 0; // terminate
  2074. GlobalUnlock( hClip );
  2075. if ( OpenClipboard( _hWnd ) )
  2076. {
  2077. SetClipboardData( CF_TEXT, hClip );
  2078. CloseClipboard( );
  2079. }
  2080. return S_OK;
  2081. }
  2082. //
  2083. // _ApplyFilters( )
  2084. //
  2085. HRESULT
  2086. CApplicationWindow::_ApplyFilters( )
  2087. {
  2088. SCROLLINFO si;
  2089. ULONG nLineCount = 0;
  2090. LINEPOINTER * lp = _pLines;
  2091. while( lp )
  2092. {
  2093. lp->fFiltered = FALSE;
  2094. if ( lp->nFilterId == g_nComponentFilters + 1 )
  2095. {
  2096. if ( g_fResourceNoise )
  2097. {
  2098. lp->fFiltered = TRUE;
  2099. }
  2100. }
  2101. else if ( lp->nFilterId !=0
  2102. && lp->nFilterId <= g_nComponentFilters )
  2103. {
  2104. if ( g_pfSelectedComponent[ lp->nFilterId - 1 ] )
  2105. {
  2106. lp->fFiltered = TRUE;
  2107. }
  2108. }
  2109. if ( ! lp->fFiltered )
  2110. {
  2111. nLineCount++;
  2112. }
  2113. lp = lp->pNext;
  2114. }
  2115. InvalidateRect( _hWnd, NULL, FALSE );
  2116. // Update scroll bar
  2117. si.cbSize = sizeof(si);
  2118. si.fMask = SIF_RANGE;
  2119. GetScrollInfo( _hWnd, SB_VERT, &si );
  2120. si.nMax = nLineCount;
  2121. SetScrollInfo( _hWnd, SB_VERT, &si, TRUE );
  2122. return S_OK;
  2123. }
  2124. //
  2125. // _OnCommand( )
  2126. //
  2127. LRESULT
  2128. CApplicationWindow::_OnCommand(
  2129. WPARAM wParam,
  2130. LPARAM lParam )
  2131. {
  2132. INT wmId = LOWORD(wParam);
  2133. INT wmEvent = HIWORD(wParam);
  2134. // Parse the menu selections:
  2135. switch (wmId)
  2136. {
  2137. case IDM_ABOUT:
  2138. DialogBox( g_hInstance, (LPCTSTR)IDD_ABOUTBOX, _hWnd, (DLGPROC)About);
  2139. break;
  2140. case IDM_EXIT:
  2141. {
  2142. DestroyWindow( _hWnd );
  2143. }
  2144. break;
  2145. case IDM_FILE_REFRESH:
  2146. {
  2147. ULONG n;
  2148. ULONG nFiles = _nFiles;
  2149. LPTSTR pszFilenames[ MAX_OPEN_FILES ];
  2150. for( n = 0; n < nFiles; n++ )
  2151. {
  2152. pszFilenames[ n ] = _pszFilenames[ n ];
  2153. _pszFilenames[ n ] = NULL;
  2154. }
  2155. Cleanup( );
  2156. for( n = 0; n < nFiles; n++ )
  2157. {
  2158. _LoadFile( pszFilenames[ n ] );
  2159. LocalFree( pszFilenames[ n ] );
  2160. }
  2161. }
  2162. break;
  2163. case IDM_NEW_FILE:
  2164. {
  2165. Cleanup( );
  2166. InvalidateRect( _hWnd, NULL, TRUE );
  2167. }
  2168. break;
  2169. case IDM_OPEN_FILE:
  2170. {
  2171. LPTSTR psz;
  2172. TCHAR szFilters[ MAX_PATH ];
  2173. TCHAR szFilename[ MAX_PATH ];
  2174. LPTSTR pszFilenameBuffer
  2175. = (LPTSTR) LocalAlloc( LPTR, 8 * MAX_PATH );
  2176. ZeroMemory( szFilters, sizeof(szFilters) );
  2177. ZeroMemory( _szOpenFileNameFilter, sizeof(_szOpenFileNameFilter) );
  2178. LoadString( g_hInstance, IDS_OPEN_FILE_FILTERS, szFilters, MAX_PATH );
  2179. for ( psz = szFilters; *psz; psz++ )
  2180. {
  2181. if ( *psz == TEXT(',') )
  2182. {
  2183. *psz = TEXT('\0');
  2184. }
  2185. }
  2186. OPENFILENAME ofn;
  2187. ZeroMemory( &ofn, sizeof(ofn) );
  2188. ofn.lStructSize = sizeof(ofn);
  2189. ofn.hwndOwner = _hWnd;
  2190. ofn.hInstance = g_hInstance;
  2191. ofn.lpstrFilter = szFilters;
  2192. // ofn.lpfnHook = NULL;
  2193. ofn.Flags = OFN_ENABLESIZING
  2194. | OFN_FILEMUSTEXIST
  2195. | OFN_EXPLORER
  2196. | OFN_ALLOWMULTISELECT;
  2197. // ofn.lCustData = 0;
  2198. ofn.lpstrCustomFilter = _szOpenFileNameFilter;
  2199. // ofn.lpstrDefExt = NULL;
  2200. ofn.lpstrFile = pszFilenameBuffer;
  2201. // ofn.lpstrFileTitle = NULL;
  2202. // ofn.lpstrInitialDir = NULL;
  2203. // ofn.lpstrTitle = NULL;
  2204. // ofn.lpTemplateName = NULL;
  2205. // ofn.nFileExtension = 0;
  2206. // ofn.nFileOffset = 0;
  2207. // ofn.nFilterIndex = 1;
  2208. ofn.nMaxCustFilter = MAX_PATH;
  2209. ofn.nMaxFile = 8 * MAX_PATH;
  2210. // ofn.nMaxFileTitle = 0;
  2211. if ( GetOpenFileName( &ofn ) )
  2212. {
  2213. LPTSTR pszFilename = pszFilenameBuffer + ofn.nFileOffset;
  2214. strcpy( szFilename, pszFilenameBuffer );
  2215. szFilename[ ofn.nFileOffset - 1] = '\\';
  2216. while ( *pszFilename )
  2217. {
  2218. strcpy( &szFilename[ ofn.nFileOffset ], pszFilename );
  2219. _LoadFile( szFilename );
  2220. pszFilename += lstrlen( pszFilename ) + 1;
  2221. }
  2222. }
  2223. else
  2224. {
  2225. DWORD dwErr = GetLastError( );
  2226. }
  2227. LocalFree( pszFilenameBuffer );
  2228. }
  2229. break;
  2230. case IDM_ALL_ON:
  2231. {
  2232. ULONG nItems = GetMenuItemCount( _hMenu );
  2233. for( ULONG n = 0; n < nItems; n++ )
  2234. {
  2235. MENUITEMINFO mii;
  2236. ZeroMemory( &mii, sizeof(mii) );
  2237. mii.cbSize = sizeof(mii);
  2238. mii.fMask = MIIM_STATE;
  2239. mii.fState = MFS_CHECKED;
  2240. SetMenuItemInfo( _hMenu, n, TRUE, &mii );
  2241. g_pfSelectedComponent[ n ] = FALSE;
  2242. }
  2243. LINEPOINTER * lp = _pLines;
  2244. while( lp )
  2245. {
  2246. lp->fFiltered = FALSE;
  2247. lp = lp->pNext;
  2248. }
  2249. _ApplyFilters( );
  2250. }
  2251. break;
  2252. case IDM_EDIT_COPY:
  2253. {
  2254. _FillClipboard( );
  2255. }
  2256. break;
  2257. case IDM_FILTER_SHOWSERVERNAME:
  2258. {
  2259. HMENU hMenu = GetSubMenu( GetMenu( _hWnd ), 2 );
  2260. MENUITEMINFO mii;
  2261. ZeroMemory( &mii, sizeof(mii) );
  2262. mii.cbSize = sizeof(mii);
  2263. mii.fMask = MIIM_STATE;
  2264. GetMenuItemInfo( hMenu, IDM_FILTER_SHOWSERVERNAME, FALSE, &mii );
  2265. g_fShowServerNames = ( ( mii.fState & MFS_CHECKED ) == MFS_CHECKED );
  2266. mii.fState = g_fShowServerNames ? 0 : MFS_CHECKED;
  2267. SetMenuItemInfo( hMenu, IDM_FILTER_SHOWSERVERNAME, FALSE, &mii );
  2268. }
  2269. break;
  2270. case IDM_FILTER_RESOURCENOISE:
  2271. {
  2272. HMENU hMenu = GetSubMenu( GetMenu( _hWnd ), 2 );
  2273. MENUITEMINFO mii;
  2274. ZeroMemory( &mii, sizeof(mii) );
  2275. mii.cbSize = sizeof(mii);
  2276. mii.fMask = MIIM_STATE;
  2277. GetMenuItemInfo( hMenu, IDM_FILTER_RESOURCENOISE, FALSE, &mii );
  2278. g_fResourceNoise = ( ( mii.fState & MFS_CHECKED ) == MFS_CHECKED );
  2279. mii.fState = g_fResourceNoise ? 0 : MFS_CHECKED;
  2280. SetMenuItemInfo( hMenu, IDM_FILTER_RESOURCENOISE, FALSE, &mii );
  2281. _ApplyFilters( );
  2282. }
  2283. break;
  2284. case IDM_EDIT_FIND:
  2285. if ( !g_hwndFind )
  2286. {
  2287. new CFindDialog( _hWnd );
  2288. }
  2289. else
  2290. {
  2291. ShowWindow( g_hwndFind, SW_SHOW );
  2292. }
  2293. break;
  2294. case IDM_ALL_OFF:
  2295. {
  2296. ULONG nItems = GetMenuItemCount( _hMenu );
  2297. for( ULONG n = 0; n < nItems; n++ )
  2298. {
  2299. MENUITEMINFO mii;
  2300. ZeroMemory( &mii, sizeof(mii) );
  2301. mii.cbSize = sizeof(mii);
  2302. mii.fMask = MIIM_STATE;
  2303. mii.fState = 0;
  2304. SetMenuItemInfo( _hMenu, n, TRUE, &mii );
  2305. g_pfSelectedComponent[ n ] = TRUE;
  2306. }
  2307. _ApplyFilters( );
  2308. }
  2309. break;
  2310. default:
  2311. if ( wmId >= IDM_FIRST_CS_FILTER && wmId <= IDM_LAST_CS_FILTER )
  2312. {
  2313. MENUITEMINFO mii;
  2314. ZeroMemory( &mii, sizeof(mii) );
  2315. mii.cbSize = sizeof(mii);
  2316. mii.fMask = MIIM_STATE;
  2317. GetMenuItemInfo( _hMenu, wmId, FALSE, &mii );
  2318. g_pfSelectedComponent[ wmId - IDM_FIRST_CS_FILTER - 1 ] = ( ( mii.fState & MFS_CHECKED ) == MFS_CHECKED );
  2319. mii.fState = g_pfSelectedComponent[ wmId - IDM_FIRST_CS_FILTER - 1 ] ? 0 : MFS_CHECKED;
  2320. SetMenuItemInfo( _hMenu, wmId, FALSE, &mii );
  2321. _ApplyFilters( );
  2322. }
  2323. break;
  2324. }
  2325. return 0;
  2326. }
  2327. //
  2328. // _OnDestroyWindow( )
  2329. //
  2330. LRESULT
  2331. CApplicationWindow::_OnDestroyWindow( )
  2332. {
  2333. g_fCApplicationWindowDestroyed = TRUE;
  2334. PostQuitMessage(0);
  2335. delete this;
  2336. return 0;
  2337. }
  2338. //
  2339. // _OnCreate( )
  2340. //
  2341. LRESULT
  2342. CApplicationWindow::_OnCreate(
  2343. HWND hwnd,
  2344. LPCREATESTRUCT pcs )
  2345. {
  2346. _hWnd = hwnd;
  2347. SetWindowLongPtr( _hWnd, GWLP_USERDATA, (LONG_PTR)this );
  2348. return 0;
  2349. }
  2350. //
  2351. // _OnKeyDown( )
  2352. //
  2353. // Returns FALSE is the default window proc should also
  2354. // take a crack at it.
  2355. //
  2356. // Returns TRUE to stop processing the message.
  2357. //
  2358. BOOL
  2359. CApplicationWindow::_OnKeyDown( WPARAM wParam, LPARAM lParam )
  2360. {
  2361. RECT rect;
  2362. SCROLLINFO si;
  2363. ULONG uOldPointer = _uPointer;
  2364. BOOL lResult = FALSE;
  2365. si.cbSize = sizeof(si);
  2366. si.fMask = SIF_POS | SIF_PAGE;
  2367. GetScrollInfo( _hWnd, SB_VERT, &si );
  2368. SetRect( &rect, 0, ( _uPointer - si.nPos ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 1 ) * _tm.tmHeight );
  2369. if ( wParam == VK_PRIOR
  2370. || wParam == VK_UP
  2371. || wParam == VK_HOME
  2372. || wParam == VK_END
  2373. || wParam == VK_NEXT
  2374. || wParam == VK_DOWN )
  2375. {
  2376. if ( _fSelection )
  2377. {
  2378. if ( GetKeyState( VK_SHIFT ) >= 0 )
  2379. {
  2380. _fSelection = FALSE;
  2381. InvalidateRect( _hWnd, NULL, FALSE );
  2382. }
  2383. }
  2384. else
  2385. {
  2386. if ( GetKeyState( VK_SHIFT ) < 0 )
  2387. {
  2388. _fSelection = TRUE;
  2389. InvalidateRect( _hWnd, NULL, FALSE );
  2390. }
  2391. }
  2392. }
  2393. switch ( wParam )
  2394. {
  2395. case VK_PRIOR:
  2396. _uPointer -= si.nPage - 1;
  2397. case VK_UP:
  2398. _uPointer--;
  2399. if ( _uPointer >= _cTotalLineCount )
  2400. {
  2401. _uPointer = _cTotalLineCount - 1;
  2402. }
  2403. if ( GetKeyState( VK_SHIFT ) < 0 )
  2404. {
  2405. if ( uOldPointer == _uStartSelection )
  2406. {
  2407. _uStartSelection = _uPointer;
  2408. }
  2409. else
  2410. {
  2411. _uEndSelection = _uPointer;
  2412. }
  2413. InvalidateRect( _hWnd, NULL, FALSE );
  2414. }
  2415. else
  2416. {
  2417. _uStartSelection = _uEndSelection = _uPointer;
  2418. if ( _uPointer < (ULONG) si.nPos )
  2419. {
  2420. if ( wParam == VK_UP )
  2421. {
  2422. SendMessage( _hWnd, WM_VSCROLL, SB_LINEUP, 0 );
  2423. GetScrollInfo( _hWnd, SB_VERT, &si );
  2424. }
  2425. }
  2426. else
  2427. {
  2428. rect.top -= _tm.tmHeight;
  2429. InvalidateRect( _hWnd, &rect, FALSE );
  2430. }
  2431. }
  2432. if ( wParam == VK_PRIOR )
  2433. {
  2434. SendMessage( _hWnd, WM_VSCROLL, SB_PAGEUP, 0 );
  2435. }
  2436. else if ( _uPointer < (ULONG) si.nPos )
  2437. {
  2438. si.fMask = SIF_POS;
  2439. si.nPos = _uPointer;
  2440. SetScrollInfo( _hWnd, SB_VERT, &si, TRUE );
  2441. InvalidateRect( _hWnd, NULL, FALSE );
  2442. }
  2443. lResult = TRUE;
  2444. break;
  2445. case VK_NEXT:
  2446. _uPointer += si.nPage - 1;
  2447. case VK_DOWN:
  2448. _uPointer++;
  2449. if ( _uPointer >= _cTotalLineCount )
  2450. {
  2451. _uPointer = _cTotalLineCount - 1;
  2452. }
  2453. if ( GetKeyState( VK_SHIFT ) < 0 )
  2454. {
  2455. if ( uOldPointer == _uEndSelection )
  2456. {
  2457. _uEndSelection = _uPointer;
  2458. }
  2459. else
  2460. {
  2461. _uStartSelection = _uPointer;
  2462. }
  2463. InvalidateRect( _hWnd, NULL, FALSE );
  2464. }
  2465. else
  2466. {
  2467. _uStartSelection = _uEndSelection = _uPointer;
  2468. if ( _uPointer > si.nPos + si.nPage )
  2469. {
  2470. if ( wParam == VK_DOWN )
  2471. {
  2472. SendMessage( _hWnd, WM_VSCROLL, SB_LINEDOWN, 0 );
  2473. GetScrollInfo( _hWnd, SB_VERT, &si );
  2474. }
  2475. }
  2476. else
  2477. {
  2478. rect.bottom += _tm.tmHeight;
  2479. InvalidateRect( _hWnd, &rect, FALSE );
  2480. }
  2481. }
  2482. if ( wParam == VK_NEXT )
  2483. {
  2484. SendMessage( _hWnd, WM_VSCROLL, SB_PAGEDOWN, 0 );
  2485. }
  2486. else if ( _uPointer > si.nPos + si.nPage )
  2487. {
  2488. si.fMask = SIF_POS;
  2489. si.nPos = _uPointer;
  2490. SetScrollInfo( _hWnd, SB_VERT, &si, TRUE );
  2491. InvalidateRect( _hWnd, NULL, FALSE );
  2492. }
  2493. lResult = TRUE;
  2494. break;
  2495. case VK_HOME:
  2496. _LineFinder.nLine = 0;
  2497. _LineFinder.psLine = NULL;
  2498. _uPointer = 0;
  2499. if ( GetKeyState( VK_SHIFT ) < 0 )
  2500. {
  2501. if ( uOldPointer == _uEndSelection )
  2502. {
  2503. _uEndSelection = _uStartSelection;
  2504. }
  2505. _uStartSelection = 0;
  2506. }
  2507. else
  2508. {
  2509. _uEndSelection = _uStartSelection = _uPointer;
  2510. }
  2511. if ( uOldPointer < si.nPage )
  2512. {
  2513. InvalidateRect( _hWnd, &rect, FALSE );
  2514. SetRect( &rect, 0, ( _uPointer - si.nPos ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 1 ) * _tm.tmHeight );
  2515. InvalidateRect( _hWnd, &rect, FALSE );
  2516. }
  2517. else
  2518. {
  2519. SendMessage( _hWnd, WM_VSCROLL, SB_TOP, 0 );
  2520. }
  2521. lResult = TRUE;
  2522. break;
  2523. case VK_END:
  2524. _LineFinder.nLine = _cTotalLineCount;
  2525. _LineFinder.psLine = NULL;
  2526. _uPointer = _cTotalLineCount - 1;
  2527. if ( GetKeyState( VK_SHIFT ) < 0 )
  2528. {
  2529. if ( uOldPointer == _uStartSelection )
  2530. {
  2531. _uStartSelection = _uEndSelection;
  2532. }
  2533. _uEndSelection = 0;
  2534. }
  2535. else
  2536. {
  2537. _uEndSelection = _uStartSelection = _uPointer;
  2538. }
  2539. if ( uOldPointer > _cTotalLineCount - si.nPage )
  2540. {
  2541. InvalidateRect( _hWnd, &rect, FALSE );
  2542. SetRect( &rect, 0, ( _uPointer - si.nPos ) * _tm.tmHeight, _xWindow, ( _uPointer - si.nPos + 1 ) * _tm.tmHeight );
  2543. InvalidateRect( _hWnd, &rect, FALSE );
  2544. }
  2545. else
  2546. {
  2547. SendMessage( _hWnd, WM_VSCROLL, SB_BOTTOM, 0 );
  2548. }
  2549. lResult = TRUE;
  2550. break;
  2551. case VK_LEFT:
  2552. SendMessage( _hWnd, WM_HSCROLL, SB_PAGEUP, 0 );
  2553. break;
  2554. case VK_RIGHT:
  2555. SendMessage( _hWnd, WM_HSCROLL, SB_PAGEDOWN, 0 );
  2556. break;
  2557. case VK_F5: // refresh
  2558. PostMessage( _hWnd, WM_COMMAND, IDM_FILE_REFRESH, 0 );
  2559. break;
  2560. case 'F':
  2561. if ( GetKeyState( VK_CONTROL ) < 0 )
  2562. {
  2563. PostMessage( _hWnd, WM_COMMAND, IDM_EDIT_FIND, 0 );
  2564. }
  2565. break;
  2566. case 'A':
  2567. if ( GetKeyState( VK_CONTROL ) < 0 )
  2568. {
  2569. PostMessage( _hWnd, WM_COMMAND, IDM_OPEN_FILE, 0 );
  2570. }
  2571. break;
  2572. case 'C':
  2573. if ( GetKeyState( VK_CONTROL ) < 0 )
  2574. {
  2575. PostMessage( _hWnd, WM_COMMAND, IDM_EDIT_COPY, 0 );
  2576. }
  2577. break;
  2578. }
  2579. return lResult;
  2580. }
  2581. //
  2582. // _OnLeftButtonDown( )
  2583. //
  2584. LRESULT
  2585. CApplicationWindow::_OnLeftButtonDown(
  2586. WPARAM wParam,
  2587. LPARAM lParam
  2588. )
  2589. {
  2590. SCROLLINFO si;
  2591. DWORD fwKeys = (DWORD) wParam;
  2592. DWORD x = GET_X_LPARAM( lParam );
  2593. DWORD y = GET_Y_LPARAM( lParam );
  2594. si.cbSize = sizeof(si);
  2595. si.fMask = SIF_POS;
  2596. GetScrollInfo( _hWnd, SB_VERT, &si );
  2597. _uPointer = si.nPos + y / _tm.tmHeight;
  2598. InvalidateRect( _hWnd, NULL, FALSE );
  2599. if ( fwKeys & MK_SHIFT )
  2600. {
  2601. if ( _uPointer < _uStartSelection )
  2602. {
  2603. _uStartSelection = _uPointer;
  2604. }
  2605. else if ( _uPointer > _uEndSelection )
  2606. {
  2607. _uEndSelection = _uPointer;
  2608. }
  2609. }
  2610. else
  2611. {
  2612. _uStartSelection = _uEndSelection = _uPointer;
  2613. }
  2614. return FALSE;
  2615. }
  2616. //
  2617. // WndProc( )
  2618. //
  2619. LRESULT CALLBACK
  2620. CApplicationWindow::WndProc(
  2621. HWND hWnd,
  2622. UINT uMsg,
  2623. WPARAM wParam,
  2624. LPARAM lParam )
  2625. {
  2626. CApplicationWindow * paw = (CApplicationWindow *) GetWindowLongPtr( hWnd, GWLP_USERDATA );
  2627. if ( paw != NULL )
  2628. {
  2629. switch( uMsg )
  2630. {
  2631. case WM_COMMAND:
  2632. return paw->_OnCommand( wParam, lParam );
  2633. case WM_PAINT:
  2634. return paw->_OnPaint( wParam, lParam );
  2635. case WM_DESTROY:
  2636. SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)NULL );
  2637. return paw->_OnDestroyWindow( );
  2638. case WM_SIZE:
  2639. return paw->_OnSize( lParam );
  2640. case WM_KEYDOWN:
  2641. case WM_SYSKEYDOWN:
  2642. if ( paw->_OnKeyDown( wParam, lParam ) )
  2643. return 0;
  2644. break; // do default as well
  2645. case WM_VSCROLL:
  2646. return paw->_OnVerticalScroll( wParam, lParam );
  2647. case WM_HSCROLL:
  2648. return paw->_OnHorizontalScroll( wParam, lParam );
  2649. case WM_MOUSEWHEEL:
  2650. return paw->_OnMouseWheel( HIWORD(wParam) );
  2651. case WM_FIND_NEXT:
  2652. return paw->_FindNext( wParam, lParam );
  2653. case WM_MARK_ALL:
  2654. return paw->_MarkAll( wParam, lParam );
  2655. case WM_ERASEBKGND:
  2656. goto EraseBackground;
  2657. case WM_LBUTTONDOWN:
  2658. return paw->_OnLeftButtonDown( wParam, lParam );
  2659. }
  2660. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  2661. }
  2662. if ( uMsg == WM_CREATE )
  2663. {
  2664. LPCREATESTRUCT pcs = (LPCREATESTRUCT) lParam;
  2665. paw = (CApplicationWindow *) pcs->lpCreateParams;
  2666. return paw->_OnCreate( hWnd, pcs );
  2667. }
  2668. if ( uMsg == WM_ERASEBKGND )
  2669. {
  2670. EraseBackground:
  2671. RECT rectWnd;
  2672. HBRUSH hBrush;
  2673. HDC hdc = (HDC) wParam;
  2674. GetClientRect( hWnd, &rectWnd );
  2675. #if defined(DEBUG_PAINT)
  2676. hBrush = CreateSolidBrush( 0xFF00FF );
  2677. #else
  2678. hBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
  2679. #endif
  2680. FillRect( hdc, &rectWnd, hBrush );
  2681. DeleteObject( hBrush );
  2682. return TRUE;
  2683. }
  2684. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  2685. }
  2686. // Mesage handler for about box.
  2687. LRESULT CALLBACK
  2688. CApplicationWindow::About(
  2689. HWND hDlg,
  2690. UINT message,
  2691. WPARAM wParam,
  2692. LPARAM lParam)
  2693. {
  2694. switch (message)
  2695. {
  2696. case WM_INITDIALOG:
  2697. return TRUE;
  2698. case WM_COMMAND:
  2699. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  2700. {
  2701. EndDialog(hDlg, LOWORD(wParam));
  2702. return TRUE;
  2703. }
  2704. break;
  2705. }
  2706. return FALSE;
  2707. }