home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / classlib / chatch.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  10KB  |  407 lines

  1. /*
  2.  * CHATCH.CPP
  3.  *
  4.  * Implementation of a class to manage a hatch border around an
  5.  * in-place editing window.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Right Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #include <windows.h>
  16. #include "classlib.h"
  17.  
  18.  
  19. //Hatch pattern brush bits
  20. static WORD g_wHatchBmp[]={0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88};
  21.  
  22. void DrawShading(LPRECT, HDC, UINT);
  23.  
  24.  
  25. /*
  26.  * HatchWindowRegister
  27.  *
  28.  * Purpose:
  29.  *  Registers the hatch window class for use with CHatchWin.
  30.  *
  31.  * Parameters:
  32.  *  hInst           HINSTANCE under which to register.
  33.  *
  34.  * Return Value:
  35.  *  BOOL            TRUE if successful, FALSE otherwise.
  36.  */
  37.  
  38. BOOL HatchWindowRegister(HINSTANCE hInst)
  39.     {
  40.     WNDCLASS    wc;
  41.  
  42.     //Must have CS_DBLCLKS for border!
  43.     wc.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  44.     wc.hInstance     = hInst;
  45.     wc.cbClsExtra    = 0;
  46.     wc.lpfnWndProc   = HatchWndProc;
  47.     wc.cbWndExtra    = CBHATCHWNDEXTRA;
  48.     wc.hIcon         = NULL;
  49.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  50.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  51.     wc.lpszMenuName  = NULL;
  52.     wc.lpszClassName = SZCLASSHATCHWIN;
  53.  
  54.     return RegisterClass(&wc);
  55.         return FALSE;
  56.     }
  57.  
  58.  
  59.  
  60.  
  61. /*
  62.  * CHatchWin:CHatchWin
  63.  * CHatchWin::~CHatchWin
  64.  *
  65.  * Constructor Parameters:
  66.  *  hInst           HINSTANCE of the application we're in.
  67.  */
  68.  
  69. CHatchWin::CHatchWin(HINSTANCE hInst)
  70.     : CWindow(hInst)
  71.     {
  72.     m_hWnd=NULL;
  73.     m_hWndKid=NULL;
  74.     m_hWndAssociate=NULL;
  75.     m_uID=0;
  76.  
  77.     m_dBorderOrg=GetProfileInt(TEXT("windows")
  78.         , TEXT("OleInPlaceBorderWidth")
  79.         , HATCHWIN_BORDERWIDTHDEFAULT);
  80.  
  81.     m_dBorder=m_dBorderOrg;
  82.     SetRect(&m_rcPos, 0, 0, 0, 0);
  83.     SetRect(&m_rcClip, 0, 0, 0, 0);
  84.  
  85.     return;
  86.     }
  87.  
  88.  
  89. CHatchWin::~CHatchWin(void)
  90.     {
  91.     /*
  92.      * Chances are this was already destroyed when a document
  93.      * was destroyed.
  94.      */
  95.     if (NULL!=m_hWnd && IsWindow(m_hWnd))
  96.         DestroyWindow(m_hWnd);
  97.  
  98.     return;
  99.     }
  100.  
  101.  
  102.  
  103. /*
  104.  * CHatchWin::Init
  105.  *
  106.  * Purpose:
  107.  *  Instantiates a hatch window within a given parent with a
  108.  *  default rectangle.  This is not initially visible.
  109.  *
  110.  * Parameters:
  111.  *  hWndParent      HWND of the parent of this window
  112.  *  uID             UINT identifier for this window (send in
  113.  *                  notifications to associate window).
  114.  *  hWndAssoc       HWND of the initial associate.
  115.  *
  116.  * Return Value:
  117.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  118.  */
  119.  
  120. BOOL CHatchWin::Init(HWND hWndParent, UINT uID, HWND hWndAssoc)
  121.     {
  122.     m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSHATCHWIN
  123.         , SZCLASSHATCHWIN, WS_CHILD | WS_CLIPSIBLINGS
  124.         | WS_CLIPCHILDREN, 0, 0, 100, 100, hWndParent, (HMENU)uID
  125.         , m_hInst, this);
  126.  
  127.     m_uID=uID;
  128.     m_hWndAssociate=hWndAssoc;
  129.  
  130.     return (NULL!=m_hWnd);
  131.     }
  132.  
  133.  
  134.  
  135.  
  136. /*
  137.  * CHatchWin::HwndAssociateSet
  138.  * CHatchWin::HwndAssociateGet
  139.  *
  140.  * Purpose:
  141.  *  Sets (Set) or retrieves (Get) the associate window of the
  142.  *  hatch window.
  143.  *
  144.  * Parameters: (Set only)
  145.  *  hWndAssoc       HWND to set as the associate.
  146.  *
  147.  * Return Value:
  148.  *  HWND            Previous (Set) or current (Get) associate
  149.  *                  window.
  150.  */
  151.  
  152. HWND CHatchWin::HwndAssociateSet(HWND hWndAssoc)
  153.     {
  154.     HWND    hWndT=m_hWndAssociate;
  155.  
  156.     m_hWndAssociate=hWndAssoc;
  157.     return hWndT;
  158.     }
  159.  
  160. HWND CHatchWin::HwndAssociateGet(void)
  161.     {
  162.     return m_hWndAssociate;
  163.     }
  164.  
  165.  
  166.  
  167.  
  168.  
  169. /*
  170.  * CHatchWin::RectsSet
  171.  *
  172.  * Purpose:
  173.  *  Changes the size and position of the hatch window and the child
  174.  *  window within it using a position rectangle for the child and
  175.  *  a clipping rectangle for the hatch window and child.  The hatch
  176.  *  window occupies prcPos expanded by the hatch border and clipped
  177.  *  by prcClip.  The child window is fit to prcPos to give the
  178.  *  proper scaling, but it clipped to the hatch window which
  179.  *  therefore clips it to prcClip without affecting the scaling.
  180.  *
  181.  * Parameters:
  182.  *  prcPos          LPRECT providing the position rectangle.
  183.  *  prcClip         LPRECT providing the clipping rectangle.
  184.  *
  185.  * Return Value:
  186.  *  None
  187.  */
  188.  
  189. void CHatchWin::RectsSet(LPRECT prcPos, LPRECT prcClip)
  190.     {
  191.     RECT    rc;
  192.     RECT    rcPos;
  193.  
  194.     m_rcPos=*prcPos;
  195.     m_rcClip=*prcClip;
  196.  
  197.     //Calculate the rectangle for the hatch window, then clip it.
  198.     rcPos=*prcPos;
  199.     InflateRect(&rcPos, m_dBorder, m_dBorder);
  200.     IntersectRect(&rc, &rcPos, prcClip);
  201.  
  202.     SetWindowPos(m_hWnd, NULL, rc.left, rc.top, rc.right-rc.left
  203.         , rc.bottom-rc.top, SWP_NOZORDER | SWP_NOACTIVATE);
  204.  
  205.     /*
  206.      * Set the rectangle of the child window to be at m_dBorder
  207.      * from the top and left but with the same size as prcPos
  208.      * contains.  The hatch window will clip it.
  209.      */
  210.     SetWindowPos(m_hWndKid, NULL, rcPos.left-rc.left+m_dBorder
  211.         , rcPos.top-rc.top+m_dBorder, prcPos->right-prcPos->left
  212.         , prcPos->bottom-prcPos->top, SWP_NOZORDER | SWP_NOACTIVATE);
  213.  
  214.     return;
  215.     }
  216.  
  217.  
  218.  
  219. /*
  220.  * CHatchWin::ChildSet
  221.  *
  222.  * Purpose:
  223.  *  Assigns a child window to this hatch window.
  224.  *
  225.  * Parameters:
  226.  *  hWndKid         HWND of the child window.
  227.  *
  228.  * Return Value:
  229.  *  None
  230.  */
  231.  
  232. void CHatchWin::ChildSet(HWND hWndKid)
  233.     {
  234.     m_hWndKid=hWndKid;
  235.  
  236.     if (NULL!=hWndKid)
  237.         {
  238.         SetParent(hWndKid, m_hWnd);
  239.  
  240.         //Insure this is visible when the hatch window becomes visible.
  241.         ShowWindow(hWndKid, SW_SHOW);
  242.         }
  243.  
  244.     return;
  245.     }
  246.  
  247.  
  248.  
  249. /*
  250.  * CHatchWin::ShowHatch
  251.  *
  252.  * Purpose:
  253.  *  Turns hatching on and off; turning the hatching off changes
  254.  *  the size of the window to be exactly that of the child, leaving
  255.  *  everything else the same.  The result is that we don't have
  256.  *  to turn off drawing because our own WM_PAINT will never be
  257.  *  called.
  258.  *
  259.  * Parameters:
  260.  *  fHatch          BOOL indicating to show (TRUE) or hide (FALSE)
  261.                     the hatching.
  262.  *
  263.  * Return Value:
  264.  *  None
  265.  */
  266.  
  267. void CHatchWin::ShowHatch(BOOL fHatch)
  268.     {
  269.     /*
  270.      * All we have to do is set the border to zero and
  271.      * call SetRects again with the last rectangles the
  272.      * child sent to us.
  273.      */
  274.     m_dBorder=fHatch ? m_dBorderOrg : 0;
  275.     RectsSet(&m_rcPos, &m_rcClip);
  276.     return;
  277.     }
  278.  
  279.  
  280.  
  281. /*
  282.  * HatchWndProc
  283.  *
  284.  * Purpose:
  285.  *  Standard window procedure for the Hatch Window
  286.  */
  287.  
  288. LRESULT APIENTRY HatchWndProc(HWND hWnd, UINT iMsg
  289.     , WPARAM wParam, LPARAM lParam)
  290.     {
  291.     PCHatchWin  phw;
  292.     HDC         hDC;
  293.     PAINTSTRUCT ps;
  294.     RECT        rc;
  295.             
  296.     phw=(PCHatchWin)GetWindowLong(hWnd, HWWL_STRUCTURE);
  297.  
  298.     switch (iMsg)
  299.         {
  300.         case WM_CREATE:
  301.             phw=(PCHatchWin)((LPCREATESTRUCT)lParam)->lpCreateParams;
  302.             SetWindowLong(hWnd, HWWL_STRUCTURE, (LONG)phw);
  303.             break;
  304.  
  305.  
  306.         case WM_PAINT: 
  307.             hDC=BeginPaint(hWnd, &ps);
  308.             GetClientRect(hWnd, &rc);
  309.  
  310.             //Always draw the hatching.
  311.             DrawShading(&rc, hDC, phw->m_dBorder);
  312.  
  313.             EndPaint(hWnd, &ps);
  314.             break;
  315.  
  316.  
  317.         case WM_SETFOCUS:
  318.             //We need this since the container will SetFocus to us.
  319.             if (NULL!=phw->m_hWndKid)
  320.                 SetFocus(phw->m_hWndKid);
  321.  
  322.             break;
  323.  
  324.  
  325.         case WM_LBUTTONDBLCLK:
  326.             /*
  327.              * If the double click was within m_dBorder of an
  328.              * edge, send the HWN_BORDERDOUBLECLICKED notification.
  329.              *
  330.              * Because we're always sized just larger than our child
  331.              * window by the border width, we can only *get* this
  332.              * message when the mouse is on the border.  So we can
  333.              * just send the notification.
  334.              */
  335.  
  336.             if (NULL!=phw->m_hWndAssociate)
  337.                 {
  338.                 SendCommand(phw->m_hWndAssociate, phw->m_uID
  339.                     , HWN_BORDERDOUBLECLICKED, hWnd);
  340.                 }
  341.  
  342.             break;
  343.  
  344.  
  345.         default:
  346.             return DefWindowProc(hWnd, iMsg, wParam, lParam);
  347.         }
  348.     
  349.     return 0L;
  350.     }
  351.  
  352.  
  353.  
  354. /*
  355.  * DrawShading
  356.  *
  357.  * Purpose:
  358.  *  Draw a hatch border ourside the rectable given.
  359.  *
  360.  * Parameters:
  361.  *  prc             LPRECT containing the rectangle.
  362.  *  hDC             HDC on which to draw.
  363.  *  cWidth          UINT width of the border to draw.  Ignored
  364.  *                  if dwFlags has UI_SHADE_FULLRECT.
  365.  *
  366.  * Return Value:
  367.  *  None
  368.  */
  369.  
  370. void DrawShading(LPRECT prc, HDC hDC, UINT cWidth)
  371.     {
  372.     HBRUSH      hBR;
  373.     HBRUSH      hBROld;
  374.     HBITMAP     hBM;
  375.     RECT        rc;
  376.     UINT        cx, cy;
  377.     COLORREF    crText;
  378.     COLORREF    crBk;
  379.     const DWORD dwROP=0x00A000C9L;  //DPa
  380.  
  381.     if (NULL==prc || NULL==hDC)
  382.         return;
  383.  
  384.     hBM=CreateBitmap(8, 8, 1, 1, g_wHatchBmp);
  385.     hBR=CreatePatternBrush(hBM);
  386.     hBROld=(HBRUSH)SelectObject(hDC, hBR);
  387.  
  388.     rc=*prc;
  389.     cx=rc.right-rc.left;
  390.     cy=rc.bottom-rc.top;
  391.  
  392.     crText=SetTextColor(hDC, RGB(255, 255, 255));
  393.     crBk=SetBkColor(hDC, RGB(0, 0, 0));
  394.     PatBlt(hDC, rc.left, rc.top, cx, cWidth, dwROP);
  395.     PatBlt(hDC, rc.left, rc.top, cWidth, cy, dwROP);
  396.     PatBlt(hDC, rc.right-cWidth, rc.top, cWidth, cy, dwROP);
  397.     PatBlt(hDC, rc.left, rc.bottom-cWidth, cx, cWidth, dwROP);
  398.  
  399.     SetTextColor(hDC, crText);
  400.     SetBkColor(hDC, crBk);
  401.     SelectObject(hDC, hBROld);
  402.     DeleteObject(hBR);
  403.     DeleteObject(hBM);
  404.  
  405.     return;
  406.     }
  407.