1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23 #if defined(_MSC_VER) && (_MSC_VER > 1310)
24 #pragma warning(disable : 4917 4555)
25 #endif
26
27 #include "docholder.hxx"
28 #include "syswinwrapper.hxx"
29
30 /*
31 * CWindow::CWindow
32 * CWindow::~CWindow
33 *
34 * Constructor Parameters:
35 * hInst HINSTANCE of the task owning us.
36 */
37
38
39 using namespace winwrap;
40
41
42 #define HWWL_STRUCTURE 0
43
44 //Notification codes for WM_COMMAND messages
45 #define HWN_BORDERDOUBLECLICKED 1
46 #define CBHATCHWNDEXTRA (sizeof(LONG))
47 #define SZCLASSHATCHWIN TEXT("hatchwin")
48 #define SendCommand(hWnd, wID, wCode, hControl) \
49 SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(wID, wCode) \
50 , (LPARAM)hControl)
51
52
53 typedef CHatchWin *PCHatchWin;
54
55
56 void DrawShading(LPRECT prc, HDC hDC, UINT cWidth);
57
58
59
CWindow(HINSTANCE hInst)60 winwrap::CWindow::CWindow(HINSTANCE hInst)
61 {
62 m_hInst=hInst;
63 m_hWnd=NULL;
64 return;
65 }
66
~CWindow(void)67 winwrap::CWindow::~CWindow(void)
68 {
69 if (IsWindow(m_hWnd))
70 DestroyWindow(m_hWnd);
71
72 return;
73 }
74
75
76
77 /*
78 * CWindow::Window
79 *
80 * Purpose:
81 * Returns the window handle associated with this object.
82 *
83 * Return Value:
84 * HWND Window handle for this object
85 */
86
Window(void)87 HWND winwrap::CWindow::Window(void)
88 {
89 return m_hWnd;
90 }
91
92
93
94 /*
95 * CWindow::Instance
96 *
97 * Purpose:
98 * Returns the instance handle associated with this object.
99 *
100 * Return Value:
101 * HINSTANCE Instance handle of the module stored here.
102 */
103
Instance(void)104 HINSTANCE winwrap::CWindow::Instance(void)
105 {
106 return m_hInst;
107 }
108
109
110
111
112
113 //Hatch pattern brush bits
114 static WORD g_wHatchBmp[]={0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88};
115
116 // void DrawShading(LPRECT, HDC, UINT);
117
118
119 /*
120 * HatchWindowRegister
121 *
122 * Purpose:
123 * Registers the hatch window class for use with CHatchWin.
124 *
125 * Parameters:
126 * hInst HINSTANCE under which to register.
127 *
128 * Return Value:
129 * BOOL TRUE if successful, FALSE otherwise.
130 */
131
HatchWindowRegister(HINSTANCE hInst)132 BOOL winwrap::HatchWindowRegister(HINSTANCE hInst)
133 {
134 WNDCLASS wc;
135
136 //Must have CS_DBLCLKS for border!
137 wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
138 wc.hInstance = hInst;
139 wc.cbClsExtra = 0;
140 wc.lpfnWndProc = HatchWndProc;
141 wc.cbWndExtra = CBHATCHWNDEXTRA;
142 wc.hIcon = NULL;
143 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
144 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
145 wc.lpszMenuName = NULL;
146 wc.lpszClassName = SZCLASSHATCHWIN;
147
148 return RegisterClass(&wc);
149 return FALSE;
150 }
151
152
153
154
155 /*
156 * CHatchWin:CHatchWin
157 * CHatchWin::~CHatchWin
158 *
159 * Constructor Parameters:
160 * hInst HINSTANCE of the application we're in.
161 */
162
CHatchWin(HINSTANCE hInst,const DocumentHolder * pDocHolder)163 CHatchWin::CHatchWin(HINSTANCE hInst,const DocumentHolder* pDocHolder)
164 : CWindow(hInst),
165 m_aTracker()
166 {
167 m_hWnd=NULL;
168 m_hWndKid=NULL;
169 m_hWndAssociate=NULL;
170 m_uID=0;
171
172 m_dBorderOrg=GetProfileInt(TEXT("windows")
173 , TEXT("OleInPlaceBorderWidth")
174 , HATCHWIN_BORDERWIDTHDEFAULT);
175
176 m_dBorder=m_dBorderOrg;
177 SetRect(&m_rcPos, 0, 0, 0, 0);
178 SetRect(&m_rcClip, 0, 0, 0, 0);
179
180 m_pDocHolder = pDocHolder;
181 return;
182 }
183
184
~CHatchWin(void)185 CHatchWin::~CHatchWin(void)
186 {
187 /*
188 * Chances are this was already destroyed when a document
189 * was destroyed.
190 */
191 if (NULL!=m_hWnd && IsWindow(m_hWnd))
192 DestroyWindow(m_hWnd);
193
194 return;
195 }
196
197
198
199 /*
200 * CHatchWin::Init
201 *
202 * Purpose:
203 * Instantiates a hatch window within a given parent with a
204 * default rectangle. This is not initially visible.
205 *
206 * Parameters:
207 * hWndParent HWND of the parent of this window
208 * uID UINT identifier for this window (send in
209 * notifications to associate window).
210 * hWndAssoc HWND of the initial associate.
211 *
212 * Return Value:
213 * BOOL TRUE if the function succeeded, FALSE otherwise.
214 */
215
Init(HWND hWndParent,UINT uID,HWND hWndAssoc)216 BOOL CHatchWin::Init(HWND hWndParent, UINT uID, HWND hWndAssoc)
217 {
218 m_hWndParent = hWndParent;
219 m_hWnd=CreateWindowEx(
220 WS_EX_NOPARENTNOTIFY, SZCLASSHATCHWIN
221 , SZCLASSHATCHWIN, WS_CHILD | WS_CLIPSIBLINGS
222 | WS_CLIPCHILDREN, 0, 0, 100, 100, hWndParent, (HMENU)uID
223 , m_hInst, this);
224
225 m_uID=uID;
226 m_hWndAssociate=hWndAssoc;
227
228 return (NULL!=m_hWnd);
229 }
230
231
SetTrans()232 void CHatchWin::SetTrans()
233 {
234 HRGN hrgn = CreateRectRgn(0,0,0,0);
235 SetWindowRgn(m_hWnd,hrgn,true);
236 }
237
238 /*
239 * CHatchWin::HwndAssociateSet
240 * CHatchWin::HwndAssociateGet
241 *
242 * Purpose:
243 * Sets (Set) or retrieves (Get) the associate window of the
244 * hatch window.
245 *
246 * Parameters: (Set only)
247 * hWndAssoc HWND to set as the associate.
248 *
249 * Return Value:
250 * HWND Previous (Set) or current (Get) associate
251 * window.
252 */
253
HwndAssociateSet(HWND hWndAssoc)254 HWND CHatchWin::HwndAssociateSet(HWND hWndAssoc)
255 {
256 HWND hWndT=m_hWndAssociate;
257
258 m_hWndAssociate=hWndAssoc;
259 return hWndT;
260 }
261
262
HwndAssociateGet(void)263 HWND CHatchWin::HwndAssociateGet(void)
264 {
265 return m_hWndAssociate;
266 }
267
268
269 /*
270 * CHatchWin::RectsSet
271 *
272 * Purpose:
273 * Changes the size and position of the hatch window and the child
274 * window within it using a position rectangle for the child and
275 * a clipping rectangle for the hatch window and child. The hatch
276 * window occupies prcPos expanded by the hatch border and clipped
277 * by prcClip. The child window is fit to prcPos to give the
278 * proper scaling, but it clipped to the hatch window which
279 * therefore clips it to prcClip without affecting the scaling.
280 *
281 * Parameters:
282 * prcPos LPRECT providing the position rectangle.
283 * prcClip LPRECT providing the clipping rectangle.
284 *
285 * Return Value:
286 * None
287 */
288
RectsSet(LPRECT prcPos,LPRECT prcClip)289 void CHatchWin::RectsSet(LPRECT prcPos, LPRECT prcClip)
290 {
291 RECT rc;
292 RECT rcPos;
293
294 m_rcPos=*prcPos;
295 m_rcClip=*prcClip;
296
297 //Calculate the rectangle for the hatch window, then clip it.
298 rcPos=*prcPos;
299 InflateRect(&rcPos, m_dBorder, m_dBorder);
300 IntersectRect(&rc, &rcPos, prcClip);
301
302 SetWindowPos(m_hWnd, NULL, rc.left, rc.top, rc.right-rc.left
303 , rc.bottom-rc.top, SWP_NOZORDER | SWP_NOACTIVATE);
304
305 /*
306 * Set the rectangle of the child window to be at m_dBorder
307 * from the top and left but with the same size as prcPos
308 * contains. The hatch window will clip it.
309 */
310 // SetWindowPos(m_hWndKid, NULL, rcPos.left-rc.left+m_dBorder
311 // , rcPos.top-rc.top+m_dBorder, prcPos->right-prcPos->left
312 // , prcPos->bottom-prcPos->top, SWP_NOZORDER | SWP_NOACTIVATE);
313
314 RECT newRC;
315 GetClientRect(m_hWnd,&newRC);
316 m_aTracker = Tracker(
317 &newRC,
318 Tracker::hatchInside |
319 Tracker::hatchedBorder |
320 Tracker::resizeInside
321 );
322
323 return;
324 }
325
326
327
328 /*
329 * CHatchWin::ChildSet
330 *
331 * Purpose:
332 * Assigns a child window to this hatch window.
333 *
334 * Parameters:
335 * hWndKid HWND of the child window.
336 *
337 * Return Value:
338 * None
339 */
340
ChildSet(HWND hWndKid)341 void CHatchWin::ChildSet(HWND hWndKid)
342 {
343 m_hWndKid=hWndKid;
344
345 if (NULL!=hWndKid)
346 {
347 SetParent(hWndKid, m_hWnd);
348
349 //Insure this is visible when the hatch window becomes visible.
350 ShowWindow(hWndKid, SW_SHOW);
351 }
352
353 return;
354 }
355
356
357
358 /*
359 * CHatchWin::ShowHatch
360 *
361 * Purpose:
362 * Turns hatching on and off; turning the hatching off changes
363 * the size of the window to be exactly that of the child, leaving
364 * everything else the same. The result is that we don't have
365 * to turn off drawing because our own WM_PAINT will never be
366 * called.
367 *
368 * Parameters:
369 * fHatch BOOL indicating to show (TRUE) or hide (FALSE)
370 the hatching.
371 *
372 * Return Value:
373 * None
374 */
375
ShowHatch(BOOL fHatch)376 void CHatchWin::ShowHatch(BOOL fHatch)
377 {
378 /*
379 * All we have to do is set the border to zero and
380 * call SetRects again with the last rectangles the
381 * child sent to us.
382 */
383 m_dBorder=fHatch ? m_dBorderOrg : 0;
384 RectsSet(&m_rcPos, &m_rcClip);
385 return;
386 }
387
388
389
390 /*
391 * HatchWndProc
392 *
393 * Purpose:
394 * Standard window procedure for the Hatch Window
395 */
396
HatchWndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam)397 LRESULT APIENTRY winwrap::HatchWndProc(
398 HWND hWnd, UINT iMsg
399 , WPARAM wParam, LPARAM lParam)
400 {
401 PCHatchWin phw;
402 HDC hDC;
403 PAINTSTRUCT ps;
404
405 phw=(PCHatchWin)GetWindowLong(hWnd, HWWL_STRUCTURE);
406 POINT ptMouse;
407
408 switch (iMsg)
409 {
410 case WM_CREATE:
411 phw=(PCHatchWin)((LPCREATESTRUCT)lParam)->lpCreateParams;
412 SetWindowLong(hWnd, HWWL_STRUCTURE, (LONG)phw);
413 break;
414 case WM_PAINT:
415 hDC=BeginPaint(hWnd,&ps);
416 //Always draw the hatching.
417 phw->m_aTracker.Draw(hDC);
418 EndPaint(hWnd,&ps);
419 break;
420 case WM_LBUTTONDOWN:
421 GetCursorPos(&ptMouse);
422 ScreenToClient(hWnd,&ptMouse);
423
424 // track in case we have to
425 if(phw->m_aTracker.Track(hWnd,ptMouse,FALSE,GetParent(hWnd)))
426 {
427 RECT aRect = phw->m_aTracker.m_rect;
428 TransformRect(&aRect,hWnd,GetParent(hWnd));
429 phw->m_pDocHolder->OnPosRectChanged(&aRect);
430 }
431 break;
432 case WM_LBUTTONUP:
433 case WM_MOUSEMOVE:
434 GetCursorPos(&ptMouse);
435 ScreenToClient(hWnd,&ptMouse);
436 phw->m_aTracker.SetCursor(hWnd,HTCLIENT);
437 break;
438 case WM_SETFOCUS:
439 //We need this since the container will SetFocus to us.
440 if (NULL!=phw->m_hWndKid)
441 SetFocus(phw->m_hWndKid);
442
443 break;
444 case WM_LBUTTONDBLCLK:
445 /*
446 * If the double click was within m_dBorder of an
447 * edge, send the HWN_BORDERDOUBLECLICKED notification.
448 *
449 * Because we're always sized just larger than our child
450 * window by the border width, we can only *get* this
451 * message when the mouse is on the border. So we can
452 * just send the notification.
453 */
454 if (NULL!=phw->m_hWndAssociate)
455 {
456 SendCommand(phw->m_hWndAssociate, phw->m_uID
457 , HWN_BORDERDOUBLECLICKED, hWnd);
458 }
459
460 break;
461 default:
462 return DefWindowProc(hWnd, iMsg, wParam, lParam);
463 }
464
465 return 0L;
466 }
467
468 // Fix strange warnings about some
469 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
470 // warning C4505: 'xxx' : unreferenced local function has been removed
471 #if defined(_MSC_VER)
472 #pragma warning(disable: 4505)
473 #endif
474