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.

767 lines
18 KiB

  1. /*++
  2. Copyright (c) 1993-1995 Microsoft Corporation
  3. Module Name:
  4. LogView.C
  5. Abstract:
  6. Author:
  7. Arthur Hanson (arth) 27-Jul-1993
  8. Revision History:
  9. --*/
  10. #include "LogView.h"
  11. #include <string.h>
  12. #include <stdio.h>
  13. //#include <dos.h>
  14. //#include <direct.h>
  15. #include <shellapi.h>
  16. // global variables used in this module or among more than one module
  17. HANDLE hInst;
  18. HANDLE hAccel;
  19. HWND hwndFrame = NULL;
  20. HWND hwndMDIClient = NULL;
  21. HWND hwndActive = NULL;
  22. HWND hwndActiveEdit = NULL;
  23. HWND hDlgFind = NULL;
  24. LPSTR lpMenu = IDLOGVIEW;
  25. TCHAR szAppName[] = "LogView";
  26. FINDREPLACE FR;
  27. PRINTDLG PD;
  28. UINT wFRMsg;
  29. UINT wHlpMsg;
  30. BOOL fReverse = FALSE; // Flag for direction of search
  31. TCHAR szSearch[CCHKEYMAX]; // Search String
  32. HANDLE hStdCursor; // handle to arrow or beam cursor
  33. HANDLE hWaitCursor; // handle to hour glass cursor
  34. void FAR Search (TCHAR * szKey);
  35. // Forward declarations of helper functions in this module
  36. VOID NEAR PASCAL InitializeMenu (HANDLE);
  37. VOID NEAR PASCAL CommandHandler (HWND, UINT, LONG);
  38. LPSTR GetCmdLine( VOID );
  39. BOOL CenterWindow( HWND hwndChild, HWND hwndParent );
  40. #define HELP_FILE TEXT("logview.hlp")
  41. /////////////////////////////////////////////////////////////////////////
  42. int PASCAL
  43. WinMain(
  44. HINSTANCE hInstance,
  45. HINSTANCE hPrevInstance,
  46. LPSTR lpCmdLine,
  47. int nCmdShow
  48. )
  49. /*++
  50. Routine Description:
  51. Creates the "frame" window, does some initialization and enters the
  52. message loop.
  53. Arguments:
  54. Return Value:
  55. --*/
  56. {
  57. MSG msg;
  58. hInst = hInstance;
  59. // If this is the first instance of the app. register window classes
  60. if (!hPrevInstance){
  61. if (!InitializeApplication ())
  62. return 0;
  63. }
  64. lpCmdLine = GetCmdLine();
  65. // Create the frame and do other initialization
  66. if (!InitializeInstance (lpCmdLine, nCmdShow))
  67. return 0;
  68. while (GetMessage (&msg, NULL, 0, 0)){
  69. // If a keyboard message is for the MDI , let the MDI client take care of it.
  70. // Otherwise, check to see if it's a normal accelerator key (like F3 = find next).
  71. // Otherwise, just handle the message as usual.
  72. if (!hDlgFind || !IsDialogMessage(hDlgFind, &msg)) {
  73. if ( !TranslateMDISysAccel (hwndMDIClient, &msg) &&
  74. !TranslateAccelerator (hwndFrame, hAccel, &msg)) {
  75. TranslateMessage (&msg);
  76. DispatchMessage (&msg);
  77. }
  78. }
  79. }
  80. return 0;
  81. } // WinMain
  82. /////////////////////////////////////////////////////////////////////////
  83. LRESULT APIENTRY
  84. MPFrameWndProc (
  85. HWND hwnd,
  86. UINT msg,
  87. UINT wParam,
  88. LONG lParam
  89. )
  90. /*++
  91. Routine Description:
  92. The window function for the "frame" window, which controls the menu
  93. and encompasses all the MDI child windows.
  94. Arguments:
  95. Return Value:
  96. --*/
  97. {
  98. LPFINDREPLACE lpfr;
  99. DWORD dwFlags;
  100. switch (msg) {
  101. case WM_CREATE: {
  102. CLIENTCREATESTRUCT ccs;
  103. HDC hdc;
  104. // Find window menu where children will be listed
  105. ccs.hWindowMenu = GetSubMenu (GetMenu(hwnd), WINDOWMENU);
  106. ccs.idFirstChild = IDM_WINDOWCHILD;
  107. // Create the MDI client filling the client area
  108. hwndMDIClient = CreateWindow ("mdiclient", NULL,
  109. WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
  110. 0, 0, 0, 0, hwnd, (HMENU) 0xCAC, hInst, (LPSTR) &ccs);
  111. ShowWindow (hwndMDIClient,SW_SHOW);
  112. // Check if printer can be initialized
  113. if (hdc = GetPrinterDC (TRUE)) {
  114. DeleteDC (hdc);
  115. }
  116. break;
  117. }
  118. case WM_INITMENU:
  119. // Set up the menu state
  120. InitializeMenu ((HMENU)wParam);
  121. break;
  122. case WM_WININICHANGE:
  123. case WM_DEVMODECHANGE:{
  124. // If control panel changes default printer characteristics, reinitialize our
  125. // printer information...
  126. HDC hdc;
  127. if (hdc = GetPrinterDC (TRUE))
  128. DeleteDC (hdc);
  129. break;
  130. }
  131. case WM_COMMAND:
  132. // Direct all menu selection or accelerator commands to another function
  133. CommandHandler(hwnd, wParam, lParam);
  134. break;
  135. case WM_CLOSE:
  136. DestroyWindow (hwnd);
  137. break;
  138. case WM_DESTROY:
  139. PostQuitMessage (0);
  140. break;
  141. default:
  142. if (msg == wFRMsg)
  143. {
  144. lpfr = (LPFINDREPLACE)lParam;
  145. dwFlags = lpfr->Flags;
  146. fReverse = (dwFlags & FR_DOWN ? FALSE : TRUE);
  147. fCase = (dwFlags & FR_MATCHCASE ? TRUE : FALSE);
  148. if (dwFlags & FR_FINDNEXT)
  149. Search (szSearch);
  150. else if (dwFlags & FR_DIALOGTERM)
  151. hDlgFind = NULL; /* invalidate modeless window handle */
  152. break;
  153. }
  154. // use DefFrameProc() instead of DefWindowProc() since there are things
  155. // that have to be handled differently because of MDI
  156. return DefFrameProc (hwnd,hwndMDIClient,msg,wParam,lParam);
  157. }
  158. return 0;
  159. } // MPFrameWndProc
  160. /////////////////////////////////////////////////////////////////////////
  161. LRESULT APIENTRY
  162. MPMDIChildWndProc (
  163. HWND hwnd,
  164. UINT msg,
  165. UINT wParam,
  166. LONG lParam
  167. )
  168. /*++
  169. Routine Description:
  170. Arguments:
  171. Return Value:
  172. --*/
  173. {
  174. HWND hwndEdit;
  175. HFONT hFont;
  176. LRESULT ret;
  177. switch (msg) {
  178. case WM_CREATE:
  179. hwndEdit = CreateWindow ("edit", NULL,
  180. WS_CHILD | WS_HSCROLL | WS_MAXIMIZE | WS_VISIBLE |
  181. WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
  182. ES_MULTILINE | ES_READONLY | ES_NOHIDESEL,
  183. 0, 0, 0, 0,
  184. hwnd, (HMENU) ID_EDIT, hInst, NULL);
  185. // Remember the window handle and initialize some window attributes
  186. SetWindowLongPtr (hwnd, GWL_HWNDEDIT, (LONG_PTR) hwndEdit);
  187. SetWindowWord (hwnd, GWW_CHANGED, FALSE);
  188. SetWindowWord (hwnd, GWL_WORDWRAP, FALSE);
  189. SetWindowWord (hwnd, GWW_UNTITLED, TRUE);
  190. hFont = GetStockObject(SYSTEM_FIXED_FONT);
  191. ret = SendMessage(hwndEdit, WM_SETFONT, (WPARAM) hFont, (LPARAM) MAKELONG((WORD) TRUE, 0));
  192. SetFocus (hwndEdit);
  193. break;
  194. case WM_MDIACTIVATE:
  195. // If we're activating this child, remember it
  196. if (GET_WM_MDIACTIVATE_FACTIVATE(hwnd, wParam, lParam)) {
  197. hwndActive = hwnd;
  198. hwndActiveEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT);
  199. }
  200. else {
  201. hwndActive = NULL;
  202. hwndActiveEdit = NULL;
  203. }
  204. break;
  205. case WM_CLOSE:
  206. goto CallDCP;
  207. case WM_SIZE:{
  208. RECT rc;
  209. // On creation or resize, size the edit control.
  210. hwndEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT);
  211. GetClientRect (hwnd, &rc);
  212. MoveWindow (hwndEdit,
  213. rc.left,
  214. rc.top,
  215. rc.right-rc.left,
  216. rc.bottom-rc.top,
  217. TRUE);
  218. goto CallDCP;
  219. }
  220. case WM_SETFOCUS:
  221. SetFocus ((HWND)GetWindowLong (hwnd, GWL_HWNDEDIT));
  222. break;
  223. case WM_COMMAND:
  224. switch (LOWORD(wParam)){
  225. case ID_EDIT:
  226. switch (GET_WM_COMMAND_CMD(wParam, lParam)) {
  227. case EN_ERRSPACE:
  228. // If the control is out of space, beep
  229. MessageBeep (0);
  230. break;
  231. default:
  232. goto CallDCP;
  233. }
  234. break;
  235. default:
  236. goto CallDCP;
  237. }
  238. break;
  239. default:
  240. CallDCP:
  241. return DefMDIChildProc (hwnd, msg, wParam, lParam);
  242. }
  243. return FALSE;
  244. } // MPMDIChildWndProc
  245. /////////////////////////////////////////////////////////////////////////
  246. VOID NEAR PASCAL
  247. InitializeMenu (
  248. register HANDLE hmenu
  249. )
  250. /*++
  251. Routine Description:
  252. Sets up greying, enabling and checking of main menu items.
  253. Arguments:
  254. Return Value:
  255. --*/
  256. {
  257. WORD status;
  258. WORD i;
  259. INT j;
  260. // Is there any active child to talk to?
  261. if (hwndActiveEdit) {
  262. // Set the word wrap state for the window
  263. if ((WORD) SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EDITWRAP, 0, 0)))
  264. status = MF_CHECKED;
  265. else
  266. status = MF_UNCHECKED;
  267. CheckMenuItem (hmenu, IDM_EDITWRAP, status);
  268. // Enable search menu items only if there is a search string
  269. if (*szSearch)
  270. status = MF_ENABLED;
  271. else
  272. status = MF_GRAYED;
  273. EnableMenuItem (hmenu, IDM_SEARCHNEXT, status);
  274. EnableMenuItem (hmenu, IDM_SEARCHPREV, status);
  275. // Enable File/Print only if a printer is available
  276. status = (WORD) (iPrinter ? MF_ENABLED : MF_GRAYED);
  277. EnableMenuItem (hmenu, IDM_FILEPRINT, status);
  278. // select all and wrap toggle always enabled
  279. status = MF_ENABLED;
  280. EnableMenuItem(hmenu, IDM_EDITSELECT, status);
  281. EnableMenuItem(hmenu, IDM_EDITWRAP, status);
  282. EnableMenuItem(hmenu, IDM_SEARCHFIND, status);
  283. } else {
  284. // There are no active child windows
  285. status = MF_GRAYED;
  286. // No active window, so disable everything
  287. for (i = IDM_EDITFIRST; i <= IDM_EDITLAST; i++)
  288. EnableMenuItem (hmenu, i, status);
  289. CheckMenuItem (hmenu, IDM_EDITWRAP, MF_UNCHECKED);
  290. for (i = IDM_SEARCHFIRST; i <= IDM_SEARCHLAST; i++)
  291. EnableMenuItem (hmenu, i, status);
  292. EnableMenuItem (hmenu, IDM_FILEPRINT, status);
  293. }
  294. // The following menu items are enabled if there is an active window
  295. EnableMenuItem (hmenu, IDM_WINDOWTILE, status);
  296. EnableMenuItem (hmenu, IDM_WINDOWCASCADE, status);
  297. EnableMenuItem (hmenu, IDM_WINDOWICONS, status);
  298. EnableMenuItem (hmenu, IDM_WINDOWCLOSEALL, status);
  299. // Allow printer setup only if printer driver supports device initialization
  300. if (iPrinter < 2)
  301. status = MF_GRAYED;
  302. EnableMenuItem ( hmenu, IDM_FILESETUP, status);
  303. UNREFERENCED_PARAMETER(j);
  304. } // InitializeMenu
  305. /////////////////////////////////////////////////////////////////////////
  306. VOID NEAR PASCAL
  307. CloseAllChildren ()
  308. /*++
  309. Routine Description:
  310. Destroys all MDI child windows.
  311. Arguments:
  312. Return Value:
  313. --*/
  314. {
  315. register HWND hwndT;
  316. // hide the MDI client window to avoid multiple repaints
  317. ShowWindow(hwndMDIClient,SW_HIDE);
  318. // As long as the MDI client has a child, destroy it
  319. while ( hwndT = GetWindow (hwndMDIClient, GW_CHILD)){
  320. // Skip the icon title windows
  321. while (hwndT && GetWindow (hwndT, GW_OWNER))
  322. hwndT = GetWindow (hwndT, GW_HWNDNEXT);
  323. if (!hwndT)
  324. break;
  325. SendMessage (hwndMDIClient, WM_MDIDESTROY, (UINT_PTR)hwndT, 0L);
  326. }
  327. } // CloseAllChildren
  328. /////////////////////////////////////////////////////////////////////////
  329. VOID NEAR PASCAL
  330. CommandHandler (
  331. HWND hwnd,
  332. UINT wParam,
  333. LONG lParam
  334. )
  335. /*++
  336. Routine Description:
  337. Arguments:
  338. Return Value:
  339. --*/
  340. {
  341. DLGPROC lpfnDlg;
  342. switch (LOWORD(wParam)){
  343. case IDM_FILENEW:
  344. // Add a new, empty MDI child
  345. AddFile (NULL);
  346. break;
  347. case IDM_FILEOPEN:
  348. MyReadFile (hwnd);
  349. break;
  350. case IDM_FILEPRINT:
  351. // Print the active child MDI
  352. PrintFile (hwndActive);
  353. break;
  354. case IDM_FILESETUP:
  355. // Set up the printer environment for this app
  356. GetInitializationData (hwnd);
  357. break;
  358. case IDM_FILEMENU: {
  359. // lengthen / shorten the size of the MDI menu
  360. HMENU hMenu;
  361. HMENU hWindowMenu;
  362. INT i;
  363. if (lpMenu == IDLOGVIEW) {
  364. lpMenu = IDLOGVIEW2;
  365. i = SHORTMENU;
  366. }
  367. else {
  368. lpMenu = IDLOGVIEW;
  369. i = WINDOWMENU;
  370. }
  371. hMenu = LoadMenu (hInst, lpMenu);
  372. hWindowMenu = GetSubMenu (hMenu, i);
  373. // Set the new menu
  374. hMenu = (HMENU)SendMessage (hwndMDIClient,
  375. WM_MDISETMENU,
  376. (UINT_PTR)hMenu,
  377. (LONG_PTR)hWindowMenu);
  378. DestroyMenu (hMenu);
  379. DrawMenuBar (hwndFrame);
  380. break;
  381. }
  382. case IDM_FILEEXIT:
  383. // Close LogView
  384. SendMessage (hwnd, WM_CLOSE, 0, 0L);
  385. break;
  386. case IDM_HELPABOUT:
  387. // Just let the shell display the about box...
  388. ShellAbout(hwnd, szAppName, szAppName, LoadIcon(hInst, IDLOGVIEW));
  389. break;
  390. // The following are edit commands. Pass these off to the active child'd edit
  391. // control window.
  392. case IDM_EDITWRAP:
  393. SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EDITWRAP, 1, 0));
  394. break;
  395. case IDM_SEARCHPREV:
  396. if (szSearch[0]) {
  397. fReverse = TRUE;
  398. Search(szSearch);
  399. break;
  400. }
  401. // else fall through and bring up find dialog
  402. case IDM_SEARCHNEXT:
  403. if (szSearch[0]) {
  404. fReverse = FALSE;
  405. Search(szSearch);
  406. break;
  407. }
  408. // else fall through and bring up find dialog
  409. case IDM_SEARCHFIND:
  410. if (hDlgFind)
  411. SetFocus(hDlgFind);
  412. else {
  413. FR.lpstrFindWhat = szSearch;
  414. FR.wFindWhatLen = CCHKEYMAX;
  415. hDlgFind = FindText((LPFINDREPLACE)&FR);
  416. }
  417. break;
  418. // The following are window commands - these are handled by the MDI Client.
  419. case IDM_WINDOWTILE:
  420. // Tile MDI windows
  421. SendMessage (hwndMDIClient, WM_MDITILE, 0, 0L);
  422. break;
  423. case IDM_WINDOWCASCADE:
  424. // Cascade MDI windows
  425. SendMessage (hwndMDIClient, WM_MDICASCADE, 0, 0L);
  426. break;
  427. case IDM_WINDOWICONS:
  428. // Auto - arrange MDI icons
  429. SendMessage (hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
  430. break;
  431. case IDM_WINDOWCLOSEALL:
  432. CloseAllChildren();
  433. // Show the window since CloseAllChilren() hides the window for fewer repaints
  434. ShowWindow( hwndMDIClient, SW_SHOW);
  435. break;
  436. case ID_HELP_CONT:
  437. WinHelp(hwnd, HELP_FILE, HELP_CONTENTS, 0L);
  438. break;
  439. case ID_HELP_INDEX:
  440. WinHelp(hwnd, HELP_FILE, HELP_PARTIALKEY, 0L);
  441. break;
  442. case ID_HELP_USING:
  443. WinHelp(hwnd, HELP_FILE, HELP_HELPONHELP, 0L);
  444. break;
  445. default:
  446. // This is essential, since there are frame WM_COMMANDS generated by the MDI
  447. // system for activating child windows via the window menu.
  448. DefFrameProc(hwnd, hwndMDIClient, WM_COMMAND, wParam, lParam);
  449. }
  450. } // CommandHandler
  451. /////////////////////////////////////////////////////////////////////////
  452. SHORT
  453. MPError(
  454. HWND hwnd,
  455. WORD bFlags,
  456. WORD id,
  457. char *psz
  458. )
  459. /*++
  460. Routine Description:
  461. Arguments:
  462. Return Value:
  463. --*/
  464. {
  465. CHAR sz[160];
  466. CHAR szFmt[128];
  467. LoadString (hInst, id, szFmt, sizeof (szFmt));
  468. sprintf (sz, szFmt, psz );
  469. LoadString (hInst, (WORD)IDS_APPNAME, (LPSTR)szFmt, sizeof (szFmt));
  470. return( (SHORT)MessageBox (hwndFrame, sz, szFmt, bFlags));
  471. UNREFERENCED_PARAMETER(hwnd);
  472. } // MPError
  473. /////////////////////////////////////////////////////////////////////////
  474. LPSTR
  475. GetCmdLine(
  476. VOID
  477. )
  478. /*++
  479. Routine Description:
  480. Arguments:
  481. Return Value:
  482. --*/
  483. {
  484. LPSTR lpCmdLine, lpT;
  485. lpCmdLine = GetCommandLine();
  486. // on Win32, lpCmdLine's first string includes its own name, remove this
  487. if (*lpCmdLine) {
  488. lpT = strchr(lpCmdLine, ' '); // skip self name
  489. if (lpT) {
  490. lpCmdLine = lpT;
  491. while (*lpCmdLine == ' ') {
  492. lpCmdLine++; // skip spaces to end or first cmd
  493. }
  494. } else {
  495. lpCmdLine += strlen(lpCmdLine); // point to NULL
  496. }
  497. }
  498. return(lpCmdLine);
  499. } // GetCmdLine
  500. #define CY_SHADOW 4
  501. #define CX_SHADOW 4
  502. /////////////////////////////////////////////////////////////////////////
  503. BOOL
  504. CenterWindow(
  505. HWND hwndChild,
  506. HWND hwndParent
  507. )
  508. /*++
  509. Routine Description:
  510. Arguments:
  511. Return Value:
  512. --*/
  513. {
  514. RECT rChild, rParent;
  515. int wChild, hChild, wParent, hParent;
  516. int wScreen, hScreen, xNew, yNew;
  517. HDC hdc;
  518. // Get the Height and Width of the child window
  519. GetWindowRect (hwndChild, &rChild);
  520. wChild = rChild.right - rChild.left;
  521. hChild = rChild.bottom - rChild.top;
  522. // Get the Height and Width of the parent window
  523. GetWindowRect (hwndParent, &rParent);
  524. wParent = rParent.right - rParent.left;
  525. hParent = rParent.bottom - rParent.top;
  526. // Get the display limits
  527. hdc = GetDC (hwndChild);
  528. wScreen = GetDeviceCaps (hdc, HORZRES);
  529. hScreen = GetDeviceCaps (hdc, VERTRES);
  530. ReleaseDC (hwndChild, hdc);
  531. // Calculate new X position, then adjust for screen
  532. xNew = rParent.left + ((wParent - wChild) /2);
  533. if (xNew < 0)
  534. xNew = 0;
  535. else if ((xNew+wChild) > wScreen)
  536. xNew = wScreen - wChild;
  537. // Calculate new Y position, then adjust for screen
  538. yNew = rParent.top + ((hParent - hChild) /2);
  539. if (yNew < 0)
  540. yNew = 0;
  541. else if ((yNew+hChild) > hScreen)
  542. yNew = hScreen - hChild;
  543. // Set it, and return
  544. return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  545. } // CenterWindow