POLYWIN.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:7k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * POLYWIN.CPP
  3.  * Polyline Component Chapter 10
  4.  *
  5.  * Window procedure for the polyline drawing window and support
  6.  * functions.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14. #include "polyline.h"
  15. /*
  16.  * PolylineWndProc
  17.  *
  18.  * Purpose:
  19.  *  Window procedure for the polyline drawing window.
  20.  */
  21. LRESULT APIENTRY PolylineWndProc(HWND hWnd, UINT iMsg
  22.     , WPARAM wParam, LPARAM lParam)
  23.     {
  24.     PCPolyline      ppl;
  25.     PAINTSTRUCT     ps;
  26.     HDC             hDC;
  27.     POINTS          pt;
  28.     RECT            rc;
  29.     ppl=(PCPolyline)GetWindowLong(hWnd, PLWL_STRUCTURE);
  30.     switch (iMsg)
  31.         {
  32.         case WM_CREATE:
  33.             ppl=(PCPolyline)((LPCREATESTRUCT)lParam)->lpCreateParams;
  34.             SetWindowLong(hWnd, PLWL_STRUCTURE, (LONG)ppl);
  35.             //New repaints this window, so store the hWnd here.
  36.             ppl->m_hWnd=hWnd;
  37.             ppl->m_pImpIPolyline->New();
  38.             break;
  39.         case WM_PAINT:
  40.             hDC=BeginPaint(hWnd, &ps);
  41.             ppl->Draw(hDC, FALSE, TRUE);
  42.             EndPaint(hWnd, &ps);
  43.             break;
  44.         case WM_LBUTTONDOWN:
  45.             //Stop if we are already at the limit.
  46.             if (CPOLYLINEPOINTS==ppl->m_pl.cPoints)
  47.                 {
  48.                 MessageBeep(0);
  49.                 break;
  50.                 }
  51.             //Convert the points into 0-32767 range
  52.             GetClientRect(hWnd, &rc);
  53.             pt=MAKEPOINTS(lParam);
  54.             ppl->PointScale(&rc, &pt, FALSE);
  55.             ppl->m_pl.rgpt[ppl->m_pl.cPoints++]=pt;
  56.             //Draw the lines to this new point only.
  57.             hDC=GetDC(hWnd);
  58.             ppl->Draw(hDC, FALSE, FALSE);
  59.             ReleaseDC(hWnd, hDC);
  60.             if (NULL!=ppl->m_pAdv)
  61.                 ppl->m_pAdv->OnPointChange();
  62.             break;
  63.         default:
  64.             return DefWindowProc(hWnd, iMsg, wParam, lParam);
  65.         }
  66.     return 0L;
  67.     }
  68. /*
  69.  * CPolyline::Draw
  70.  *
  71.  * Purpose:
  72.  *  Paints the current line in the polyline window.
  73.  *
  74.  * Parameters:
  75.  *  hDC             HDC to draw on, a metafile or printer DC.
  76.  *  fMetafile       BOOL indicating if hDC is a metafile or not,
  77.  *                  so we can avoid operations that RIP.
  78.  *  fEntire         BOOL indicating if we should draw the entire
  79.  *                  figure or not.
  80.  *
  81.  * Return Value:
  82.  *  None
  83.  */
  84. void CPolyline::Draw(HDC hDC, BOOL fMetafile, BOOL fEntire)
  85.     {
  86.     HBRUSH          hBrush;
  87.     HPEN            hPen;
  88.     HGDIOBJ         hObj1, hObj2;
  89.     UINT            i, j;
  90.     UINT            uMM;
  91.     POINTS          pt1, pt2;
  92.     POINT           rgpt[CPOLYLINEPOINTS];
  93.     RECT            rc;
  94.     GetClientRect(m_hWnd, &rc);
  95.     /*
  96.      * Make a 32-bit copy of the points in the POLYLINE itself
  97.      * so we can use DPtoLP and LPtoDP.
  98.      */
  99.     for (i=0; i < m_pl.cPoints; i++)
  100.         {
  101.         rgpt[i].x=m_pl.rgpt[i].x;
  102.         rgpt[i].y=m_pl.rgpt[i].y;
  103.         }
  104.     /*
  105.      * If the mapping mode is not MM_TEXT, convert the points to
  106.      * whatever mapping mode in in effect before drawing.
  107.      * This specifically supports metafiles in MM_ANISOTROPIC.
  108.      */
  109.     uMM=fMetafile ? MM_TEXT : GetMapMode(hDC);
  110.     if (MM_TEXT!=uMM)
  111.         DPtoLP(hDC, rgpt, m_pl.cPoints);
  112.     hPen=CreatePen(m_pl.iLineStyle, 1, m_pl.rgbLine);
  113.     hObj1=SelectObject(hDC, hPen);
  114.     hBrush=CreateSolidBrush(m_pl.rgbBackground);
  115.     hObj2=SelectObject(hDC, hBrush);
  116.     SetBkColor(hDC, m_pl.rgbBackground);
  117.     /*
  118.      * Either draw the entire figure or just a single point.  The
  119.      * entire figure also includes erasing the background
  120.      * completely, since hDC may be a metafile DC.  Drawing a single
  121.      * point just updates the figure for that new point.
  122.      */
  123.     if (fEntire || 0==m_pl.cPoints)
  124.         {
  125.         //Erase the background for bitmaps and metafiles.
  126.         SelectObject(hDC, GetStockObject(NULL_PEN));
  127.         Rectangle(hDC, rc.left, rc.top, rc.right+1, rc.bottom+1);
  128.         SelectObject(hDC, hPen);
  129.         /*
  130.          * If we are drawing the entire figure, then loop through
  131.          * each point drawing a line to each successive point.
  132.          */
  133.         for (i=0; i < m_pl.cPoints; i++)
  134.             {
  135.             for (j=i; j < m_pl.cPoints; j++)
  136.                 {
  137.                 pt1.x=(short)rgpt[i].x;
  138.                 pt1.y=(short)rgpt[i].y;
  139.                 pt2.x=(short)rgpt[j].x;
  140.                 pt2.y=(short)rgpt[j].y;
  141.                 PointScale(&rc, &pt1, TRUE);
  142.                 PointScale(&rc, &pt2, TRUE);
  143.                 MoveToEx(hDC, pt1.x, pt1.y, NULL);
  144.                 LineTo(hDC, pt2.x, pt2.y);
  145.                 }
  146.             }
  147.         }
  148.     else
  149.         {
  150.         /*
  151.          * If we are only drawing the last point, just cycle once
  152.          * through previous points.
  153.          */
  154.         //Get the last point entered in the array.
  155.         j=m_pl.cPoints-1;
  156.         pt1.x=(short)rgpt[j].x;
  157.         pt1.y=(short)rgpt[j].y;
  158.         PointScale(&rc, &pt1, TRUE);
  159.         for (i=0; i < j; i++)
  160.             {
  161.             pt2.x=(short)rgpt[i].x;
  162.             pt2.y=(short)rgpt[i].y;
  163.             PointScale(&rc, &pt2, TRUE);
  164.             MoveToEx(hDC, pt1.x, pt1.y, NULL);
  165.             LineTo(hDC, pt2.x, pt2.y);
  166.             }
  167.         }
  168.     //If we have one point, draw a dot to indicate it's position.
  169.     if (1==m_pl.cPoints)
  170.         {
  171.         pt1.x=(short)rgpt[0].x;
  172.         pt1.y=(short)rgpt[0].y;
  173.         PointScale(&rc, &pt1, TRUE);
  174.         SetPixel(hDC, pt1.x, pt1.y, m_pl.rgbLine);
  175.         }
  176.     //Restore original points.
  177.     if (MM_TEXT!=uMM)
  178.         LPtoDP(hDC, rgpt, m_pl.cPoints);
  179.     SelectObject(hDC, hObj1);
  180.     SelectObject(hDC, hObj2);
  181.     DeleteObject(hBrush);
  182.     DeleteObject(hPen);
  183.     return;
  184.     }
  185. /*
  186.  * CPolyline::PointScale
  187.  *
  188.  * Purpose:
  189.  *  Scales a point to or from a relative window coordinate to a
  190.  *  0-32767 coordinate.
  191.  *
  192.  * Parameters:
  193.  *  pRect           LPRECT of the window.
  194.  *  ppt             LPPOINTS to convert
  195.  *  fScaleToWindow  BOOL indicating direction of scaling.
  196.  *
  197.  * Return Value:
  198.  *  None
  199.  */
  200. void CPolyline::PointScale(LPRECT pRect, LPPOINTS ppt
  201.     , BOOL fScaleToWindow)
  202.     {
  203.     DWORD   cx, cy;
  204.     //Window size
  205.     cx=(DWORD)(pRect->right-pRect->left);
  206.     cy=(DWORD)(pRect->bottom-pRect->top);
  207.     //Prevent crashes
  208.     if (0L==cx) cx=1;
  209.     if (0L==cy) cy=1;
  210.     //Must use DWORD to insure proper scaling.
  211.     if (fScaleToWindow)
  212.         {
  213.         ppt->x=(UINT)(((DWORD)ppt->x*cx) >> 15);
  214.         ppt->y=(UINT)(((DWORD)ppt->y*cy) >> 15);
  215.         }
  216.     else
  217.         {
  218.         ppt->x=(UINT)(((DWORD)ppt->x << 15)/cx);
  219.         ppt->y=(UINT)(((DWORD)ppt->y << 15)/cy);
  220.         }
  221.     return;
  222.     }