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 60 winwrap::CWindow::CWindow(HINSTANCE hInst) 61 { 62 m_hInst=hInst; 63 m_hWnd=NULL; 64 return; 65 } 66 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 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 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 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 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 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 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 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 254 HWND CHatchWin::HwndAssociateSet(HWND hWndAssoc) 255 { 256 HWND hWndT=m_hWndAssociate; 257 258 m_hWndAssociate=hWndAssoc; 259 return hWndT; 260 } 261 262 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 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 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 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 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