| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| #if defined(_MSC_VER) && (_MSC_VER > 1310) |
| #pragma warning(disable : 4917 4555) |
| #endif |
| |
| #include "docholder.hxx" |
| #include "syswinwrapper.hxx" |
| |
| /* |
| * CWindow::CWindow |
| * CWindow::~CWindow |
| * |
| * Constructor Parameters: |
| * hInst HINSTANCE of the task owning us. |
| */ |
| |
| |
| using namespace winwrap; |
| |
| |
| #define HWWL_STRUCTURE 0 |
| |
| //Notification codes for WM_COMMAND messages |
| #define HWN_BORDERDOUBLECLICKED 1 |
| #define CBHATCHWNDEXTRA (sizeof(LONG)) |
| #define SZCLASSHATCHWIN TEXT("hatchwin") |
| #define SendCommand(hWnd, wID, wCode, hControl) \ |
| SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(wID, wCode) \ |
| , (LPARAM)hControl) |
| |
| |
| typedef CHatchWin *PCHatchWin; |
| |
| |
| void DrawShading(LPRECT prc, HDC hDC, UINT cWidth); |
| |
| |
| |
| winwrap::CWindow::CWindow(HINSTANCE hInst) |
| { |
| m_hInst=hInst; |
| m_hWnd=NULL; |
| return; |
| } |
| |
| winwrap::CWindow::~CWindow(void) |
| { |
| if (IsWindow(m_hWnd)) |
| DestroyWindow(m_hWnd); |
| |
| return; |
| } |
| |
| |
| |
| /* |
| * CWindow::Window |
| * |
| * Purpose: |
| * Returns the window handle associated with this object. |
| * |
| * Return Value: |
| * HWND Window handle for this object |
| */ |
| |
| HWND winwrap::CWindow::Window(void) |
| { |
| return m_hWnd; |
| } |
| |
| |
| |
| /* |
| * CWindow::Instance |
| * |
| * Purpose: |
| * Returns the instance handle associated with this object. |
| * |
| * Return Value: |
| * HINSTANCE Instance handle of the module stored here. |
| */ |
| |
| HINSTANCE winwrap::CWindow::Instance(void) |
| { |
| return m_hInst; |
| } |
| |
| |
| |
| |
| |
| //Hatch pattern brush bits |
| static WORD g_wHatchBmp[]={0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88}; |
| |
| // void DrawShading(LPRECT, HDC, UINT); |
| |
| |
| /* |
| * HatchWindowRegister |
| * |
| * Purpose: |
| * Registers the hatch window class for use with CHatchWin. |
| * |
| * Parameters: |
| * hInst HINSTANCE under which to register. |
| * |
| * Return Value: |
| * BOOL TRUE if successful, FALSE otherwise. |
| */ |
| |
| BOOL winwrap::HatchWindowRegister(HINSTANCE hInst) |
| { |
| WNDCLASS wc; |
| |
| //Must have CS_DBLCLKS for border! |
| wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; |
| wc.hInstance = hInst; |
| wc.cbClsExtra = 0; |
| wc.lpfnWndProc = HatchWndProc; |
| wc.cbWndExtra = CBHATCHWNDEXTRA; |
| wc.hIcon = NULL; |
| wc.hCursor = LoadCursor(NULL, IDC_ARROW); |
| wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); |
| wc.lpszMenuName = NULL; |
| wc.lpszClassName = SZCLASSHATCHWIN; |
| |
| return RegisterClass(&wc); |
| return FALSE; |
| } |
| |
| |
| |
| |
| /* |
| * CHatchWin:CHatchWin |
| * CHatchWin::~CHatchWin |
| * |
| * Constructor Parameters: |
| * hInst HINSTANCE of the application we're in. |
| */ |
| |
| CHatchWin::CHatchWin(HINSTANCE hInst,const DocumentHolder* pDocHolder) |
| : CWindow(hInst), |
| m_aTracker() |
| { |
| m_hWnd=NULL; |
| m_hWndKid=NULL; |
| m_hWndAssociate=NULL; |
| m_uID=0; |
| |
| m_dBorderOrg=GetProfileInt(TEXT("windows") |
| , TEXT("OleInPlaceBorderWidth") |
| , HATCHWIN_BORDERWIDTHDEFAULT); |
| |
| m_dBorder=m_dBorderOrg; |
| SetRect(&m_rcPos, 0, 0, 0, 0); |
| SetRect(&m_rcClip, 0, 0, 0, 0); |
| |
| m_pDocHolder = pDocHolder; |
| return; |
| } |
| |
| |
| CHatchWin::~CHatchWin(void) |
| { |
| /* |
| * Chances are this was already destroyed when a document |
| * was destroyed. |
| */ |
| if (NULL!=m_hWnd && IsWindow(m_hWnd)) |
| DestroyWindow(m_hWnd); |
| |
| return; |
| } |
| |
| |
| |
| /* |
| * CHatchWin::Init |
| * |
| * Purpose: |
| * Instantiates a hatch window within a given parent with a |
| * default rectangle. This is not initially visible. |
| * |
| * Parameters: |
| * hWndParent HWND of the parent of this window |
| * uID UINT identifier for this window (send in |
| * notifications to associate window). |
| * hWndAssoc HWND of the initial associate. |
| * |
| * Return Value: |
| * BOOL TRUE if the function succeeded, FALSE otherwise. |
| */ |
| |
| BOOL CHatchWin::Init(HWND hWndParent, UINT uID, HWND hWndAssoc) |
| { |
| m_hWndParent = hWndParent; |
| m_hWnd=CreateWindowEx( |
| WS_EX_NOPARENTNOTIFY, SZCLASSHATCHWIN |
| , SZCLASSHATCHWIN, WS_CHILD | WS_CLIPSIBLINGS |
| | WS_CLIPCHILDREN, 0, 0, 100, 100, hWndParent, (HMENU)uID |
| , m_hInst, this); |
| |
| m_uID=uID; |
| m_hWndAssociate=hWndAssoc; |
| |
| return (NULL!=m_hWnd); |
| } |
| |
| |
| void CHatchWin::SetTrans() |
| { |
| HRGN hrgn = CreateRectRgn(0,0,0,0); |
| SetWindowRgn(m_hWnd,hrgn,true); |
| } |
| |
| /* |
| * CHatchWin::HwndAssociateSet |
| * CHatchWin::HwndAssociateGet |
| * |
| * Purpose: |
| * Sets (Set) or retrieves (Get) the associate window of the |
| * hatch window. |
| * |
| * Parameters: (Set only) |
| * hWndAssoc HWND to set as the associate. |
| * |
| * Return Value: |
| * HWND Previous (Set) or current (Get) associate |
| * window. |
| */ |
| |
| HWND CHatchWin::HwndAssociateSet(HWND hWndAssoc) |
| { |
| HWND hWndT=m_hWndAssociate; |
| |
| m_hWndAssociate=hWndAssoc; |
| return hWndT; |
| } |
| |
| |
| HWND CHatchWin::HwndAssociateGet(void) |
| { |
| return m_hWndAssociate; |
| } |
| |
| |
| /* |
| * CHatchWin::RectsSet |
| * |
| * Purpose: |
| * Changes the size and position of the hatch window and the child |
| * window within it using a position rectangle for the child and |
| * a clipping rectangle for the hatch window and child. The hatch |
| * window occupies prcPos expanded by the hatch border and clipped |
| * by prcClip. The child window is fit to prcPos to give the |
| * proper scaling, but it clipped to the hatch window which |
| * therefore clips it to prcClip without affecting the scaling. |
| * |
| * Parameters: |
| * prcPos LPRECT providing the position rectangle. |
| * prcClip LPRECT providing the clipping rectangle. |
| * |
| * Return Value: |
| * None |
| */ |
| |
| void CHatchWin::RectsSet(LPRECT prcPos, LPRECT prcClip) |
| { |
| RECT rc; |
| RECT rcPos; |
| |
| m_rcPos=*prcPos; |
| m_rcClip=*prcClip; |
| |
| //Calculate the rectangle for the hatch window, then clip it. |
| rcPos=*prcPos; |
| InflateRect(&rcPos, m_dBorder, m_dBorder); |
| IntersectRect(&rc, &rcPos, prcClip); |
| |
| SetWindowPos(m_hWnd, NULL, rc.left, rc.top, rc.right-rc.left |
| , rc.bottom-rc.top, SWP_NOZORDER | SWP_NOACTIVATE); |
| |
| /* |
| * Set the rectangle of the child window to be at m_dBorder |
| * from the top and left but with the same size as prcPos |
| * contains. The hatch window will clip it. |
| */ |
| // SetWindowPos(m_hWndKid, NULL, rcPos.left-rc.left+m_dBorder |
| // , rcPos.top-rc.top+m_dBorder, prcPos->right-prcPos->left |
| // , prcPos->bottom-prcPos->top, SWP_NOZORDER | SWP_NOACTIVATE); |
| |
| RECT newRC; |
| GetClientRect(m_hWnd,&newRC); |
| m_aTracker = Tracker( |
| &newRC, |
| Tracker::hatchInside | |
| Tracker::hatchedBorder | |
| Tracker::resizeInside |
| ); |
| |
| return; |
| } |
| |
| |
| |
| /* |
| * CHatchWin::ChildSet |
| * |
| * Purpose: |
| * Assigns a child window to this hatch window. |
| * |
| * Parameters: |
| * hWndKid HWND of the child window. |
| * |
| * Return Value: |
| * None |
| */ |
| |
| void CHatchWin::ChildSet(HWND hWndKid) |
| { |
| m_hWndKid=hWndKid; |
| |
| if (NULL!=hWndKid) |
| { |
| SetParent(hWndKid, m_hWnd); |
| |
| //Insure this is visible when the hatch window becomes visible. |
| ShowWindow(hWndKid, SW_SHOW); |
| } |
| |
| return; |
| } |
| |
| |
| |
| /* |
| * CHatchWin::ShowHatch |
| * |
| * Purpose: |
| * Turns hatching on and off; turning the hatching off changes |
| * the size of the window to be exactly that of the child, leaving |
| * everything else the same. The result is that we don't have |
| * to turn off drawing because our own WM_PAINT will never be |
| * called. |
| * |
| * Parameters: |
| * fHatch BOOL indicating to show (TRUE) or hide (FALSE) |
| the hatching. |
| * |
| * Return Value: |
| * None |
| */ |
| |
| void CHatchWin::ShowHatch(BOOL fHatch) |
| { |
| /* |
| * All we have to do is set the border to zero and |
| * call SetRects again with the last rectangles the |
| * child sent to us. |
| */ |
| m_dBorder=fHatch ? m_dBorderOrg : 0; |
| RectsSet(&m_rcPos, &m_rcClip); |
| return; |
| } |
| |
| |
| |
| /* |
| * HatchWndProc |
| * |
| * Purpose: |
| * Standard window procedure for the Hatch Window |
| */ |
| |
| LRESULT APIENTRY winwrap::HatchWndProc( |
| HWND hWnd, UINT iMsg |
| , WPARAM wParam, LPARAM lParam) |
| { |
| PCHatchWin phw; |
| HDC hDC; |
| PAINTSTRUCT ps; |
| |
| phw=(PCHatchWin)GetWindowLong(hWnd, HWWL_STRUCTURE); |
| POINT ptMouse; |
| |
| switch (iMsg) |
| { |
| case WM_CREATE: |
| phw=(PCHatchWin)((LPCREATESTRUCT)lParam)->lpCreateParams; |
| SetWindowLong(hWnd, HWWL_STRUCTURE, (LONG)phw); |
| break; |
| case WM_PAINT: |
| hDC=BeginPaint(hWnd,&ps); |
| //Always draw the hatching. |
| phw->m_aTracker.Draw(hDC); |
| EndPaint(hWnd,&ps); |
| break; |
| case WM_LBUTTONDOWN: |
| GetCursorPos(&ptMouse); |
| ScreenToClient(hWnd,&ptMouse); |
| |
| // track in case we have to |
| if(phw->m_aTracker.Track(hWnd,ptMouse,FALSE,GetParent(hWnd))) |
| { |
| RECT aRect = phw->m_aTracker.m_rect; |
| TransformRect(&aRect,hWnd,GetParent(hWnd)); |
| phw->m_pDocHolder->OnPosRectChanged(&aRect); |
| } |
| break; |
| case WM_LBUTTONUP: |
| case WM_MOUSEMOVE: |
| GetCursorPos(&ptMouse); |
| ScreenToClient(hWnd,&ptMouse); |
| phw->m_aTracker.SetCursor(hWnd,HTCLIENT); |
| break; |
| case WM_SETFOCUS: |
| //We need this since the container will SetFocus to us. |
| if (NULL!=phw->m_hWndKid) |
| SetFocus(phw->m_hWndKid); |
| |
| break; |
| case WM_LBUTTONDBLCLK: |
| /* |
| * If the double click was within m_dBorder of an |
| * edge, send the HWN_BORDERDOUBLECLICKED notification. |
| * |
| * Because we're always sized just larger than our child |
| * window by the border width, we can only *get* this |
| * message when the mouse is on the border. So we can |
| * just send the notification. |
| */ |
| if (NULL!=phw->m_hWndAssociate) |
| { |
| SendCommand(phw->m_hWndAssociate, phw->m_uID |
| , HWN_BORDERDOUBLECLICKED, hWnd); |
| } |
| |
| break; |
| default: |
| return DefWindowProc(hWnd, iMsg, wParam, lParam); |
| } |
| |
| return 0L; |
| } |
| |
| // Fix strange warnings about some |
| // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions. |
| // warning C4505: 'xxx' : unreferenced local function has been removed |
| #if defined(_MSC_VER) |
| #pragma warning(disable: 4505) |
| #endif |