home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / GDIINPUT.PAK / PENDLG.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  11.2 KB  |  411 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:   pendlg.c
  9. //
  10. //  PURPOSE:  Displays the "Pen Style" dialog box
  11. //
  12. //  FUNCTIONS:
  13. //    PenDlg          - Process messages for "Pen Style" dialog box.
  14. //    MsgPenInit      - Initialize the Pen dialog with info from lparam.
  15. //    MsgPenPaint     - Paint the Example Window in the Pen dialog
  16. //    MsgPenCommand   - Process WM_COMMAND messages sent to the Pen dialog.
  17. //    CmdPenStyle     - Track the currently selected pen style.
  18. //    CmdPenColor     - Put up the ChooseColor dialog to select pen color.
  19. //    CmdPenDone      - Free the Pen dialog and related data.
  20. //
  21. //  COMMENTS:
  22. //
  23.  
  24. #include <windows.h>            // required for all Windows applications
  25. #include <windowsx.h>
  26. #include "globals.h"            // prototypes specific to this application
  27. #include "pendlg.h"             // Controls ID's for the Pen dialog
  28.  
  29. // global variables specific to this module
  30. RECT rcExam;                 // location of example window in dialog
  31.  
  32. // prototypes specific to this module
  33. LRESULT MsgPenInit    (HWND, UINT, WPARAM, LPARAM);
  34. LRESULT MsgPenPaint   (HWND, UINT, WPARAM, LPARAM);
  35. LRESULT MsgPenCommand (HWND, UINT, WPARAM, LPARAM);
  36. LRESULT CmdPenStyle   (HWND, WORD, WORD, HWND);
  37. LRESULT CmdPenColor   (HWND, WORD, WORD, HWND);
  38. LRESULT CmdPenDone    (HWND, WORD, WORD, HWND);
  39.  
  40. // Pen dialog message table definition.
  41. MSD rgmsdPen[] =
  42. {
  43.     {WM_COMMAND,    MsgPenCommand},
  44.     {WM_PAINT,      MsgPenPaint},
  45.     {WM_INITDIALOG, MsgPenInit}
  46. };
  47.  
  48. MSDI msdiPen =
  49. {
  50.     sizeof(rgmsdPen) / sizeof(MSD),
  51.     rgmsdPen,
  52.     edwpNone
  53. };
  54.  
  55. // Pen dialog command table definition.
  56. CMD rgcmdPen[] =
  57. {
  58.     {IDD_PENSTYLE,  CmdPenStyle},   // Pen Style notification msg
  59.     {IDD_PENCOLOR,  CmdPenColor},   // Color button
  60.     {IDOK,          CmdPenDone},    // OK and Cancel buttons
  61.     {IDCANCEL,      CmdPenDone}
  62. };
  63.  
  64. CMDI cmdiPen =
  65. {
  66.     sizeof(rgcmdPen) / sizeof(CMD),
  67.     rgcmdPen,
  68.     edwpNone
  69. };
  70.  
  71.  
  72. //
  73. //  FUNCTION: PenDlg(HWND, UINT, WPARAM, LPARAM)
  74. //
  75. //  PURPOSE:  Processes messages for "Pen Style" dialog box.
  76. //
  77. //  PARAMETERS:
  78. //    hdlg - window handle of the dialog box
  79. //    wMessage - type of message
  80. //    wparam - message-specific information
  81. //    lparam - message-specific information
  82. //
  83. //  RETURN VALUE:
  84. //    TRUE - message handled
  85. //    FALSE - message not handled
  86. //
  87. //  COMMENTS:
  88. //
  89. //
  90.  
  91. LRESULT CALLBACK PenDlg(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  92. {
  93.     return DispMessage(&msdiPen, hdlg, uMessage, wparam, lparam);
  94. }
  95.  
  96.  
  97. //
  98. //  FUNCTION: MsgPenInit(HWND, UINT, WPARAM, LPARAM)
  99. //
  100. //  PURPOSE: To initialize the Pen dialog with info from lparam.
  101. //
  102. //  PARAMETERS:
  103. //    hwnd - The window handing the message.
  104. //    uMessage - The message number. (unused).
  105. //    wparam - Message specific data (unused).
  106. //    lparam - points to LOGPEN structure.
  107. //
  108. //  RETURN VALUE:
  109. //    Always returns TRUE
  110. //
  111. //  COMMENTS:
  112. //    Sets the initial state of the controls according to the LOGPEN
  113. //      passed in via lparam.
  114. //
  115.  
  116. #pragma argsused
  117. LRESULT MsgPenInit(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  118. {
  119.     int i, nIndex, nSel;
  120.     HWND hctlStyle;
  121.     char szTmp[32];
  122.     LPLOGPEN lpLP;
  123.  
  124.     // lparam is a pointer to a LOGPEN structure
  125.     lpLP = (LPLOGPEN)lparam;
  126.  
  127.     // Save pointer to LOGPEN structure in window bytes
  128.     SetWindowLong(hdlg, DWL_USER, (LONG)lpLP);
  129.  
  130.     // Center the dialog over the application window
  131.     CenterWindow(hdlg, GetWindow(hdlg, GW_OWNER));
  132.  
  133.     // Fill up the style combobox.  The item data is set to the
  134.     // corresponding pen style defined in windows.h (e.g. PS_SOLID).
  135.  
  136.     hctlStyle = GetDlgItem(hdlg, IDD_PENSTYLE);
  137.     nSel = 0;
  138.  
  139.     for (i = IDD_PENFIRST; i <= IDD_PENLAST; i++)
  140.     {
  141.         LoadString(hInst, i, szTmp, sizeof(szTmp));
  142.         nIndex = SendMessage(hctlStyle, CB_ADDSTRING, 0, (LPARAM)(LPSTR)szTmp);
  143.         SendMessage(hctlStyle, CB_SETITEMDATA, nIndex, i - IDD_PENSTYLE);
  144.  
  145.         // If this item is the current style, remember it
  146.         if (i == IDD_PENSTYLE + (int)lpLP->lopnStyle)
  147.             nSel = nIndex;
  148.     }
  149.  
  150.     // Set the initial style selection
  151.     SendMessage(hctlStyle, CB_SETCURSEL, nSel, 0L);
  152.  
  153.     // Initialize the Width edit control
  154.     SetDlgItemInt(hdlg, IDD_PENWIDTH, lpLP->lopnWidth.x, FALSE);
  155.  
  156.     // Example window always uses 0 width (so styles work)
  157.     lpLP->lopnWidth.x = 0;
  158.  
  159.     // Get coordinates of the example window in the dialog
  160.     GetWindowRect(GetDlgItem(hdlg, IDD_PENEXAMPLE), &rcExam);
  161.     ScreenToClient(hdlg, (LPPOINT)&rcExam);
  162.     ScreenToClient(hdlg, ((LPPOINT)&rcExam) + 1);
  163.  
  164.     // Reduce rect slightly so we don't paint over its frame
  165.     InflateRect(&rcExam, -1, -1);
  166.  
  167.     return TRUE;
  168. }
  169.  
  170.  
  171. //
  172. //  FUNCTION: MsgPenPaint(HWND, UINT, WPARAM, LPARAM)
  173. //
  174. //  PURPOSE: Paint the example window with examples of the current pen
  175. //
  176. //  PARAMETERS:
  177. //    hwnd - The window handling the message.
  178. //    uMessage - The message number. (unused).
  179. //    wparam - Message specific data (unused).
  180. //    lparam - Message specific data (unused).
  181. //
  182. //  RETURN VALUE:
  183. //    Always returns TRUE
  184. //
  185. //  COMMENTS:
  186. //    Sets the initial state of the controls according to the LOGPEN
  187. //    passed in via lparam.
  188. //
  189.  
  190. #pragma argsused
  191. LRESULT MsgPenPaint(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  192. {
  193.     PAINTSTRUCT ps;
  194.     HPEN hpen, hpenBlack;
  195.     LPLOGPEN lpLP;
  196.     int i, y, dy;
  197.  
  198.     BeginPaint(hdlg, &ps);
  199.     SetBkMode(ps.hdc, TRANSPARENT);
  200.     SelectObject(ps.hdc, GetStockObject(NULL_BRUSH));
  201.  
  202.     // Get pointer to LOGPEN from window bytes
  203.     lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  204.  
  205.  
  206.     // Draw some stuff in the example window with pens based on
  207.     // the current LOGPEN (vary the width starting at 0).
  208.  
  209.     #define NUMLINES    5
  210.  
  211.     y = rcExam.top;
  212.     dy = (rcExam.bottom - rcExam.top) / (NUMLINES + 1);
  213.     lpLP->lopnWidth.x = 0;
  214.     hpenBlack = GetStockObject(BLACK_PEN);
  215.  
  216.     for (i = 0; i < NUMLINES; i++)
  217.     {
  218.           lpLP->lopnWidth.x = i*3;
  219.         hpen = CreatePenIndirect(lpLP);
  220.         SelectObject(ps.hdc, hpen);
  221.  
  222.         MoveToEx(ps.hdc, rcExam.left + 10, y += dy, NULL);
  223.         LineTo(ps.hdc, rcExam.right - 10, y);
  224.  
  225.         // Deselect and delete the pen
  226.         SelectObject(ps.hdc, hpenBlack);
  227.         DeleteObject(hpen);
  228.     }
  229.  
  230.     EndPaint(hdlg, &ps);
  231.      return 0;
  232. }
  233.  
  234.  
  235. //
  236. //  FUNCTION: MsgPenCommand(HWND, UINT, WPARAM, LPARAM)
  237. //
  238. //  PURPOSE: Process WM_COMMAND messages sent to the PenStyle box.
  239. //
  240. //  PARAMETERS:
  241. //    hwnd      - The window handing the message.
  242. //    uMessage  - The message number. (unused).
  243. //    wparam    - Message specific data (unused).
  244. //    lparam    - Message specific data (unused).
  245. //
  246. //  RETURN VALUE:
  247. //    Always returns 0 - message handled.
  248. //
  249. //  COMMENTS:
  250. //    Uses this DipsCommand function defined in wndproc.c combined
  251. //    with the cmdiPen structure defined in this file to handle
  252. //    the command messages for the Pen dialog box.
  253. //
  254.  
  255. #pragma argsused
  256. LRESULT MsgPenCommand(HWND   hwnd,
  257.                              UINT   uMessage,
  258.                              WPARAM wparam,
  259.                              LPARAM lparam)
  260. {
  261.     return DispCommand(&cmdiPen, hwnd, wparam, lparam);
  262. }
  263.  
  264.  
  265. //
  266. //  FUNCTION: CmdPenStyle(HWND, WORD, WORD, HWND)
  267. //
  268. //  PURPOSE: Keeps track of which style button is selected.
  269. //
  270. //  PARAMETERS:
  271. //    hwnd      - The window handling the command.
  272. //    wCommand  - Child control ID (unused).
  273. //    wNotify   - Child notification code.
  274. //    hwndCtrl  - NULL (unused).
  275. //
  276. //  RETURN VALUE:
  277. //    Always returns TRUE.
  278. //
  279. //  COMMENTS:
  280. //
  281.  
  282. #pragma argsused
  283. LRESULT CmdPenStyle(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  284. {
  285.     LPLOGPEN lpLP;
  286.     int nSel;
  287.  
  288.     // Get pointer to LOGPEN from window bytes
  289.     lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  290.  
  291.     // Update the style selection if necessary.
  292.     if (CBN_SELCHANGE == wNotify)
  293.     {
  294.         nSel = SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0L);
  295.         if (CB_ERR != nSel)
  296.         {
  297.             // Save new style
  298.             lpLP->lopnStyle = SendMessage(hwndCtrl, CB_GETITEMDATA, nSel, 0L);
  299.  
  300.             // Repaint the example window
  301.             InvalidateRect(hdlg, &rcExam, TRUE);
  302.         }
  303.      }
  304.  
  305.     return TRUE;
  306. }
  307.  
  308.  
  309. //
  310. //  FUNCTION: CmdPenColor(HWND, WORD, WORD, HWND)
  311. //
  312. //  PURPOSE: Puts up ChooseColor dialog to choose pen color.
  313. //
  314. //  PARAMETERS:
  315. //    hwnd      - The window handling the command.
  316. //    wCommand  - IDD_PENCOLOR (unused).
  317. //    wNotify   - Child notification code (unused).
  318. //    hwndCtrl  - NULL (unused).
  319. //
  320. //  RETURN VALUE:
  321. //    Always returns TRUE.
  322. //
  323. //  COMMENTS:
  324. //
  325.  
  326. #pragma argsused
  327. LRESULT CmdPenColor(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  328. {
  329.     LPLOGPEN lpLP;
  330.     CHOOSECOLOR cc;
  331.     static DWORD dwCustColors[16];
  332.  
  333.     // Get pointer to LOGPEN from window bytes
  334.     lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  335.  
  336.     // Initialize CHOOSECOLOR struct
  337.     cc.lStructSize      = sizeof(cc);
  338.     cc.hwndOwner        = hdlg;
  339.     cc.hInstance        = NULL;
  340.      cc.rgbResult        = lpLP->lopnColor;
  341.     cc.lpCustColors     = dwCustColors;
  342.     cc.Flags            = CC_RGBINIT;
  343.     cc.lCustData        = 0;
  344.     cc.lpfnHook         = NULL;
  345.     cc.lpTemplateName   = NULL;
  346.  
  347.     if (ChooseColor(&cc))
  348.     {
  349.         // Save new color
  350.         lpLP->lopnColor = cc.rgbResult;
  351.  
  352.         // Repaint the example window
  353.           InvalidateRect(hdlg, &rcExam, TRUE);
  354.     }
  355.  
  356.     return TRUE;
  357. }
  358.  
  359.  
  360. //
  361. //  FUNCTION: CmdPenDone(HWND, WORD, WORD, HWND)
  362. //
  363. //  PURPOSE: Free the PenStyle box and related data.
  364. //
  365. //  PARAMETERS:
  366. //    hwnd      - The window handling the command.
  367. //    wCommand  - The command to be handled.
  368. //    wNotify   - Notification code (unused).
  369. //    hwndCtrl  - NULL (unused).
  370. //
  371. //  RETURN VALUE:
  372. //    Always returns TRUE.
  373. //
  374. //  COMMENTS:
  375. //    Calls EndDialog to finish the dialog session.
  376. //
  377.  
  378. #pragma argsused
  379. LRESULT CmdPenDone(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  380. {
  381.     LPLOGPEN lpLP;
  382.     UINT nWidth;
  383.     BOOL bTranslated;
  384.  
  385.     if (IDOK == wCommand)
  386.     {
  387.         // Get pointer to LOGPEN from window bytes
  388.         lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  389.  
  390.         // Get pen width from edit control
  391.         nWidth = GetDlgItemInt(hdlg, IDD_PENWIDTH, &bTranslated, FALSE);
  392.  
  393.         if (bTranslated)                // Did GetDlgItemInt succeed?
  394.         {
  395.             lpLP->lopnWidth.x = nWidth; // Yes, save new width.
  396.             EndDialog(hdlg, TRUE);      // Exit the dialog (success)
  397.         }
  398.         else                            // Error
  399.         {
  400.             MessageBox(hdlg, "Pen Width must be a non-negative integer.",
  401.                         "Pen Style", MB_ICONINFORMATION | MB_OK);
  402.             SetDlgItemInt(hdlg, IDD_PENWIDTH, lpLP->lopnWidth.x, FALSE);
  403.             SetFocus(GetDlgItem(hdlg, IDD_PENWIDTH));
  404.         }
  405.      }
  406.     else    // Just close the dialog (cancel)
  407.         EndDialog(hdlg, FALSE);
  408.  
  409.     return TRUE;
  410. }
  411.