blob: 769ee62c99c701893e7e8d059ca5b13ce766365d [file] [log] [blame]
/**************************************************************
*
* 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