1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <docholder.hxx>
21 #include <syswinwrapper.hxx>
27 * Constructor Parameters:
28 * hInst HINSTANCE of the task owning us.
32 using namespace winwrap
;
35 #define HWWL_STRUCTURE 0
37 //Notification codes for WM_COMMAND messages
38 #define HWN_BORDERDOUBLECLICKED 1
39 #define CBHATCHWNDEXTRA (sizeof(LONG))
40 #define SZCLASSHATCHWIN L"hatchwin"
42 typedef CHatchWin
*PCHatchWin
;
44 winwrap::CWindow::CWindow(HINSTANCE hInst
)
51 winwrap::CWindow::~CWindow()
54 DestroyWindow(m_hWnd
);
64 * Returns the window handle associated with this object.
67 * HWND Window handle for this object
70 HWND
winwrap::CWindow::Window()
80 * Returns the instance handle associated with this object.
83 * HINSTANCE Instance handle of the module stored here.
86 HINSTANCE
winwrap::CWindow::Instance()
95 * Registers the hatch window class for use with CHatchWin.
98 * hInst HINSTANCE under which to register.
101 * BOOL TRUE if successful, FALSE otherwise.
104 BOOL
winwrap::HatchWindowRegister(HINSTANCE hInst
)
108 //Must have CS_DBLCLKS for border!
109 wc
.style
= CS_HREDRAW
| CS_VREDRAW
| CS_DBLCLKS
;
110 wc
.hInstance
= hInst
;
112 wc
.lpfnWndProc
= HatchWndProc
;
113 wc
.cbWndExtra
= CBHATCHWNDEXTRA
;
115 wc
.hCursor
= LoadCursor(nullptr, IDC_ARROW
);
116 wc
.hbrBackground
= reinterpret_cast<HBRUSH
>(COLOR_WINDOW
+1);
117 wc
.lpszMenuName
= nullptr;
118 wc
.lpszClassName
= SZCLASSHATCHWIN
;
120 return RegisterClassW(&wc
) != 0;
125 * CHatchWin:CHatchWin
126 * CHatchWin::~CHatchWin
128 * Constructor Parameters:
129 * hInst HINSTANCE of the application we're in.
132 CHatchWin::CHatchWin(HINSTANCE hInst
,const DocumentHolder
* pDocHolder
)
138 m_hWndAssociate
=nullptr;
141 m_dBorderOrg
=GetProfileIntW(L
"windows"
142 , L
"OleInPlaceBorderWidth"
143 , HATCHWIN_BORDERWIDTHDEFAULT
);
145 m_dBorder
=m_dBorderOrg
;
146 SetRect(&m_rcPos
, 0, 0, 0, 0);
147 SetRect(&m_rcClip
, 0, 0, 0, 0);
149 m_pDocHolder
= pDocHolder
;
154 CHatchWin::~CHatchWin()
157 * Chances are this was already destroyed when a document
160 if (nullptr!=m_hWnd
&& IsWindow(m_hWnd
))
161 DestroyWindow(m_hWnd
);
171 * Instantiates a hatch window within a given parent with a
172 * default rectangle. This is not initially visible.
175 * hWndParent HWND of the parent of this window
176 * uID WORD identifier for this window (send in
177 * notifications to associate window).
178 * hWndAssoc HWND of the initial associate.
181 * BOOL TRUE if the function succeeded, FALSE otherwise.
184 BOOL
CHatchWin::Init(HWND hWndParent
, WORD uID
, HWND hWndAssoc
)
186 m_hWndParent
= hWndParent
;
187 m_hWnd
=CreateWindowExW(
188 WS_EX_NOPARENTNOTIFY
, SZCLASSHATCHWIN
189 , SZCLASSHATCHWIN
, WS_CHILD
| WS_CLIPSIBLINGS
190 | WS_CLIPCHILDREN
, 0, 0, 100, 100, hWndParent
191 , reinterpret_cast<HMENU
>(UINT_PTR(uID
)), m_hInst
, this);
194 m_hWndAssociate
=hWndAssoc
;
196 return (nullptr!=m_hWnd
);
200 void CHatchWin::SetTrans()
202 HRGN hrgn
= CreateRectRgn(0,0,0,0);
203 SetWindowRgn(m_hWnd
,hrgn
,true);
207 * CHatchWin::HwndAssociateSet
208 * CHatchWin::HwndAssociateGet
211 * Sets (Set) or retrieves (Get) the associate window of the
214 * Parameters: (Set only)
215 * hWndAssoc HWND to set as the associate.
218 * HWND Previous (Set) or current (Get) associate
222 HWND
CHatchWin::HwndAssociateSet(HWND hWndAssoc
)
224 HWND hWndT
=m_hWndAssociate
;
226 m_hWndAssociate
=hWndAssoc
;
231 HWND
CHatchWin::HwndAssociateGet()
233 return m_hWndAssociate
;
238 * CHatchWin::RectsSet
241 * Changes the size and position of the hatch window and the child
242 * window within it using a position rectangle for the child and
243 * a clipping rectangle for the hatch window and child. The hatch
244 * window occupies prcPos expanded by the hatch border and clipped
245 * by prcClip. The child window is fit to prcPos to give the
246 * proper scaling, but it clipped to the hatch window which
247 * therefore clips it to prcClip without affecting the scaling.
250 * prcPos LPRECT providing the position rectangle.
251 * prcClip LPRECT providing the clipping rectangle.
257 void CHatchWin::RectsSet(LPRECT prcPos
, LPRECT prcClip
)
265 //Calculate the rectangle for the hatch window, then clip it.
267 InflateRect(&rcPos
, m_dBorder
, m_dBorder
);
268 IntersectRect(&rc
, &rcPos
, prcClip
);
270 SetWindowPos(m_hWnd
, nullptr, rc
.left
, rc
.top
, rc
.right
-rc
.left
271 , rc
.bottom
-rc
.top
, SWP_NOZORDER
| SWP_NOACTIVATE
);
274 * Set the rectangle of the child window to be at m_dBorder
275 * from the top and left but with the same size as prcPos
276 * contains. The hatch window will clip it.
278 // SetWindowPos(m_hWndKid, NULL, rcPos.left-rc.left+m_dBorder
279 // , rcPos.top-rc.top+m_dBorder, prcPos->right-prcPos->left
280 // , prcPos->bottom-prcPos->top, SWP_NOZORDER | SWP_NOACTIVATE);
283 GetClientRect(m_hWnd
,&newRC
);
284 m_aTracker
= Tracker(
286 Tracker::hatchInside
|
287 Tracker::hatchedBorder
|
288 Tracker::resizeInside
296 * CHatchWin::ChildSet
299 * Assigns a child window to this hatch window.
302 * hWndKid HWND of the child window.
308 void CHatchWin::ChildSet(HWND hWndKid
)
312 if (nullptr!=hWndKid
)
314 SetParent(hWndKid
, m_hWnd
);
316 //Ensure this is visible when the hatch window becomes visible.
317 ShowWindow(hWndKid
, SW_SHOW
);
325 * CHatchWin::ShowHatch
328 * Turns hatching on and off; turning the hatching off changes
329 * the size of the window to be exactly that of the child, leaving
330 * everything else the same. The result is that we don't have
331 * to turn off drawing because our own WM_PAINT will never be
335 * fHatch BOOL indicating to show (TRUE) or hide (FALSE)
342 void CHatchWin::ShowHatch(BOOL fHatch
)
345 * All we have to do is set the border to zero and
346 * call SetRects again with the last rectangles the
349 m_dBorder
=fHatch
? m_dBorderOrg
: 0;
350 RectsSet(&m_rcPos
, &m_rcClip
);
359 * Standard window procedure for the Hatch Window
362 LRESULT APIENTRY
winwrap::HatchWndProc(
364 , WPARAM wParam
, LPARAM lParam
)
370 phw
=reinterpret_cast<PCHatchWin
>(GetWindowLongPtrW(hWnd
, HWWL_STRUCTURE
));
376 phw
=static_cast<PCHatchWin
>(reinterpret_cast<LPCREATESTRUCT
>(lParam
)->lpCreateParams
);
377 SetWindowLongPtrW(hWnd
, HWWL_STRUCTURE
, reinterpret_cast<LONG_PTR
>(phw
));
380 hDC
=BeginPaint(hWnd
,&ps
);
381 //Always draw the hatching.
382 phw
->m_aTracker
.Draw(hDC
);
386 GetCursorPos(&ptMouse
);
387 ScreenToClient(hWnd
,&ptMouse
);
389 // track in case we have to
390 if(phw
->m_aTracker
.Track(hWnd
,ptMouse
,FALSE
,GetParent(hWnd
)))
392 RECT aRect
= phw
->m_aTracker
.m_rect
;
393 TransformRect(&aRect
,hWnd
,GetParent(hWnd
));
394 phw
->m_pDocHolder
->OnPosRectChanged(&aRect
);
399 GetCursorPos(&ptMouse
);
400 ScreenToClient(hWnd
,&ptMouse
);
401 phw
->m_aTracker
.SetCursor(hWnd
,HTCLIENT
);
404 //We need this since the container will SetFocus to us.
405 if (nullptr!=phw
->m_hWndKid
)
406 SetFocus(phw
->m_hWndKid
);
409 case WM_LBUTTONDBLCLK
:
411 * If the double click was within m_dBorder of an
412 * edge, send the HWN_BORDERDOUBLECLICKED notification.
414 * Because we're always sized just larger than our child
415 * window by the border width, we can only *get* this
416 * message when the mouse is on the border. So we can
417 * just send the notification.
419 if (nullptr!=phw
->m_hWndAssociate
)
422 phw
->m_hWndAssociate
, WM_COMMAND
,
423 MAKEWPARAM(phw
->m_uID
, HWN_BORDERDOUBLECLICKED
),
424 reinterpret_cast<LPARAM
>(hWnd
));
429 return DefWindowProcW(hWnd
, iMsg
, wParam
, lParam
);
435 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */