home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / BOCOLE.PAK / BHATCH.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  26KB  |  773 lines

  1. //
  2. //**************************************************************************
  3. //
  4. // Bhatch.cpp - An implementation of the hatched border around inplace
  5. //              active windows.
  6. //
  7. // Modifications to OLE2UI version:
  8. //              - C++ version
  9. //              - removed restriction that parent must be non-null in CreateHatchWindow
  10. //              - changed window from a child to a popup to allow null parent
  11. //              - "extra bytes" removed in favor of member data
  12. //              - added Paint() and InitWidth() to unclutter wnd proc
  13. //              - added hit testing and correct cursors for handles
  14. //              - added resizing for handles
  15. //              - added NegotiateSize() to mediate inplace size negotiations between
  16. //                the container and the server
  17. //
  18. // Copyright (c) 1993,94 by Borland International, Inc. All rights reserved
  19. //
  20. //**************************************************************************
  21.  
  22. #include "BOle.h"
  23.  
  24. // #define STRICT  1
  25. #define STRICT
  26. #include "OLE2UI.h"
  27. #include "BHatch.h"
  28.  
  29. // class name of hatch window
  30. #ifdef ANSI
  31.   #define CLASS_HATCH "BOle Hatch Window"
  32. #else
  33.   #define CLASS_HATCH OLESTR("BOle Hatch Window")
  34. #endif
  35.  
  36. // local function prototypes
  37. LRESULT FAR PASCAL EXPORT BOleHatchWndProc (HWND, UINT, WPARAM, LPARAM);
  38.  
  39. // static initializer
  40. UINT BOleHatchWindow::hatchWidth = 0;
  41.  
  42. // global functions
  43. void SetRectExt (LPRECT r, UINT x, UINT y, UINT extent)
  44. {
  45.     r->left = x;
  46.     r->top = y;
  47.     r->right = x + extent;
  48.     r->bottom = y + extent;
  49. }
  50.  
  51. BOleHatchWindow::BOleHatchWindow(HWND hWndParent, HINSTANCE hInst, BOleSite *p)
  52. {
  53.   pBack = p; // assign BOleSite
  54. #ifdef ANSI
  55.   hWndHatch = ::CreateWindowExA(
  56.     0,
  57.     CLASS_HATCH,    // Class name
  58.     "Hatch Window", // Window name
  59.     WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  60.     0, 0, 0, 0,
  61.     GetDesktopWindow(),
  62.     (HMENU)NULL,
  63.     hInst,
  64.     this
  65.   );
  66. #else
  67.   hWndHatch = ::CreateWindowEx(
  68.     0,
  69.     CLASS_HATCH,    // Class name
  70.     OLESTR("Hatch Window"), // Window name
  71.     WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  72.     0, 0, 0, 0,
  73.     GetDesktopWindow(),
  74.     (HMENU)NULL,
  75.     hInst,
  76.     this
  77.   );
  78. #endif
  79.  
  80.   hatchRect.left = hatchRect.top = hatchRect.bottom = hatchRect.right = 0;
  81.   MoveRect.left = MoveRect.top = MoveRect.bottom = MoveRect.right = 0;
  82.   nClippedFlag = 0;
  83.   pSite = NULL;
  84.   fInMouseDown = FALSE;
  85. }
  86.  
  87. //***************************************************************************
  88. // Destructor: ~BOleHatchWindow
  89. //
  90. // Purpose:
  91. //              Public destructor to destroy the hWnd
  92. //
  93. //***************************************************************************
  94. BOleHatchWindow::~BOleHatchWindow ()
  95. {
  96.     if (hWndHatch)
  97.         ::DestroyWindow (hWndHatch);
  98. }
  99.  
  100. //***************************************************************************
  101. // Static member function: Register
  102. //
  103. // Purpose:
  104. //      Register the hatch window
  105. //
  106. // Parameters:
  107. //      hInst                   Process instance
  108. //
  109. // Return Value:
  110. //      TRUE                    if successful
  111. //      FALSE                   if failed
  112. //
  113. //***************************************************************************
  114. BOOL BOleHatchWindow::Register (HINSTANCE hInst)
  115. {
  116. #ifdef ANSI
  117.   WNDCLASSA wc;
  118. #else
  119.   WNDCLASS wc;
  120. #endif
  121.  
  122.   // Register Hatch Window Class
  123.   wc.style = CS_BYTEALIGNWINDOW;
  124.   wc.lpfnWndProc = BOleHatchWndProc;
  125.   wc.cbClsExtra = 0;
  126.   wc.cbWndExtra = sizeof(BOleHatchWindow*);    // 'this' in extra bytes
  127.   wc.hInstance = hInst;
  128.   wc.hIcon = NULL;
  129.   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  130.   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  131.   wc.lpszMenuName = NULL;
  132.   wc.lpszClassName = CLASS_HATCH;
  133.  
  134. #ifdef ANSI
  135.   if (!::RegisterClassA(&wc))
  136. #else
  137.   if (!::RegisterClass(&wc))
  138. #endif
  139.     return FALSE;
  140.   else
  141.     return TRUE;
  142. }
  143.  
  144. //***************************************************************************
  145. // Static member function: InitWidth
  146. //
  147. // Purpose:
  148. //              Initialize hatch border with from WIN.INI
  149. //
  150. //***************************************************************************
  151. void BOleHatchWindow::InitWidth ()
  152. {
  153. #ifdef ANSI
  154.   hatchWidth = GetProfileIntA("windows", "oleinplaceborderwidth",
  155.                   DEFAULT_HATCHBORDER_WIDTH);
  156. #else
  157.   hatchWidth = GetProfileInt(OLESTR("windows"), OLESTR("oleinplaceborderwidth"),
  158.                  DEFAULT_HATCHBORDER_WIDTH);
  159. #endif
  160. }
  161.  
  162. //***************************************************************************
  163. // Member function: GetWidth
  164. //
  165. // Purpose:
  166. //      Get width of hatch border
  167. //
  168. // Parameters:          None
  169. //
  170. // Return Value:
  171. //    UINT                                      width of the hatch border
  172. //***************************************************************************
  173. UINT BOleHatchWindow::GetWidth ()
  174. {
  175.     if (!::IsWindow(hWndHatch))
  176.         return 0;
  177.  
  178.     return hatchWidth;
  179. }
  180.  
  181. //****************************************************************
  182. // window messages related member functions
  183. //
  184. // Purpose:
  185. //              Window Procedure dispatches all messages here.
  186. //      Each member functions got the message name.
  187. //              Do messages processing here.
  188. //              Refer to windows help to get information about messages
  189. //
  190. //****************************************************************
  191.  
  192. //****************************************************************
  193. // Member function: wmCreate
  194. //
  195. // Parameters:
  196. //                      LPCREATESTRUCT  struct containing information about the window
  197. //                                                                      to be created. Not used
  198. //
  199. // Return Value:
  200. //                      LRESULT                         0L to continue creation process
  201. //
  202. //****************************************************************
  203. #ifdef ANSI
  204. LRESULT BOleHatchWindow::wmCreate (LPCREATESTRUCTA)
  205. #else
  206. LRESULT BOleHatchWindow::wmCreate (LPCREATESTRUCT)
  207. #endif
  208. {
  209.     BOleHatchWindow::InitWidth ();
  210.     return 0L;
  211. }
  212.  
  213. //***************************************************************************
  214. // Member function: wmPaint
  215. //
  216. // Purpose:
  217. //              Draw hatched border and handles
  218. //
  219. // Parameters:                          None
  220. //
  221. // Return Value:
  222. //                      LRESULT                         0L
  223. //
  224. //***************************************************************************
  225. LRESULT BOleHatchWindow::wmPaint ()
  226. {
  227.     HDC hDC;
  228.     PAINTSTRUCT ps;
  229.     RECT rcHatchRect;
  230.  
  231.     hDC = ::BeginPaint(hWndHatch, &ps);
  232.     // get hatchRect to paint hatch border
  233.     rcHatchRect = hatchRect;
  234.     SetRect((LPRECT)&rcHatchRect,rcHatchRect.left, rcHatchRect.top,
  235.                                 rcHatchRect.right,
  236.                                     rcHatchRect.bottom);
  237.     OleUIDrawShading(&rcHatchRect, hDC, OLEUI_SHADE_BORDERIN,
  238.             hatchWidth);
  239.     // get the real visible rect to draw handles
  240.     GetWindowRect(hWndHatch, (LPRECT)&rcHatchRect);
  241.     SetRect((LPRECT)&rcHatchRect,0, 0, rcHatchRect.right-rcHatchRect.left,
  242.                                     rcHatchRect.bottom-rcHatchRect.top);
  243.     ::InflateRect ((LPRECT)&rcHatchRect, -hatchWidth, -hatchWidth);
  244.     OleUIDrawHandles (&rcHatchRect, hDC, OLEUI_HANDLES_OUTSIDE,
  245.         hatchWidth+1, TRUE);
  246.     ::EndPaint (hWndHatch, &ps);
  247.  
  248.     return 0L;
  249. }
  250.  
  251. //****************************************************************
  252. // Member function: wmNCHitTest
  253. //
  254. // Purpose:
  255. //                      Find out which handle the cursor is over
  256. //
  257. // Parameters:
  258. //       LPPOINT                mouse position
  259. //
  260. // Return Value:
  261. //       UINT                   a value indicating the position of the cursor
  262. //
  263. //****************************************************************
  264. UINT BOleHatchWindow::wmNCHitTest (LPPOINT lpPoint)
  265. {
  266.     RECT handleRect;
  267.     RECT rc; // contain hatch window rect
  268.  
  269.     // we want lpPoint to be in client coordinates
  270.     ::ScreenToClient (hWndHatch, lpPoint);
  271.  
  272.     GetWindowRect(hWndHatch, (LPRECT)&rc);
  273.     SetRect((LPRECT)&rc,0,0,rc.right-rc.left,rc.bottom-rc.top);
  274.  
  275.     SetRectExt (&handleRect, rc.left, rc.top, hatchWidth + 1);
  276.     if (::PtInRect(&handleRect, *lpPoint))  return HTTOPLEFT;
  277.  
  278.     SetRectExt (&handleRect, rc.left, (rc.top+rc.bottom-hatchWidth + 1)/2, hatchWidth + 1);
  279.     if (::PtInRect(&handleRect, *lpPoint))  return HTLEFT;
  280.  
  281.     SetRectExt (&handleRect, rc.left, rc.bottom - hatchWidth + 1, hatchWidth + 1);
  282.     if (::PtInRect(&handleRect, *lpPoint))  return HTBOTTOMLEFT;
  283.  
  284.     SetRectExt (&handleRect, (rc.left+rc.right-hatchWidth + 1)/2, rc.top, hatchWidth + 1);
  285.     if (::PtInRect(&handleRect, *lpPoint))  return HTTOP;
  286.  
  287.     SetRectExt (&handleRect, (rc.left+rc.right-hatchWidth + 1)/2, rc.bottom - hatchWidth + 1, hatchWidth + 1);
  288.     if (::PtInRect(&handleRect, *lpPoint))  return HTBOTTOM;
  289.  
  290.     SetRectExt (&handleRect, rc.right-hatchWidth + 1, rc.top, hatchWidth + 1);
  291.     if (::PtInRect(&handleRect, *lpPoint))  return HTTOPRIGHT;
  292.  
  293.     SetRectExt (&handleRect, rc.right-hatchWidth + 1, (rc.top+rc.bottom-hatchWidth + 1)/2, hatchWidth + 1);
  294.     if (::PtInRect(&handleRect, *lpPoint))  return HTRIGHT;
  295.  
  296.     SetRectExt (&handleRect, rc.right-hatchWidth + 1, rc.bottom-hatchWidth + 1, hatchWidth + 1);
  297.     if (::PtInRect(&handleRect, *lpPoint))  return HTBOTTOMRIGHT;
  298.  
  299.     // If we've gotten this far, the cursor is not over a handle, but it
  300.     // is over the hatch window (because we got the message). This means
  301.     // the cursor is over the hatched border. It can't be over our client
  302.     // area because the server object takes up the client area.
  303.     //
  304.     // So, by telling Windows that the cursor is over the caption bar, we
  305.     // can piggy-back on Windows' code for dragging windows around.
  306.     //
  307.     return HTCAPTION;
  308. }
  309.  
  310. //****************************************************************
  311. // Member function: wmSetCursor
  312. //
  313. //      Purpose:
  314. //                      Set the cursor bitmap to match the handle it's over.
  315. //
  316. // Parameters:
  317. //                      HWND                    handle of the window with the cursor
  318. //       UINT                   only used. Contains the value returned from wmNCHitTest
  319. //                      UINT        Mouse message number
  320. //
  321. // Return Value:
  322. //                      LRESULT         TRUE, to stop further processing
  323. //
  324. //****************************************************************
  325. LRESULT BOleHatchWindow::wmSetCursor (HWND, UINT hitTestCode, UINT)
  326. {
  327.  
  328.     switch (hitTestCode) {
  329.         case HTTOPLEFT:
  330.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZENWSE)));
  331.             break;
  332.         case HTLEFT:
  333.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
  334.             break;
  335.         case HTBOTTOMLEFT:
  336.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZENESW)));
  337.             break;
  338.         case HTTOP:
  339.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZENS)));
  340.             break;
  341.         case HTBOTTOM:
  342.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZENS)));
  343.             break;
  344.         case HTTOPRIGHT:
  345.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZENESW)));
  346.             break;
  347.         case HTRIGHT:
  348.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
  349.             break;
  350.         case HTBOTTOMRIGHT:
  351.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZENWSE)));
  352.             break;
  353.         default:
  354.             ::SetCursor (::LoadCursor (NULL, MAKEINTRESOURCE(IDC_ARROW)));
  355.     }
  356.  
  357.     return (LRESULT)TRUE;
  358. }
  359.  
  360. //****************************************************************
  361. // Member function: wmMouseActivate
  362. //
  363. // Parameters:
  364. //                      HWND                    handle of the top level parent. Not used
  365. //       UINT                   hit test code. Not used
  366. //                      UINT        Mouse message identifier. Not used
  367. //
  368. // Return Value:
  369. //                      UINT                    MA_NOACTIVATE does not activate the window
  370. //
  371. //****************************************************************
  372. UINT BOleHatchWindow::wmMouseActivate (HWND, UINT, UINT)
  373. {
  374.     return MA_NOACTIVATE;
  375. }
  376.  
  377. //****************************************************************
  378. // Member function: wmNCLButtonDown
  379. //
  380. // Parameters:
  381. //                      UINT            hit test code as returned from WM_NCHITTEST
  382. //                      LPOINT                  cursor coordinates
  383. //
  384. // Return Value:
  385. //                      LRESULT         let it process by DefWindowProc
  386. //
  387. //****************************************************************
  388. LRESULT BOleHatchWindow::wmNCLButtonDown (UINT nTestCode, LPPOINT lpPoint)
  389. {
  390.     // first resize window if needed
  391.     if (nClippedFlag & CLIPPED) {
  392.         RECT WinRect;
  393.         // get the real (visible) window in client coordinates
  394.         GetWindowRect( hWndHatch, (LPRECT)&WinRect);
  395.         ScreenToClient( GetParent( hWndHatch), (LPPOINT)&WinRect);
  396.  
  397.         // if clipped left or top hatchRect adjust top and/or left
  398.         if (nClippedFlag & CLIPPED_LEFT)
  399.             WinRect.left += hatchRect.left;
  400.         if (nClippedFlag & CLIPPED_TOP)
  401.             WinRect.top += hatchRect.top;
  402.         // move window
  403.         MoveWindow( hWndHatch, WinRect.left, WinRect.top,
  404.                             hatchRect.right - hatchRect.left,
  405.                             hatchRect.bottom - hatchRect.top,
  406.                             FALSE);
  407.     }
  408.  
  409.     // set flag indicating the user is moving the window and initiating
  410.     // all space negotiation procedure
  411.     fInMouseDown=TRUE;
  412.  
  413.     return ::DefWindowProc (hWndHatch, WM_NCLBUTTONDOWN, nTestCode, *((long *)lpPoint));
  414. }
  415.  
  416. //****************************************************************
  417. // Member function: wmGetMinMaxInfo
  418. //
  419. // Parameters:
  420. //                      LPMINMAXINFO    struct containing resizing information
  421. //
  422. // Return Value:
  423. //                      LRESULT                 0L when processing this message
  424. //
  425. //****************************************************************
  426. LRESULT BOleHatchWindow::wmGetMinMaxInfo (MINMAXINFO* pMMI)
  427. {
  428.     int minWidth = (GetWidth() * 2) + 15;
  429.     pMMI->ptMinTrackSize.x = minWidth;
  430.     pMMI->ptMinTrackSize.y = minWidth;
  431.     return 0L;
  432. }
  433.  
  434. //****************************************************************
  435. // Member function: wmWindowPosChanging
  436. //
  437. // Purpose:
  438. //       Call negotiate size to activate the space negotiation
  439. //                      procedure and, in case, changes the WINDOWPOS values
  440. //                      so to accomplish the new size
  441. //
  442. // Parameters:
  443. //       LPWINDOWPOS    structure containing information about
  444. //                                                      resizing values
  445. //
  446. // Return Value:
  447. //                      LRESULT
  448. //
  449. //****************************************************************
  450. LRESULT BOleHatchWindow::wmWindowPosChanging (LPWINDOWPOS pWP)
  451. {
  452.           if (hWndHatch == GetCapture()) {
  453.                 RECT TempRect;
  454.                 fInMouseDown = TRUE;
  455.                 ::DefWindowProc (hWndHatch, WM_WINDOWPOSCHANGING, 0, (DWORD)(LPVOID)pWP);
  456.                 ::InvalidateRect(hWndHatch, NULL, FALSE);
  457.                 ::CopyRect((LPRECT)&TempRect, (LPRECT)&hatchRect);
  458.                 ::InflateRect((LPRECT)&TempRect, -hatchWidth, -hatchWidth);
  459.                 ::ValidateRect(hWndHatch, (LPRECT)&TempRect);
  460.                 return 0L;
  461.           }
  462.  
  463.           if (fInMouseDown) {
  464.                      int minWidth = (GetWidth() * 2) + 15;
  465.                      if (pWP->cx < minWidth) {
  466.                                 pWP->cx = minWidth;
  467.                      }
  468.                      if (pWP->cy < minWidth) {
  469.                                 pWP->cy = minWidth;
  470.                      }
  471.                      NegotiateSize (pWP);
  472.                      if (nClippedFlag & CLIPPED) {
  473.                                 pWP->x = MoveRect.left;
  474.                                 pWP->y = MoveRect.top;
  475.                                 pWP->cx = MoveRect.right;
  476.                                 pWP->cy = MoveRect.bottom;
  477.                                 pWP->flags = 0;
  478.                      }
  479.                      ::InvalidateRect(hWndHatch, NULL, TRUE);
  480.                      fInMouseDown = FALSE;
  481.                      return 0L;
  482.           }
  483.  
  484.             return ::DefWindowProc (hWndHatch, WM_WINDOWPOSCHANGING, 0, (DWORD)(LPVOID)pWP);
  485. }
  486.  
  487. //***************************************************************************
  488. // Member function: Show
  489. //
  490. // Purpose:
  491. //              Show or hide the hatch window; provide access to the site
  492. //
  493. // Parameters:
  494. //              BOOL                                    TRUE to show the hatch window, FALSE to hide it
  495. //              LPOLEINPLACESITE        Pointer to the in place site, which is used to
  496. //                                              negotiate new size when a handle is dragged
  497. //
  498. //***************************************************************************
  499. void BOleHatchWindow::Show (BOOL fShow, LPOLEINPLACESITE pS)
  500. {
  501.     pSite = pS;
  502.     ::ShowWindow (hWndHatch, fShow ? SW_SHOW : SW_HIDE);
  503. }
  504.  
  505. //***************************************************************************
  506. //      Member function: SetSize
  507. //
  508. // Purpose:
  509. //              Move/size the HatchWindow correctly given the rect required by the
  510. //              in-place server object window and the lprcClipRect imposed by the
  511. //              in-place container. both rect's are expressed in the client coord.
  512. //              of the in-place container's window (which is the parent of the
  513. //              HatchWindow). When fInMouseDown is TRUE must not use MoveWindow
  514. //                      but change the values in the WINDOWPOS struct inside the
  515. //                      WM_WINDOWPOSCHANGING message (it seems Windows code is not re-entrant
  516. //       there)
  517. //
  518. //              OLE2NOTE: the in-place server must honor the lprcClipRect specified
  519. //              by its in-place container. it must NOT draw outside of the ClipRect.
  520. //              in order to achieve this, the hatch window is sized to be
  521. //              exactly the size that should be visible (rcVisRect). the
  522. //              rcVisRect is defined as the intersection of the full size of
  523. //              the HatchRect window and the lprcClipRect.
  524. //              the ClipRect could infact clip the HatchRect on the
  525. //              right/bottom and/or on the top/left. if it is clipped on the
  526. //              right/bottom then it is sufficient to simply resize the hatch
  527. //              window. but if the HatchRect is clipped on the top/left then
  528. //              in-place server document window (child of HatchWindow) must be moved
  529. //              by the delta that was clipped. the window origin of the
  530. //              in-place server window will then have negative coordinates relative
  531. //              to its parent HatchWindow.
  532. //
  533. // Parameters:
  534. //              LPRECT                  full size of in-place server object window
  535. //              LPRECT                  clipping rect imposed by in-place container
  536. //              LPPOINT         offset required to position in-place server object
  537. //                      window properly. caller should call:
  538. //                                                              OffsetRect(&rcObjRect,lpptOffset->x,lpptOffset->y)
  539. //
  540. //      Return Value:                   None
  541. //
  542. //***************************************************************************
  543. void BOleHatchWindow::SetSize(
  544.         LPRECT      lprcIPObjRect,
  545.         LPRECT      lprcClipRect,
  546.         LPPOINT     lpptOffset)
  547. {
  548.  
  549.     RECT        rcHatchRect;
  550.     RECT        rcVisRect;
  551.     UINT        uHatchWidth;
  552.     POINT       ptOffset;
  553.  
  554.     if (!::IsWindow(hWndHatch))
  555.         return;
  556.  
  557.     rcHatchRect = *lprcIPObjRect;
  558.     uHatchWidth = GetWidth();
  559.     ::InflateRect((LPRECT)&rcHatchRect, uHatchWidth + 1, uHatchWidth + 1);
  560.  
  561.     // find the intersection between hatch (server) window and
  562.     // clipping area (area where the object is allowed to paint)
  563.     ::IntersectRect (&rcVisRect, &rcHatchRect, lprcClipRect);
  564.  
  565.     // move the hatch window at the intersection rectangle if you are not
  566.     // dragging the window around
  567.     if (!fInMouseDown) {
  568.         ::MoveWindow(
  569.                 hWndHatch,
  570.                 rcVisRect.left,
  571.                 rcVisRect.top,
  572.                 rcVisRect.right-rcVisRect.left,
  573.                 rcVisRect.bottom-rcVisRect.top,
  574.                 TRUE    /* fRepaint */
  575.         );
  576.         ::InvalidateRect(hWndHatch, NULL, TRUE);
  577.     }
  578.     else {
  579.         // this information will be used in the WM_WINDOWPOSCHANGING
  580.         // message to change WINDOWPOS structure values
  581.                      ::SetRect(&MoveRect, rcVisRect.left, rcVisRect.top,
  582.                                                                 rcVisRect.right-rcVisRect.left,
  583.                                                                                      rcVisRect.bottom-rcVisRect.top);
  584.           }
  585.  
  586.  
  587.     nClippedFlag = 0; // clear clipped flag
  588.     // store clipping information
  589.     if (!(::EqualRect(&rcVisRect,&rcHatchRect))) {
  590.         nClippedFlag |= CLIPPED;
  591.         if (rcVisRect.left != rcHatchRect.left ) {
  592.             nClippedFlag |= CLIPPED_LEFT;
  593.         }
  594.         if (rcVisRect.top != rcHatchRect.top) {
  595.             nClippedFlag |= CLIPPED_TOP;
  596.         }
  597.     }
  598.  
  599.     // convert the rcHatchRect into the client coordinate system of the
  600.     // HatchWindow itself
  601.     ptOffset.x = - rcVisRect.left;
  602.     ptOffset.y = - rcVisRect.top;
  603.     ::OffsetRect(&rcHatchRect, ptOffset.x, ptOffset.y);
  604.     hatchRect = rcHatchRect;
  605.  
  606.     // calculate offset required to position in-place
  607.     // server doc window (output value)
  608.     lpptOffset->x = ptOffset.x;
  609.     lpptOffset->y = ptOffset.y;
  610.  
  611.     return;
  612. }
  613.  
  614. //***************************************************************************
  615. // Member function: NegotiateSize
  616. //
  617. // Purpose:
  618. //              When the user drags a handle of the hatch window, Windows attempts
  619. //              to resize the window. This routine catches that attempt and validates
  620. //              it with the client. We don't need to validate it with the server
  621. //              because the client will call the server back from OnPosRectChange to
  622. //              BOleSite::SetObjectRects.
  623. //
  624. //      Parameters:
  625. //              WINDOWPOS*                              Pointer to Windows' WINDOWPOS structure
  626. //
  627. //***************************************************************************
  628. void BOleHatchWindow::NegotiateSize (WINDOWPOS *pwp)
  629. {
  630.     RECT rcWnd; // The pre-resize size of the hatch window
  631.  
  632.     // As an optimization, get the current size of the hatch window
  633.     // and bail out if it's the same as the new size. This saves the
  634.     // potentially expensive renegotiation.
  635.     //
  636.     ::GetWindowRect (hWndHatch, &rcWnd);
  637.     HWND parent = ::GetParent (hWndHatch);
  638.     ::ScreenToClient (parent, (LPPOINT) &rcWnd.left);
  639.     ::ScreenToClient (parent, (LPPOINT) &rcWnd.right);
  640.           //if ( rcWnd.left == pwp->x && rcWnd.top == pwp->y &&
  641.           //        (rcWnd.bottom - rcWnd.top == pwp->cy) &&
  642.           //        (rcWnd.right - rcWnd.left == pwp->cx))
  643.     //        return;
  644.  
  645.     // Ask the client to resize to the new size of the window
  646.     //
  647.     RECT rcNew;
  648.  
  649.     // The new size of the server's inplace window
  650.     ::SetRect (&rcNew, pwp->x, pwp->y, pwp->x + pwp->cx, pwp->y + pwp->cy);
  651.     ::InflateRect (&rcNew, -(hatchWidth + 1), -(hatchWidth + 1));
  652.     if (pSite) {
  653.         // Ask the server to show more/less of object
  654.         //
  655.         if (!SUCCEEDED(pBack->SetSiteRect(&rcNew))) {
  656.             SIZE size;
  657.             // undo resize of the server
  658.             size.cx = rcWnd.right - rcWnd.left;
  659.             size.cy = rcWnd.bottom - rcWnd.top;
  660.             pBack->pPart->SetPartSize(&size);
  661.  
  662.             // If the client refuses the new size, give the pre-resize
  663.             // size of the hatch window, back to Windows through the WINDOWPOS
  664.             //
  665.             pwp->x = rcWnd.left;
  666.             pwp->y = rcWnd.top;
  667.             pwp->cx = rcWnd.right - rcWnd.left;
  668.             pwp->cy = rcWnd.bottom - rcWnd.top;
  669.         }
  670.     }
  671. }
  672.  
  673. //***************************************************************************
  674. //      BOleHatchWndProc
  675. //
  676. // Purpose:
  677. //                      WndProc for hatch window
  678. //
  679. // Parameters:
  680. //                      hWnd
  681. //                      Message
  682. //                      wParam
  683. //                      lParam
  684. //
  685. // Return Value:
  686. //                      message dependent
  687. //***************************************************************************
  688. LRESULT FAR PASCAL EXPORT BOleHatchWndProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
  689. {
  690. #ifdef ANSI
  691.   BOleHatchWindow *pHW  = (BOleHatchWindow*) ::GetWindowLongA(hWnd, 0);
  692. #else
  693.   BOleHatchWindow *pHW  = (BOleHatchWindow*) ::GetWindowLong(hWnd, 0);
  694. #endif
  695.   // if pHW is NULL, assign it if WM_NCCREATE otherwise
  696.   // return DefWindowProc
  697.   if (!pHW) {
  698.     if (Message==WM_NCCREATE) {
  699. #ifdef ANSI
  700.       CREATESTRUCTA FAR* lpcs = (CREATESTRUCTA FAR*)lParam;
  701.       ::SetWindowLongA(hWnd, 0, (DWORD)(LPVOID)(lpcs->lpCreateParams));
  702. #else
  703.       CREATESTRUCT FAR* lpcs = (CREATESTRUCT FAR*)lParam;
  704.       ::SetWindowLong(hWnd, 0, (DWORD)(LPVOID)(lpcs->lpCreateParams));
  705. #endif
  706.     }
  707.     return ::DefWindowProc (hWnd, Message, wParam, lParam);
  708.   }
  709.  
  710.   switch (Message) {
  711.     case WM_CREATE:
  712. #ifdef ANSI
  713.       return pHW->wmCreate((LPCREATESTRUCTA)lParam);
  714. #else
  715.       return pHW->wmCreate((LPCREATESTRUCT)lParam);
  716. #endif
  717.  
  718.     case WM_PAINT:
  719.       return pHW->wmPaint ();
  720.  
  721.     case WM_GETMINMAXINFO:
  722.       return pHW->wmGetMinMaxInfo((MINMAXINFO*)lParam);
  723.  
  724.     // The cursor setting strategy here is to catch the WM_NCHITTEST
  725.     // first to figure out which hit-test area the cursor is over.
  726.     // Then Windows calls us back with WM_SETCURSOR so we can make
  727.     // the cursor the correct shape for that hit-test area.
  728.     //
  729.     case WM_NCHITTEST:
  730.       if (pHW) {
  731.     POINT pt;
  732.     pt.x = LOWORD(lParam);
  733.     pt.y = HIWORD(lParam);
  734.     return pHW->wmNCHitTest ((LPPOINT) &pt);
  735.       }
  736.  
  737.     // Any window that is used during in-place activation
  738.     // must handle the WM_SETCURSOR message or else the cursor
  739.     // of the in-place parent will be used. if WM_SETCURSOR is
  740.     // not handled, then DefWindowProc sends the message to the
  741.     // window's parent.
  742.     //
  743.     case WM_SETCURSOR:
  744.       return pHW->wmSetCursor((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  745.  
  746.     case WM_MOUSEACTIVATE:
  747.       return pHW->wmMouseActivate((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  748.  
  749.     // The window move/resize strategy here is:
  750.     // - Keep control so we can allow the OLE2 client app to refuse
  751.     //   the new dimensions. Don't wait until the window has already
  752.     //   been moved and then move it back.
  753.     // - In order to keep control, we catch the WM_WINDOWPOSCHANGING
  754.     //   and set appropriate flags in the WINDOWPOS struct.
  755.     // - Since WM_WINDOWPOSCHANGING is sent for both user-interface
  756.     //   initiated actions and for ::MoveWindow-initiated changes, we
  757.     //   keep a flag which prevents changes during mousedowns
  758.     //
  759.     case WM_NCLBUTTONDOWN:
  760.       return pHW->wmNCLButtonDown(wParam, (LPPOINT)&lParam);
  761.  
  762.     case WM_WINDOWPOSCHANGING:
  763.       return pHW->wmWindowPosChanging((WINDOWPOS*) lParam);
  764.  
  765.     default:
  766.       return ::DefWindowProc (hWnd, Message, wParam, lParam);
  767.   }
  768. }
  769.  
  770.  
  771.  
  772.  
  773.