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