home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / INPUT.PAK / INPUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  19.9 KB  |  809 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE: input.c
  9. //
  10. //  PURPOSE: Show windows input: mouse, keyboard, control(scroll), and timer
  11. //
  12. //  FUNCTIONS:
  13. //    WndProc - Processes messages for the main window.
  14. //    MsgCommand - Handle the WM_COMMAND messages for the main window.
  15. //    MsgCreate - Set the timer for five-second intervals.
  16. //    MsgDestroy - Kills the timer and posts the quit message.
  17. //    MsgMouseMove - Display mouse move message and its parameters.
  18. //    MsgLButtonDown -
  19. //      Display left mouse button down message and its parameters.
  20. //    MsgLButtonUp - Display left mouse button up message and its parameters.
  21. //    MsgLButtonDoubleClick -
  22. //      Display left mouse button double click message and its parameters.
  23. //    MsgRButtonDown -
  24. //      Display right mouse button down message and its parameters.
  25. //    MsgRButtonUp - Display right mouse button up message and its parameters.
  26. //    MsgRButtonDoubleClick -
  27. //      Display right mouse button double click message and its parameters.
  28. //    MsgKeyDown - Display key down message and its parameters.
  29. //    MsgKeyUp - Display key up message and its parameters.
  30. //    MsgChar - Display character recieved message and its parameters.
  31. //    MsgTimer - Display timer message and a current time.
  32. //    MsgScroll - Display scrollbar events and position.
  33. //    MsgPaint - Draw the strings for current messages.
  34. //    InitInput - Set up the rectangles for dispay of each type of message.
  35. //
  36. //   COMMENTS:
  37. //    Message dispatch table -
  38. //      For every message to be handled by the main window procedure
  39. //      place the message number and handler function pointer in
  40. //      rgmsd (the message dispatch table).  Place the prototype
  41. //      for the function in globals.h and the definition of the
  42. //      function in the appropriate module.
  43. //    Globals.h Contains the definitions of the structures and dispatch.c
  44. //      contains the functions that use these structures.
  45. //
  46.  
  47. #include <windows.h>            // required for all Windows applications
  48. #include <windowsx.h>
  49. #ifdef WIN16
  50. #include <string.h>
  51. #include "win16ext.h"           // required only for win16 applications
  52. #endif
  53. #include "globals.h"            // prototypes specific to this application
  54. #include "resource.h"
  55.  
  56. // Global variables
  57. static char MouseText[48];         //  mouse state
  58. static char ButtonText[48];        //  mouse-button state
  59. static char KeyboardText[48];      //  keyboard state
  60. static char CharacterText[48];     //  latest character
  61. static char ScrollText[48];        //  scroll status
  62. static char TimerText[48];         //  timer state
  63. static RECT rectMouse;
  64. static RECT rectButton;
  65. static RECT rectKeyboard;
  66. static RECT rectCharacter;
  67. static RECT rectScroll;
  68. static RECT rectTimer;
  69. static UINT idTimer;                //  timer ID
  70. static int  nTimerCount = 0;        //  current timer count
  71.  
  72. #define TIMERID ((UINT) 't')
  73.  
  74.  
  75. // Main window message table definition.
  76. MSD rgmsd[] =
  77. {
  78.     {WM_COMMAND,        MsgCommand},
  79.     {WM_CREATE,         MsgCreate},
  80.     {WM_DESTROY,        MsgDestroy},
  81.     {WM_MOUSEMOVE,      MsgMouseMove},
  82.     {WM_LBUTTONDOWN,    MsgLButtonDown},
  83.     {WM_LBUTTONUP,      MsgLButtonUp},
  84.     {WM_LBUTTONDBLCLK,  MsgLButtonDoubleClick},
  85.     {WM_RBUTTONDOWN,    MsgRButtonDown},
  86.     {WM_RBUTTONUP,      MsgRButtonUp},
  87.     {WM_RBUTTONDBLCLK,  MsgRButtonDoubleClick},
  88.     {WM_KEYDOWN,        MsgKeyDown},
  89.     {WM_KEYUP,          MsgKeyUp},
  90.     {WM_CHAR,           MsgChar},
  91.     {WM_TIMER,          MsgTimer},
  92.     {WM_HSCROLL,        MsgScroll},
  93.     {WM_VSCROLL,        MsgScroll},
  94.     {WM_PAINT,          MsgPaint}
  95. };
  96.  
  97. MSDI msdiMain =
  98. {
  99.     sizeof(rgmsd) / sizeof(MSD),
  100.     rgmsd,
  101.     edwpWindow
  102. };
  103.  
  104.  
  105. //
  106. //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  107. //
  108. //  PURPOSE:  Processes messages for the main window.
  109. //
  110. //  PARAMETERS:
  111. //    hwnd     - window handle
  112. //    uMessage - message number
  113. //    wparam   - additional information (dependant on message number)
  114. //    lparam   - additional information (dependant on message number)
  115. //
  116. //  RETURN VALUE:
  117. //    The return value depends on the message number.  If the message
  118. //    is implemented in the message dispatch table, the return value is
  119. //    the value returned by the message handling function.  Otherwise,
  120. //    the return value is the value returned by the default window procedure.
  121. //
  122. //  COMMENTS:
  123. //    Call the DispMessage() function with the main window's message dispatch
  124. //    information (msdiMain) and the message specific information.
  125. //
  126.  
  127. LRESULT CALLBACK WndProc
  128.     (HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  129. {
  130.     return DispMessage(&msdiMain, hwnd, uMessage, wparam, lparam);
  131. }
  132.  
  133.  
  134. //
  135. //  FUNCTION: MsgCommand(HWND, UINT, WPARAM, LPARAM)
  136. //
  137. //  PURPOSE: Handle the WM_COMMAND messages
  138. //
  139. //  PARAMETERS:
  140. //    hwnd - The window handle
  141. //    uMessage - WM_COMMAND (unused)
  142. //    GET_WM_COMMAND_ID(wparam,lparam) - The command number
  143. //
  144. //  RETURN VALUE:
  145. //    Depends on the command.
  146. //
  147. //  COMMENTS:
  148. //
  149. //
  150.  
  151. LRESULT MsgCommand(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  152. {
  153.     LRESULT lRet = 0;
  154.  
  155.     // Message packing of wparam and lparam have changed for Win32,
  156.     // so use the GET_WM_COMMAND macro to unpack the commnad
  157.  
  158.     switch (GET_WM_COMMAND_ID(wparam,lparam))
  159.     {
  160.         //
  161.         // **TODO** Add cases here for application specific command messages.
  162.         //
  163.  
  164.         case IDM_EXIT:
  165.             DestroyWindow (hwnd);
  166.             break;
  167.  
  168.         default:
  169.             lRet = DefWindowProc(hwnd, uMessage, wparam, lparam);
  170.     }
  171.  
  172.     return lRet;
  173. }
  174.  
  175.  
  176. //
  177. //  FUNCTION: MsgCreate(HWND, UINT, WPARAM, LPARAM)
  178. //
  179. //  PURPOSE: Set the timer for five-second intervals
  180. //
  181. //  PARAMETERS:
  182. //    hwnd      - Window handle
  183. //    uMessage  - WM_CREATE      (Unused)
  184. //    wparam    - Extra data     (Unused)
  185. //    lparam    - Extra data     (Unused)
  186. //
  187. //  RETURN VALUE:
  188. //    Always returns 0 - Message handled
  189. //
  190. //  COMMENTS:
  191. //
  192. //
  193.  
  194. #pragma argsused
  195. LRESULT MsgCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  196. {
  197.     // Set the timer for five-second intervals
  198.     idTimer =  SetTimer(hwnd, TIMERID, 5000, NULL);
  199.  
  200.      return 0;
  201. }
  202.  
  203.  
  204. //
  205. //  FUNCTION: MsgDestroy(HWND, UINT, WPARAM, LPARAM)
  206. //
  207. //  PURPOSE: Kills the timer and posts the quit message.
  208. //
  209. //  PARAMETERS:
  210. //    hwnd      - Window handle
  211. //    uMessage  - WM_DESTROY (Unused)
  212. //    wparam    - Extra data (Unused)
  213. //    lparam    - Extra data (Unused)
  214. //
  215. //  RETURN VALUE:
  216. //    Always returns 0 - Message handled
  217. //
  218. //  COMMENTS:
  219. //
  220. //
  221.  
  222. #pragma argsused
  223. LRESULT MsgDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  224. {
  225.     KillTimer(hwnd, idTimer);       // Stops the timer
  226.     PostQuitMessage(0);
  227.  
  228.      return 0;
  229. }
  230.  
  231.  
  232. //
  233. //  FUNCTION: MsgMouseMove(HWND, UINT, WPARAM, LPARAM)
  234. //
  235. //  PURPOSE: Display mouse move message and its parameters.
  236. //
  237. //  PARAMETERS:
  238. //    hwnd      - Window handle
  239. //    uMessage  - WM_MOUSEMOVE (Unused)
  240. //    wparam    - Key flags
  241. //    lparam    -
  242. //      LOWORD - x position of cursor
  243. //      HIWORD - y position of cursor
  244. //
  245. //  RETURN VALUE:
  246. //    Always returns 0 - Message handled
  247. //
  248. //  COMMENTS:
  249. //
  250. //
  251.  
  252. #pragma argsused
  253. LRESULT MsgMouseMove(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  254. {
  255.     wsprintf(
  256.         MouseText,
  257.         "WM_MOUSEMOVE: %x, %d, %d",
  258.         wparam, LOWORD(lparam), HIWORD(lparam)
  259.     );
  260.     InvalidateRect(hwnd, &rectMouse, TRUE);
  261.  
  262.     return 0;
  263. }
  264.  
  265.  
  266. //
  267. //  FUNCTION: MsgLButtonDown(HWND, UINT, WPARAM, LPARAM)
  268. //
  269. //  PURPOSE: Display left mouse button down message and its parameters.
  270. //
  271. //  PARAMETERS:
  272. //    hwnd      - Window handle
  273. //    uMessage  - WM_LBUTTONDOWN (Unused)
  274. //    wparam    - Key flags
  275. //    lparam    -
  276. //      LOWORD - x position of cursor
  277. //      HIWORD - y position of cursor
  278. //
  279. //  RETURN VALUE:
  280. //    Always returns 0 - Message handled
  281. //
  282. //  COMMENTS:
  283. //
  284. //
  285.  
  286. #pragma argsused
  287. LRESULT MsgLButtonDown(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  288. {
  289.      wsprintf(
  290.           ButtonText,
  291.           "WM_LBUTTONDOWN: %x, %d, %d",
  292.           wparam, LOWORD(lparam), HIWORD(lparam)
  293.      );
  294.      InvalidateRect(hwnd, &rectButton, TRUE);
  295.  
  296.     return 0;
  297. }
  298.  
  299.  
  300. //
  301. //  FUNCTION: MsgLButtonUp(HWND, UINT, WPARAM, LPARAM)
  302. //
  303. //  PURPOSE: Display left mouse button up message and its parameters.
  304. //
  305. //  PARAMETERS:
  306. //    hwnd      - Window handle
  307. //    uMessage  - WM_LBUTTONUP (Unused)
  308. //    wparam    - Key flags
  309. //    lparam    -
  310. //      LOWORD - x position of cursor
  311. //      HIWORD - y position of cursor
  312. //
  313. //  RETURN VALUE:
  314. //
  315. //    Always returns 0 - Message handled
  316. //
  317. //  COMMENTS:
  318. //
  319. //
  320.  
  321. #pragma argsused
  322. LRESULT MsgLButtonUp(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  323. {
  324.      wsprintf(
  325.           ButtonText,
  326.           "WM_LBUTTONUP: %x, %d, %d",
  327.           wparam, LOWORD(lparam), HIWORD(lparam)
  328.      );
  329.     InvalidateRect(hwnd, &rectButton, TRUE);
  330.  
  331.     return 0;
  332. }
  333.  
  334. //
  335. //  FUNCTION: MsgLButtonDoubleClick(HWND, UINT, WPARAM, LPARAM)
  336. //
  337. //  PURPOSE: Display left mouse button double click message and its parameters.
  338. //
  339. //  PARAMETERS:
  340. //    hwnd      - Window handle
  341. //    uMessage  - WM_LBUTTONDOBLECLICK (Unused)
  342. //    wparam    - Key flags
  343. //    lparam    -
  344. //      LOWORD - x position of cursor
  345. //      HIWORD - y position of cursor
  346. //
  347. //  RETURN VALUE:
  348. //    Always returns 0 - Message handled
  349. //
  350. //  COMMENTS:
  351. //
  352. //
  353.  
  354. #pragma argsused
  355. LRESULT MsgLButtonDoubleClick
  356.      (HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  357. {
  358.      wsprintf(
  359.           ButtonText,
  360.           "WM_LBUTTONDBLCLK: %x, %d, %d",
  361.           wparam, LOWORD(lparam), HIWORD(lparam)
  362.     );
  363.     InvalidateRect(hwnd, &rectButton, TRUE);
  364.  
  365.     return 0;
  366. }
  367.  
  368.  
  369. //
  370. //  FUNCTION: MsgRButtonDown(HWND, UINT, WPARAM, LPARAM)
  371. //
  372. //  PURPOSE: Display right mouse button down message and its parameters.
  373. //
  374. //  PARAMETERS:
  375. //    hwnd      - Window handle
  376. //    uMessage  - WM_RBUTTONDOWN (Unused)
  377. //    wparam    - Key flags
  378. //    lparam    -
  379. //      LOWORD - x position of cursor
  380. //      HIWORD - y position of cursor
  381. //
  382. //  RETURN VALUE:
  383. //    Always returns 0 - Message handled
  384. //
  385. //  COMMENTS:
  386. //
  387. //
  388.  
  389. #pragma argsused
  390. LRESULT MsgRButtonDown(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  391. {
  392.      wsprintf(
  393.           ButtonText,
  394.           "WM_RBUTTONDOWN: %x, %d, %d",
  395.         wparam, LOWORD(lparam), HIWORD(lparam)
  396.     );
  397.     InvalidateRect(hwnd, &rectButton, TRUE);
  398.  
  399.     return 0;
  400. }
  401.  
  402.  
  403. //
  404. //  FUNCTION: MsgRButtonUp(HWND, UINT, WPARAM, LPARAM)
  405. //
  406. //  PURPOSE: Display right mouse button up message and its parameters.
  407. //
  408. //  PARAMETERS:
  409. //    hwnd      - Window handle
  410. //    uMessage  - WM_RBUTTONUP (Unused)
  411. //    wparam    - Key flags
  412. //    lparam    -
  413. //      LOWORD - x position of cursor
  414. //      HIWORD - y position of cursor
  415. //
  416. //  RETURN VALUE:
  417. //    Always returns 0 - Message handled
  418. //
  419. //  COMMENTS:
  420. //
  421. //
  422.  
  423. #pragma argsused
  424. LRESULT MsgRButtonUp(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  425. {
  426.      wsprintf(
  427.           ButtonText,
  428.         "WM_RBUTTONUP: %x, %d, %d",
  429.         wparam, LOWORD(lparam), HIWORD(lparam)
  430.     );
  431.     InvalidateRect(hwnd, &rectButton, TRUE);
  432.  
  433.     return 0;
  434. }
  435.  
  436.  
  437. //
  438. //  FUNCTION: MsgRButtonDoubleClick(HWND, UINT, WPARAM, LPARAM)
  439. //
  440. //  PURPOSE: Display right mouse button double click message and its parameters.
  441. //
  442. //  PARAMETERS:
  443. //    hwnd      - Window handle
  444. //    uMessage  - WM_RBUTTONDOUBLECLICK (Unused)
  445. //    wparam    - Key flags
  446. //    lparam    -
  447. //      LOWORD - x position of cursor
  448. //      HIWORD - y position of cursor
  449. //
  450. //  RETURN VALUE:
  451. //    Always returns 0 - Message handled
  452. //
  453. //  COMMENTS:
  454. //
  455. //
  456.  
  457. #pragma argsused
  458. LRESULT MsgRButtonDoubleClick
  459.      (HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  460. {
  461.      wsprintf(
  462.         ButtonText,
  463.         "WM_RBUTTONDBLCLK: %x, %d, %d",
  464.         wparam, LOWORD(lparam), HIWORD(lparam)
  465.     );
  466.     InvalidateRect(hwnd, &rectButton, TRUE);
  467.  
  468.     return 0;
  469. }
  470.  
  471.  
  472. //
  473. //  FUNCTION: MsgKeyDown(HWND, UINT, WPARAM, LPARAM)
  474. //
  475. //  PURPOSE: Display key down message and its parameters.
  476. //
  477. //  PARAMETERS:
  478. //    hwnd      - Window handle
  479. //    uMessage  - WM_KEYDOWN (Unused)
  480. //    wparam    - Virtual Key Code
  481. //    lparam    - Key Data
  482. //
  483. //  RETURN VALUE:
  484. //    Always returns 0 - Message handled
  485. //
  486. //  COMMENTS:
  487. //
  488. //
  489.  
  490. #pragma argsused
  491. LRESULT MsgKeyDown(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  492. {
  493.     wsprintf(
  494.         KeyboardText,
  495.         "WM_KEYDOWN: %x, %x, %x",
  496.         wparam, LOWORD(lparam), HIWORD(lparam)
  497.     );
  498.     InvalidateRect(hwnd, &rectKeyboard, TRUE);
  499.  
  500.     return 0;
  501. }
  502.  
  503.  
  504. //
  505. //  FUNCTION: MsgKeyUp(HWND, UINT, WPARAM, LPARAM)
  506. //
  507. //  PURPOSE: Display key up message and its parameters.
  508. //
  509. //  PARAMETERS:
  510. //    hwnd      - Window handle
  511. //    uMessage  - WM_KEYUP (Unused)
  512. //    wparam    - Virtual Key Code
  513. //    lparam    - Key Data
  514. //
  515. //  RETURN VALUE:
  516. //    Always returns 0 - Message handled
  517. //
  518. //  COMMENTS:
  519. //
  520. //
  521.  
  522. #pragma argsused
  523. LRESULT MsgKeyUp(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  524. {
  525.     wsprintf(
  526.         KeyboardText,
  527.         "WM_KEYUP: %x, %x, %x",
  528.         wparam, LOWORD(lparam), HIWORD(lparam)
  529.     );
  530.     InvalidateRect(hwnd, &rectKeyboard, TRUE);
  531.  
  532.     return 0;
  533. }
  534.  
  535.  
  536. //
  537. //  FUNCTION: MsgChar(HWND, UINT, WPARAM, LPARAM)
  538. //
  539. //  PURPOSE: Display character recieved message and its parameters.
  540. //
  541. //  PARAMETERS:
  542. //    hwnd      - Window handle
  543. //    uMessage  - WM_CHAR (Unused)
  544. //    wparam    - Character Code
  545. //    lparam    - Key Data
  546. //
  547. //  RETURN VALUE:
  548. //    Always returns 0 - Message handled
  549. //
  550. //  COMMENTS:
  551. //
  552. //
  553.  
  554. #pragma argsused
  555. LRESULT MsgChar(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  556. {
  557.     wsprintf(
  558.         CharacterText,
  559.         "WM_CHAR: %c, %x, %x",
  560.         wparam, LOWORD(lparam), HIWORD(lparam)
  561.     );
  562.     InvalidateRect(hwnd, &rectCharacter, TRUE);
  563.  
  564.     return 0;
  565. }
  566.  
  567.  
  568. //
  569. //  FUNCTION: MsgTimer(HWND, UINT, WPARAM, LPARAM)
  570. //
  571. //  PURPOSE: Display timer message and a current time.
  572. //
  573. //  PARAMETERS:
  574. //    hwnd      - Window handle
  575. //    uMessage  - WM_TIMER (Unused)
  576. //    wparam    - The timer identifier
  577. //    lparam    - NULL           (Unused)
  578. //
  579. //  RETURN VALUE:
  580. //    Always returns 0 - Message handled
  581. //
  582. //  COMMENTS:
  583. //
  584. //
  585.  
  586. #pragma argsused
  587. LRESULT MsgTimer(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  588. {
  589.     if ( wparam == TIMERID ) {
  590.         wsprintf(
  591.             TimerText,
  592.             "WM_TIMER: %d seconds",
  593.             nTimerCount += 5
  594.         );
  595.         InvalidateRect(hwnd, &rectTimer, TRUE);
  596.     }
  597.  
  598.     return 0;
  599. }
  600.  
  601.  
  602. //
  603. //  FUNCTION: MsgScroll(HWND, UINT, WPARAM, LPARAM)
  604. //
  605. //  PURPOSE: Display scrollbar events and current position.
  606. //
  607. //  PARAMETERS:
  608. //    hwnd      - Window handle
  609. //    uMessage  - WM_VSCROLL or WM_HSCROLL
  610. //    GET_WM_HSCROLL_CODE(wparam,lparam) - Type of scroll
  611. //    GET_WM_HSCROLL_POS(wparam, lparam) - Position of scroll
  612. //          Only valid for SB_THUMBPOSTION and SB_THUMBTRACK
  613. //
  614. //  RETURN VALUE:
  615. //    Always returns 0 - Message handled
  616. //
  617. //  COMMENTS:
  618. //
  619. //
  620.  
  621. #pragma argsused
  622. LRESULT MsgScroll(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  623. {
  624.      char *szDirection;
  625.      char *szType;
  626.      int  fnBar = (uMessage == WM_HSCROLL) ? SB_HORZ : SB_VERT;
  627.      int  nPos  = GetScrollPos(hwnd, fnBar);
  628.  
  629.      szDirection = (uMessage == WM_HSCROLL) ? "WM_HSCROLL" : "WM_VSCROLL";
  630.  
  631.      switch(GET_WM_HSCROLL_CODE(wparam,lparam))
  632.      {
  633.           case SB_LINEUP:
  634.                 szType = "SB_LINEUP";
  635.                 nPos = max(0, nPos-1);
  636.                 break;
  637.           case SB_LINEDOWN:
  638.                 szType = "SB_LINEDOWN";
  639.                 nPos = min(100, nPos+1);
  640.                 break;
  641.           case SB_PAGEUP:
  642.                 szType = "SB_PAGEUP";
  643.                 nPos = max(0, nPos-10);
  644.                 break;
  645.           case SB_PAGEDOWN:
  646.                 szType = "SB_PAGEDOWN";
  647.                 nPos = min(100, nPos+10);
  648.                 break;
  649.           case SB_THUMBPOSITION:
  650.                 szType = "SB_THUMBPOSITION";
  651.                 nPos = GET_WM_HSCROLL_POS(wparam, lparam);
  652.                 break;
  653.           case SB_THUMBTRACK:
  654.                 szType = "SB_THUMBTRACK";
  655.                 nPos = GET_WM_HSCROLL_POS(wparam, lparam);
  656.                 break;
  657.           case SB_ENDSCROLL:
  658.                 szType = "SB_ENDSCROLL";
  659.                 break;
  660.           default:
  661.                 szType = "unknown";
  662.                 break;
  663.     }
  664.  
  665.     wsprintf(
  666.          ScrollText, "%s: %s, %x",
  667.         (LPSTR)szDirection, (LPSTR)szType, nPos
  668.     );
  669.     InvalidateRect(hwnd, &rectScroll, TRUE);
  670.  
  671.     if (GET_WM_HSCROLL_CODE(wparam,lparam) != SB_THUMBTRACK)
  672.         SetScrollPos(hwnd, fnBar, nPos, TRUE);
  673.  
  674.     return 0;
  675. }
  676.  
  677.  
  678. //
  679. //  FUNCTION: MsgPaint(HWND, UINT, WPARAM, LPARAM)
  680. //
  681. //  PURPOSE: Draw the strings for current messages.
  682. //
  683. //  PARAMETERS:
  684. //    hwnd      - Window handle
  685. //    uMessage  - WM_PAINT (Unused)
  686. //    wparam    - Extra data (Unused)
  687. //    lparam    - Extra data (Unused)
  688. //
  689. //  RETURN VALUE:
  690. //    Always returns 0 - Message handled
  691. //
  692. //  COMMENTS:
  693. //
  694. //
  695.  
  696. #pragma argsused
  697. LRESULT MsgPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  698. {
  699.     PAINTSTRUCT ps;
  700.     RECT rect;
  701.     HDC hdc = BeginPaint(hwnd, &ps);
  702.  
  703.     if (IntersectRect(&rect, &rectMouse, &ps.rcPaint))
  704.         TextOut(
  705.             hdc,
  706.             rectMouse.left, rectMouse.top,
  707.             MouseText, strlen(MouseText)
  708.         );
  709.     if (IntersectRect(&rect, &rectButton, &ps.rcPaint))
  710.         TextOut(
  711.             hdc,
  712.             rectButton.left, rectButton.top,
  713.             ButtonText, strlen(ButtonText)
  714.         );
  715.     if (IntersectRect(&rect, &rectKeyboard, &ps.rcPaint))
  716.         TextOut(
  717.             hdc,
  718.             rectKeyboard.left, rectKeyboard.top,
  719.             KeyboardText, strlen(KeyboardText)
  720.         );
  721.     if (IntersectRect(&rect, &rectCharacter, &ps.rcPaint))
  722.         TextOut(
  723.             hdc,
  724.             rectCharacter.left, rectCharacter.top,
  725.             CharacterText, strlen(CharacterText)
  726.         );
  727.     if (IntersectRect(&rect, &rectTimer, &ps.rcPaint))
  728.         TextOut(
  729.             hdc, rectTimer.left, rectTimer.top,
  730.             TimerText, strlen(TimerText)
  731.         );
  732.     if (IntersectRect(&rect, &rectScroll, &ps.rcPaint))
  733.         TextOut(
  734.             hdc,
  735.             rectScroll.left, rectScroll.top,
  736.             ScrollText, strlen(ScrollText)
  737.         );
  738.  
  739.     EndPaint(hwnd, &ps);
  740.  
  741.     return 0;
  742. }
  743.  
  744. //
  745. //  FUNCTION: InitInput(HWND)
  746. //
  747. //  PURPOSE: Set up the rectangles for dispay of each type of message
  748. //
  749. //  PARAMETERS:
  750. //    hwnd   - Window handle
  751. //
  752. //  RETURN VALUE:
  753. //    Always returns TRUE - Sucess
  754. //
  755. //  COMMENTS:
  756. //
  757. //
  758.  
  759. BOOL InitInput(HWND hwnd)
  760. {
  761.     HDC hdc;
  762.     TEXTMETRIC tm;
  763.     RECT rect;
  764.     int  dyLine;
  765.  
  766.     // Get a handle to the display context for the window in order
  767.     //  to compute line height, screen width, and pixel count for 1/4 inch
  768.  
  769.     hdc = GetDC(hwnd);
  770.     GetTextMetrics(hdc, &tm);
  771.     dyLine = tm.tmExternalLeading + tm.tmHeight;
  772.  
  773.     rect.left   = GetDeviceCaps(hdc, LOGPIXELSX) / 4;   // 1/4 inch
  774.     rect.right  = GetDeviceCaps(hdc, HORZRES);
  775.     rect.top    = GetDeviceCaps(hdc, LOGPIXELSY) / 4;   // 1/4 inch
  776.     ReleaseDC(hwnd, hdc);
  777.  
  778.     // Compute rectangle for mouse move events
  779.     rect.bottom = rect.top + dyLine;
  780.     rectMouse   = rect;
  781.  
  782.     // Compute rectangle for mouse button events
  783.     rect.top += dyLine;
  784.     rect.bottom += dyLine;
  785.     rectButton = rect;
  786.  
  787.     // Compute rectangle for keyboard events
  788.     rect.top += dyLine;
  789.     rect.bottom += dyLine;
  790.     rectKeyboard = rect;
  791.  
  792.     // Compute rectangle for character events
  793.     rect.top += dyLine;
  794.     rect.bottom += dyLine;
  795.     rectCharacter = rect;
  796.  
  797.     // Compute rectangle for scroll events
  798.     rect.top += dyLine;
  799.     rect.bottom += dyLine;
  800.     rectScroll = rect;
  801.  
  802.     // Compute rectangle for timer events
  803.     rect.top += dyLine;
  804.     rect.bottom += dyLine;
  805.     rectTimer = rect;
  806.  
  807.     return TRUE;
  808. }
  809.