1 /* 2 * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "awt_Toolkit.h" 27 #include "awt_Frame.h" 28 #include "awt_MenuBar.h" 29 #include "awt_Dialog.h" 30 #include "awt_IconCursor.h" 31 #include "awt_Win32GraphicsDevice.h" 32 #include "ComCtl32Util.h" 33 34 #include <windowsx.h> 35 36 #include <java_lang_Integer.h> 37 #include <sun_awt_windows_WEmbeddedFrame.h> 38 #include <sun_awt_windows_WEmbeddedFramePeer.h> 39 40 41 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 42 */ 43 44 /***********************************************************************/ 45 // Struct for _SetState() method 46 struct SetStateStruct { 47 jobject frame; 48 jint state; 49 }; 50 // Struct for _SetMaximizedBounds() method 51 struct SetMaximizedBoundsStruct { 52 jobject frame; 53 jint x, y; 54 jint width, height; 55 }; 56 // Struct for _SetMenuBar() method 57 struct SetMenuBarStruct { 58 jobject frame; 59 jobject menubar; 60 }; 61 62 // Struct for _SetIMMOption() method 63 struct SetIMMOptionStruct { 64 jobject frame; 65 jstring option; 66 }; 67 // Struct for _SynthesizeWmActivate() method 68 struct SynthesizeWmActivateStruct { 69 jobject frame; 70 jboolean doActivate; 71 }; 72 // Struct for _NotifyModalBlocked() method 73 struct NotifyModalBlockedStruct { 74 jobject frame; 75 jobject peer; 76 jobject blockerPeer; 77 jboolean blocked; 78 }; 79 // Information about thread containing modal blocked embedded frames 80 struct BlockedThreadStruct { 81 int framesCount; 82 HHOOK mouseHook; 83 HHOOK modalHook; 84 }; 85 86 87 // Communication with plugin control 88 89 // The value must be the same as in AxControl.h 90 #define WM_AX_REQUEST_FOCUS_TO_EMBEDDER (WM_USER + 197) 91 92 static bool SetFocusToPluginControl(HWND hwndPlugin); 93 94 /************************************************************************ 95 * AwtFrame fields 96 */ 97 98 jfieldID AwtFrame::handleID; 99 100 jfieldID AwtFrame::undecoratedID; 101 jmethodID AwtFrame::getExtendedStateMID; 102 jmethodID AwtFrame::setExtendedStateMID; 103 104 jmethodID AwtFrame::activateEmbeddingTopLevelMID; 105 jfieldID AwtFrame::isEmbeddedInIEID; 106 107 Hashtable AwtFrame::sm_BlockedThreads("AWTBlockedThreads"); 108 109 /************************************************************************ 110 * AwtFrame methods 111 */ 112 113 AwtFrame::AwtFrame() { 114 m_parentWnd = NULL; 115 menuBar = NULL; 116 m_isEmbedded = FALSE; 117 m_isEmbeddedInIE = FALSE; 118 m_isLightweight = FALSE; 119 m_ignoreWmSize = FALSE; 120 m_isMenuDropped = FALSE; 121 m_isInputMethodWindow = FALSE; 122 m_isUndecorated = FALSE; 123 m_imeTargetComponent = NULL; 124 m_actualFocusedWindow = NULL; 125 m_iconic = FALSE; 126 m_zoomed = FALSE; 127 m_maxBoundsSet = FALSE; 128 m_forceResetZoomed = FALSE; 129 130 isInManualMoveOrSize = FALSE; 131 grabbedHitTest = 0; 132 } 133 134 AwtFrame::~AwtFrame() 135 { 136 } 137 138 void AwtFrame::Dispose() 139 { 140 AwtWindow::Dispose(); 141 } 142 143 LPCTSTR AwtFrame::GetClassName() { 144 return AWT_FRAME_WINDOW_CLASS_NAME; 145 } 146 147 /* 148 * Create a new AwtFrame object and window. 149 */ 150 AwtFrame* AwtFrame::Create(jobject self, jobject parent) 151 { 152 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 153 if (env->EnsureLocalCapacity(1) < 0) { 154 return NULL; 155 } 156 157 PDATA pData; 158 HWND hwndParent = NULL; 159 AwtFrame* frame = NULL; 160 jclass cls = NULL; 161 jclass inputMethodWindowCls = NULL; 162 jobject target = NULL; 163 164 try { 165 target = env->GetObjectField(self, AwtObject::targetID); 166 JNI_CHECK_NULL_GOTO(target, "target", done); 167 168 if (parent != NULL) { 169 JNI_CHECK_PEER_GOTO(parent, done); 170 { 171 AwtFrame* parent = (AwtFrame *)pData; 172 HWND oHWnd = parent->GetOverriddenHWnd(); 173 hwndParent = oHWnd ? oHWnd : parent->GetHWnd(); 174 } 175 } 176 177 frame = new AwtFrame(); 178 179 { 180 /* 181 * A variation on Netscape's hack for embedded frames: the client 182 * area of the browser is a Java Frame for parenting purposes, but 183 * really a Windows child window 184 */ 185 BOOL isEmbeddedInstance = FALSE; 186 BOOL isEmbedded = FALSE; 187 cls = env->FindClass("sun/awt/EmbeddedFrame"); 188 189 if (cls) { 190 isEmbeddedInstance = env->IsInstanceOf(target, cls); 191 } else { 192 throw std::bad_alloc(); 193 } 194 INT_PTR handle; 195 if (isEmbeddedInstance) { 196 handle = static_cast<INT_PTR>(env->GetLongField(target, AwtFrame::handleID)); 197 if (handle != 0) { 198 isEmbedded = TRUE; 199 } 200 } 201 frame->m_isEmbedded = isEmbedded; 202 203 BOOL isLightweight = FALSE; 204 cls = env->FindClass("sun/awt/LightweightFrame"); 205 if (cls) { 206 isLightweight = env->IsInstanceOf(target, cls); 207 } else { 208 throw std::bad_alloc(); 209 } 210 frame->m_isLightweight = isLightweight; 211 212 if (isEmbedded) { 213 hwndParent = (HWND)handle; 214 215 // JDK-8056915: Handle focus communication between plugin and frame 216 frame->m_isEmbeddedInIE = IsEmbeddedInIE(hwndParent); 217 if (frame->m_isEmbeddedInIE) { 218 env->SetBooleanField(target, isEmbeddedInIEID, JNI_TRUE); 219 } 220 221 RECT rect; 222 ::GetClientRect(hwndParent, &rect); 223 //Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6 224 frame->m_isUndecorated = true; 225 /* 226 * Fix for BugTraq ID 4337754. 227 * Initialize m_peerObject before the first call 228 * to AwtFrame::GetClassName(). 229 */ 230 frame->m_peerObject = env->NewGlobalRef(self); 231 frame->RegisterClass(); 232 DWORD exStyle = WS_EX_NOPARENTNOTIFY; 233 234 if (GetRTL()) { 235 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; 236 if (GetRTLReadingOrder()) 237 exStyle |= WS_EX_RTLREADING; 238 } 239 240 frame->m_hwnd = ::CreateWindowEx(exStyle, 241 frame->GetClassName(), TEXT(""), 242 WS_CHILD | WS_CLIPCHILDREN, 243 0, 0, 244 rect.right, rect.bottom, 245 hwndParent, NULL, 246 AwtToolkit::GetInstance().GetModuleHandle(), 247 NULL); 248 frame->LinkObjects(env, self); 249 frame->SubclassHWND(); 250 251 // Update target's dimensions to reflect this embedded window. 252 ::GetClientRect(frame->m_hwnd, &rect); 253 ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2); 254 255 env->SetIntField(target, AwtComponent::xID, rect.left); 256 env->SetIntField(target, AwtComponent::yID, rect.top); 257 env->SetIntField(target, AwtComponent::widthID, 258 rect.right-rect.left); 259 env->SetIntField(target, AwtComponent::heightID, 260 rect.bottom-rect.top); 261 frame->InitPeerGraphicsConfig(env, self); 262 AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent); 263 } else if (isLightweight) { 264 frame->m_isUndecorated = true; 265 frame->m_peerObject = env->NewGlobalRef(self); 266 frame->RegisterClass(); 267 268 DWORD exStyle = 0; 269 DWORD style = WS_POPUP; 270 271 frame->CreateHWnd(env, L"", 272 style, 273 exStyle, 274 0, 0, 0, 0, 275 0, 276 NULL, 277 ::GetSysColor(COLOR_WINDOWTEXT), 278 ::GetSysColor(COLOR_WINDOWFRAME), 279 self); 280 } else { 281 jint state = env->CallIntMethod(self, AwtFrame::getExtendedStateMID); 282 DWORD exStyle; 283 DWORD style; 284 285 // for input method windows, use minimal decorations 286 inputMethodWindowCls = env->FindClass("sun/awt/im/InputMethodWindow"); 287 if (inputMethodWindowCls == NULL) { 288 throw std::bad_alloc(); 289 } 290 291 if (env->IsInstanceOf(target, inputMethodWindowCls)) { 292 //for below-the-spot composition window, use no decoration 293 if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE){ 294 exStyle = 0; 295 style = WS_POPUP|WS_CLIPCHILDREN; 296 frame->m_isUndecorated = TRUE; 297 } else { 298 exStyle = WS_EX_PALETTEWINDOW; 299 style = WS_CLIPCHILDREN; 300 } 301 frame->m_isInputMethodWindow = TRUE; 302 } else if (env->GetBooleanField(target, AwtFrame::undecoratedID) == JNI_TRUE) { 303 exStyle = 0; 304 style = WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN | 305 WS_MAXIMIZEBOX | WS_MINIMIZEBOX; 306 if (state & java_awt_Frame_ICONIFIED) { 307 frame->setIconic(TRUE); 308 } 309 frame->m_isUndecorated = TRUE; 310 } else { 311 exStyle = WS_EX_WINDOWEDGE; 312 style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; 313 if (state & java_awt_Frame_ICONIFIED) { 314 frame->setIconic(TRUE); 315 } 316 } 317 318 if (GetRTL()) { 319 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; 320 if (GetRTLReadingOrder()) 321 exStyle |= WS_EX_RTLREADING; 322 } 323 324 jint x = env->GetIntField(target, AwtComponent::xID); 325 jint y = env->GetIntField(target, AwtComponent::yID); 326 jint width = env->GetIntField(target, AwtComponent::widthID); 327 jint height = env->GetIntField(target, AwtComponent::heightID); 328 329 frame->CreateHWnd(env, L"", 330 style, 331 exStyle, 332 x, y, width, height, 333 hwndParent, 334 NULL, 335 ::GetSysColor(COLOR_WINDOWTEXT), 336 ::GetSysColor(COLOR_WINDOWFRAME), 337 self); 338 frame->RecalcNonClient(); 339 } 340 } 341 } catch (...) { 342 env->DeleteLocalRef(target); 343 env->DeleteLocalRef(cls); 344 env->DeleteLocalRef(inputMethodWindowCls); 345 throw; 346 } 347 348 done: 349 env->DeleteLocalRef(target); 350 env->DeleteLocalRef(cls); 351 env->DeleteLocalRef(inputMethodWindowCls); 352 353 return frame; 354 } 355 356 /* 357 * Returns true if the frame is embedded into Internet Explorer. 358 * The function checks the class name of the parent window of the embedded frame. 359 */ 360 BOOL AwtFrame::IsEmbeddedInIE(HWND hwndParent) 361 { 362 const char *pluginClass = "Java Plug-in Control Window"; 363 #define PARENT_CLASS_BUFFER_SIZE 64 364 char parentClass[PARENT_CLASS_BUFFER_SIZE]; 365 366 return (::GetClassNameA(hwndParent, parentClass, PARENT_CLASS_BUFFER_SIZE) > 0) 367 && (strncmp(parentClass, pluginClass, PARENT_CLASS_BUFFER_SIZE) == 0); 368 } 369 370 371 LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr) 372 { 373 LRESULT retValue = 0L; 374 375 AwtComponent *focusOwner = NULL; 376 AwtComponent *imeTargetComponent = NULL; 377 378 // IME and input language related messages need to be sent to a window 379 // which has the Java input focus 380 switch (message) { 381 case WM_IME_STARTCOMPOSITION: 382 case WM_IME_ENDCOMPOSITION: 383 case WM_IME_COMPOSITION: 384 case WM_IME_SETCONTEXT: 385 case WM_IME_NOTIFY: 386 case WM_IME_CONTROL: 387 case WM_IME_COMPOSITIONFULL: 388 case WM_IME_SELECT: 389 case WM_IME_CHAR: 390 case WM_IME_REQUEST: 391 case WM_IME_KEYDOWN: 392 case WM_IME_KEYUP: 393 case WM_INPUTLANGCHANGEREQUEST: 394 case WM_INPUTLANGCHANGE: 395 if (message == WM_IME_STARTCOMPOSITION) { 396 SetImeTargetComponent(sm_focusOwner); 397 } 398 imeTargetComponent = AwtComponent::GetComponent(GetImeTargetComponent()); 399 if (imeTargetComponent != NULL && 400 imeTargetComponent != this) // avoid recursive calls 401 { 402 retValue = imeTargetComponent->WindowProc(message, wParam, lParam); 403 mr = mrConsume; 404 } 405 if (message == WM_IME_ENDCOMPOSITION) { 406 SetImeTargetComponent(NULL); 407 } 408 break; 409 case WM_SETFOCUS: 410 if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain 411 412 if (!sm_suppressFocusAndActivation) { 413 if (IsLightweightFrame() || IsEmbeddedFrame()) { 414 AwtSetActiveWindow(); 415 } 416 } 417 mr = mrConsume; 418 break; 419 case WM_KILLFOCUS: 420 if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain 421 422 if (!sm_suppressFocusAndActivation) { 423 if (IsLightweightFrame() || IsEmbeddedFrame()) { 424 HWND oppositeToplevelHWnd = AwtComponent::GetTopLevelParentForWindow((HWND)wParam); 425 if (oppositeToplevelHWnd != AwtComponent::GetFocusedWindow()) { 426 AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL); 427 } 428 } 429 } else if (sm_restoreFocusAndActivation) { 430 if (AwtComponent::GetFocusedWindow() != NULL) { 431 AwtWindow *focusedWindow = (AwtWindow*)GetComponent(AwtComponent::GetFocusedWindow()); 432 if (focusedWindow != NULL) { 433 // Will just silently restore native focus & activation. 434 focusedWindow->AwtSetActiveWindow(); 435 } 436 } 437 } 438 mr = mrConsume; 439 break; 440 case 0x0127: // WM_CHANGEUISTATE 441 case 0x0128: // WM_UPDATEUISTATE 442 mr = mrConsume; 443 break; 444 } 445 446 return retValue; 447 } 448 449 LRESULT AwtFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 450 { 451 MsgRouting mr = mrDoDefault; 452 LRESULT retValue = 0L; 453 454 retValue = ProxyWindowProc(message, wParam, lParam, mr); 455 456 if (mr != mrConsume) { 457 retValue = AwtWindow::WindowProc(message, wParam, lParam); 458 } 459 return retValue; 460 } 461 462 MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status) 463 { 464 /* 465 * Fix for 6492970. 466 * When a non-focusable toplevel is shown alone the Java process 467 * is not foreground. If one shows another (focusable) toplevel 468 * the native platform not always makes it foreground (see the CR). 469 * Even worse, sometimes it sends the newly shown toplevel WM_ACTIVATE 470 * message. This breaks Java focus. To workaround the problem we 471 * set the toplevel being shown foreground programmatically. 472 * The fix is localized to non-foreground process case only. 473 * (See also: 6599270) 474 */ 475 if (!IsEmbeddedFrame() && show == TRUE && status == 0) { 476 HWND fgHWnd = ::GetForegroundWindow(); 477 if (fgHWnd != NULL) { 478 DWORD fgProcessID; 479 ::GetWindowThreadProcessId(fgHWnd, &fgProcessID); 480 481 if (fgProcessID != ::GetCurrentProcessId()) { 482 AwtWindow* window = (AwtWindow*)GetComponent(GetHWnd()); 483 484 if (window != NULL && 485 window->IsFocusableWindow() && 486 window->IsAutoRequestFocus() && 487 !::IsWindowVisible(GetHWnd()) && // the window is really showing 488 !::IsWindow(GetModalBlocker(GetHWnd()))) 489 { 490 // When the Java process is not allowed to set the foreground window 491 // (see MSDN) the request below will just have no effect. 492 ::SetForegroundWindow(GetHWnd()); 493 } 494 } 495 } 496 } 497 return AwtWindow::WmShowWindow(show, status); 498 } 499 500 MsgRouting AwtFrame::WmMouseUp(UINT flags, int x, int y, int button) { 501 if (isInManualMoveOrSize) { 502 isInManualMoveOrSize = FALSE; 503 ::ReleaseCapture(); 504 return mrConsume; 505 } 506 return AwtWindow::WmMouseUp(flags, x, y, button); 507 } 508 509 MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) { 510 /** 511 * If this Frame is non-focusable then we should implement move and size operation for it by 512 * ourselfves because we don't dispatch appropriate mouse messages to default window procedure. 513 */ 514 if (!IsFocusableWindow() && isInManualMoveOrSize) { 515 DWORD curPos = ::GetMessagePos(); 516 x = GET_X_LPARAM(curPos); 517 y = GET_Y_LPARAM(curPos); 518 RECT r; 519 ::GetWindowRect(GetHWnd(), &r); 520 POINT mouseLoc = {x, y}; 521 mouseLoc.x -= savedMousePos.x; 522 mouseLoc.y -= savedMousePos.y; 523 savedMousePos.x = x; 524 savedMousePos.y = y; 525 if (grabbedHitTest == HTCAPTION) { 526 ::SetWindowPos(GetHWnd(), NULL, r.left+mouseLoc.x, r.top+mouseLoc.y, 527 r.right-r.left, r.bottom-r.top, 528 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); 529 } else { 530 switch (grabbedHitTest) { 531 case HTTOP: 532 r.top += mouseLoc.y; 533 break; 534 case HTBOTTOM: 535 r.bottom += mouseLoc.y; 536 break; 537 case HTRIGHT: 538 r.right += mouseLoc.x; 539 break; 540 case HTLEFT: 541 r.left += mouseLoc.x; 542 break; 543 case HTTOPLEFT: 544 r.left += mouseLoc.x; 545 r.top += mouseLoc.y; 546 break; 547 case HTTOPRIGHT: 548 r.top += mouseLoc.y; 549 r.right += mouseLoc.x; 550 break; 551 case HTBOTTOMLEFT: 552 r.left += mouseLoc.x; 553 r.bottom += mouseLoc.y; 554 break; 555 case HTBOTTOMRIGHT: 556 case HTSIZE: 557 r.right += mouseLoc.x; 558 r.bottom += mouseLoc.y; 559 break; 560 } 561 562 ::SetWindowPos(GetHWnd(), NULL, r.left, r.top, 563 r.right-r.left, r.bottom-r.top, 564 SWP_NOACTIVATE | SWP_NOZORDER | 565 SWP_NOCOPYBITS | SWP_DEFERERASE); 566 } 567 return mrConsume; 568 } else { 569 return AwtWindow::WmMouseMove(flags, x, y); 570 } 571 } 572 573 MsgRouting AwtFrame::WmNcMouseUp(WPARAM hitTest, int x, int y, int button) { 574 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) { 575 /* 576 * Fix for 6399659. 577 * The native system shouldn't activate the next window in z-order 578 * when minimizing non-focusable window. 579 */ 580 if (hitTest == HTMINBUTTON) { 581 ::ShowWindow(GetHWnd(), SW_SHOWMINNOACTIVE); 582 return mrConsume; 583 } 584 /** 585 * If this Frame is non-focusable then we should implement move and size operation for it by 586 * ourselfves because we don't dispatch appropriate mouse messages to default window procedure. 587 */ 588 if ((button & DBL_CLICK) && hitTest == HTCAPTION) { 589 // Double click on caption - maximize or restore Frame. 590 if (IsResizable()) { 591 if (::IsZoomed(GetHWnd())) { 592 ::ShowWindow(GetHWnd(), SW_SHOWNOACTIVATE); 593 } else { 594 ::ShowWindow(GetHWnd(), SW_MAXIMIZE); 595 } 596 } 597 return mrConsume; 598 } 599 switch (hitTest) { 600 case HTMAXBUTTON: 601 if (IsResizable()) { 602 if (::IsZoomed(GetHWnd())) { 603 ::ShowWindow(GetHWnd(), SW_SHOWNOACTIVATE); 604 } else { 605 ::ShowWindow(GetHWnd(), SW_MAXIMIZE); 606 } 607 } 608 return mrConsume; 609 default: 610 return mrDoDefault; 611 } 612 } 613 return AwtWindow::WmNcMouseUp(hitTest, x, y, button); 614 } 615 616 MsgRouting AwtFrame::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { 617 // By Swing request, click on the Frame's decorations (even on 618 // grabbed Frame) should generate UngrabEvent 619 if (m_grabbedWindow != NULL/* && !m_grabbedWindow->IsOneOfOwnersOf(this)*/) { 620 m_grabbedWindow->Ungrab(); 621 } 622 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) { 623 switch (hitTest) { 624 case HTTOP: 625 case HTBOTTOM: 626 case HTLEFT: 627 case HTRIGHT: 628 case HTTOPLEFT: 629 case HTTOPRIGHT: 630 case HTBOTTOMLEFT: 631 case HTBOTTOMRIGHT: 632 case HTSIZE: 633 // Zoomed or non-resizable unfocusable frames should not be resizable. 634 if (isZoomed() || !IsResizable()) { 635 return mrConsume; 636 } 637 case HTCAPTION: 638 // We are going to perform default mouse action on non-client area of this window 639 // Grab mouse for this purpose and store coordinates for motion vector calculation 640 savedMousePos.x = x; 641 savedMousePos.y = y; 642 ::SetCapture(GetHWnd()); 643 isInManualMoveOrSize = TRUE; 644 grabbedHitTest = hitTest; 645 return mrConsume; 646 default: 647 return mrDoDefault; 648 } 649 } 650 return AwtWindow::WmNcMouseDown(hitTest, x, y, button); 651 } 652 653 // Override AwtWindow::Reshape() to handle minimized/maximized 654 // frames (see 6525850, 4065534) 655 void AwtFrame::Reshape(int x, int y, int width, int height) 656 { 657 if (isIconic()) { 658 // normal AwtComponent::Reshape will not work for iconified windows so... 659 WINDOWPLACEMENT wp; 660 POINT ptMinPosition = {x,y}; 661 POINT ptMaxPosition = {0,0}; 662 RECT rcNormalPosition = {x,y,x+width,y+height}; 663 RECT rcWorkspace; 664 HWND hWndDesktop = GetDesktopWindow(); 665 HWND hWndSelf = GetHWnd(); 666 667 // SetWindowPlacement takes workspace coordinates, but 668 // if taskbar is at top of screen, workspace coords != 669 // screen coords, so offset by workspace origin 670 VERIFY(::SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&rcWorkspace, 0)); 671 ::OffsetRect(&rcNormalPosition, -rcWorkspace.left, -rcWorkspace.top); 672 673 // set the window size for when it is not-iconified 674 wp.length = sizeof(wp); 675 wp.flags = WPF_SETMINPOSITION; 676 wp.showCmd = IsVisible() ? SW_SHOWMINIMIZED : SW_HIDE; 677 wp.ptMinPosition = ptMinPosition; 678 wp.ptMaxPosition = ptMaxPosition; 679 wp.rcNormalPosition = rcNormalPosition; 680 681 // If the call is not guarded with ignoreWmSize, 682 // a regression for bug 4851435 appears. 683 // Having this call guarded also prevents 684 // changing the iconified state of the frame 685 // while calling the Frame.setBounds() method. 686 m_ignoreWmSize = TRUE; 687 ::SetWindowPlacement(hWndSelf, &wp); 688 m_ignoreWmSize = FALSE; 689 690 return; 691 } 692 693 if (isZoomed()) { 694 // setting size of maximized window, we remove the 695 // maximized state bit (matches Motif behaviour) 696 // (calling ShowWindow(SW_RESTORE) would fire an 697 // activation event which we don't want) 698 HWND hWnd = GetHWnd(); 699 if (hWnd != NULL && ::IsWindowVisible(hWnd)) { 700 LONG style = GetStyle(); 701 DASSERT(style & WS_MAXIMIZE); 702 style ^= WS_MAXIMIZE; 703 SetStyle(style); 704 } 705 } 706 707 AwtWindow::Reshape(x, y, width, height); 708 } 709 710 711 /* Show the frame in it's current state */ 712 void 713 AwtFrame::Show() 714 { 715 m_visible = true; 716 HWND hwnd = GetHWnd(); 717 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 718 719 if (IsLightweightFrame()) { 720 return; 721 } 722 723 DTRACE_PRINTLN3("AwtFrame::Show:%s%s%s", 724 m_iconic ? " iconic" : "", 725 m_zoomed ? " zoomed" : "", 726 m_iconic || m_zoomed ? "" : " normal"); 727 728 BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID); 729 730 if (locationByPlatform) { 731 moveToDefaultLocation(); 732 } 733 EnableTranslucency(TRUE); 734 735 BOOL autoRequestFocus = IsAutoRequestFocus(); 736 737 if (m_iconic) { 738 if (m_zoomed) { 739 // This whole function could probably be rewritten to use 740 // ::SetWindowPlacement but MS docs doesn't tell if 741 // ::SetWindowPlacement is a proper superset of 742 // ::ShowWindow. So let's be conservative and only use it 743 // here, where we really do need it. 744 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED"); 745 WINDOWPLACEMENT wp; 746 ::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT)); 747 wp.length = sizeof(WINDOWPLACEMENT); 748 ::GetWindowPlacement(hwnd, &wp); 749 if (!IsFocusableWindow() || !autoRequestFocus) { 750 wp.showCmd = SW_SHOWMINNOACTIVE; 751 } else { 752 wp.showCmd = SW_SHOWMINIMIZED; 753 } 754 wp.flags |= WPF_RESTORETOMAXIMIZED; 755 ::SetWindowPlacement(hwnd, &wp); 756 } 757 else { 758 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMINIMIZED)"); 759 if (!IsFocusableWindow() || !autoRequestFocus) { 760 ::ShowWindow(hwnd, SW_SHOWMINNOACTIVE); 761 } else { 762 ::ShowWindow(hwnd, SW_SHOWMINIMIZED); 763 } 764 } 765 } 766 else if (m_zoomed) { 767 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWMAXIMIZED)"); 768 if (!autoRequestFocus) { 769 770 m_filterFocusAndActivation = TRUE; 771 ::ShowWindow(hwnd, SW_MAXIMIZE); 772 m_filterFocusAndActivation = FALSE; 773 774 } else if (!IsFocusableWindow()) { 775 ::ShowWindow(hwnd, SW_MAXIMIZE); 776 } else { 777 ::ShowWindow(hwnd, SW_SHOWMAXIMIZED); 778 } 779 } 780 else if (m_isInputMethodWindow) { 781 // Don't activate input methow window 782 DTRACE_PRINTLN("AwtFrame::Show(SW_SHOWNA)"); 783 ::ShowWindow(hwnd, SW_SHOWNA); 784 785 // After the input method window shown, we have to adjust the 786 // IME candidate window position. Here is why. 787 // Usually, when IMM opens the candidate window, it sends WM_IME_NOTIFY w/ 788 // IMN_OPENCANDIDATE message to the awt component window. The 789 // awt component makes a Java call to acquire the text position 790 // in order to show the candidate window just below the input method window. 791 // However, by the time it acquires the position, the input method window 792 // hasn't been displayed yet, the position returned is just below 793 // the composed text and when the input method window is shown, it 794 // will hide part of the candidate list. To fix this, we have to 795 // adjust the candidate window position after the input method window 796 // is shown. See bug 5012944. 797 AdjustCandidateWindowPos(); 798 } 799 else { 800 // Nor iconic, nor zoomed (handled above) - so use SW_RESTORE 801 // to show in "normal" state regardless of whatever stale 802 // state might the invisible window still has. 803 DTRACE_PRINTLN("AwtFrame::Show(SW_RESTORE)"); 804 if (!IsFocusableWindow() || !autoRequestFocus) { 805 ::ShowWindow(hwnd, SW_SHOWNOACTIVATE); 806 } else { 807 ::ShowWindow(hwnd, SW_RESTORE); 808 } 809 } 810 } 811 812 void 813 AwtFrame::SendWindowStateEvent(int oldState, int newState) 814 { 815 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_STATE_CHANGED, 816 NULL, oldState, newState); 817 } 818 819 void 820 AwtFrame::ClearMaximizedBounds() 821 { 822 m_maxBoundsSet = FALSE; 823 } 824 825 void AwtFrame::AdjustCandidateWindowPos() 826 { 827 // This method should only be called if the current frame 828 // is the input method window frame. 829 if (!m_isInputMethodWindow) { 830 return; 831 } 832 833 RECT inputWinRec, focusWinRec; 834 AwtComponent *comp = AwtComponent::GetComponent(AwtComponent::sm_focusOwner); 835 if (comp == NULL) { 836 return; 837 } 838 839 ::GetWindowRect(GetHWnd(), &inputWinRec); 840 ::GetWindowRect(sm_focusOwner, &focusWinRec); 841 842 LPARAM candType = comp->GetCandidateType(); 843 HWND defaultIMEWnd = ::ImmGetDefaultIMEWnd(GetHWnd()); 844 if (defaultIMEWnd == NULL) { 845 return; 846 } 847 UINT bits = 1; 848 // adjusts the candidate window position 849 for (int iCandType = 0; iCandType < 32; iCandType++, bits<<=1) { 850 if (candType & bits) { 851 CANDIDATEFORM cf; 852 cf.dwIndex = iCandType; 853 cf.dwStyle = CFS_CANDIDATEPOS; 854 // Since the coordinates are relative to the containing window, 855 // we have to calculate the coordinates as below. 856 cf.ptCurrentPos.x = inputWinRec.left - focusWinRec.left; 857 cf.ptCurrentPos.y = inputWinRec.bottom - focusWinRec.top; 858 859 // sends IMC_SETCANDIDATEPOS to IMM to move the candidate window. 860 ::SendMessage(defaultIMEWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS, (LPARAM)&cf); 861 } 862 } 863 } 864 865 void 866 AwtFrame::SetMaximizedBounds(int x, int y, int w, int h) 867 { 868 m_maxPos.x = x; 869 m_maxPos.y = y; 870 m_maxSize.x = w; 871 m_maxSize.y = h; 872 m_maxBoundsSet = TRUE; 873 } 874 875 MsgRouting AwtFrame::WmGetMinMaxInfo(LPMINMAXINFO lpmmi) 876 { 877 //Firstly call AwtWindow's function 878 MsgRouting r = AwtWindow::WmGetMinMaxInfo(lpmmi); 879 880 //Then replace maxPos & maxSize if necessary 881 if (!m_maxBoundsSet) { 882 return r; 883 } 884 885 if (m_maxPos.x != java_lang_Integer_MAX_VALUE) 886 lpmmi->ptMaxPosition.x = m_maxPos.x; 887 if (m_maxPos.y != java_lang_Integer_MAX_VALUE) 888 lpmmi->ptMaxPosition.y = m_maxPos.y; 889 if (m_maxSize.x != java_lang_Integer_MAX_VALUE) 890 lpmmi->ptMaxSize.x = m_maxSize.x; 891 if (m_maxSize.y != java_lang_Integer_MAX_VALUE) 892 lpmmi->ptMaxSize.y = m_maxSize.y; 893 return mrConsume; 894 } 895 896 MsgRouting AwtFrame::WmWindowPosChanging(LPARAM windowPos) { 897 if (::IsZoomed(GetHWnd()) && m_maxBoundsSet) { 898 // Limits the size of the maximized window, effectively cuts the 899 // adjustments added by the window manager 900 WINDOWPOS *wp = (WINDOWPOS *) windowPos; 901 if (m_maxSize.x < java_lang_Integer_MAX_VALUE && wp->cx > m_maxSize.x) { 902 wp->cx = m_maxSize.x; 903 } 904 if (m_maxSize.y < java_lang_Integer_MAX_VALUE && wp->cy > m_maxSize.y) { 905 wp->cy = m_maxSize.y; 906 } 907 } 908 return AwtWindow::WmWindowPosChanging(windowPos); 909 } 910 911 MsgRouting AwtFrame::WmSize(UINT type, int w, int h) 912 { 913 currentWmSizeState = type; 914 if (currentWmSizeState == SIZE_MINIMIZED) { 915 UpdateSecurityWarningVisibility(); 916 } 917 918 if (m_ignoreWmSize) { 919 return mrDoDefault; 920 } 921 922 DTRACE_PRINTLN6("AwtFrame::WmSize: %dx%d,%s visible, state%s%s%s", 923 w, h, 924 ::IsWindowVisible(GetHWnd()) ? "" : " not", 925 m_iconic ? " iconic" : "", 926 m_zoomed ? " zoomed" : "", 927 m_iconic || m_zoomed ? "" : " normal"); 928 929 BOOL iconify = type == SIZE_MINIMIZED; 930 931 // Note that zoom may be set to TRUE in several cases: 932 // 1. type == SIZE_MAXIMIZED means that either the user or 933 // the developer (via setExtendedState(MAXIMIZED_BOTH) 934 // maximizes the frame. 935 // 2. type == SIZE_MINIMIZED && isZoomed() means that a maximized 936 // frame is to be minimized. If the user minimizes a maximized 937 // frame, we need to keep the zoomed property TRUE. However, 938 // if the developer calls setExtendedState(ICONIFIED), i.e. 939 // w/o combining the ICONIFIED state with the MAXIMIZED state, 940 // we MUST RESET the zoomed property. 941 // The flag m_forceResetZoomed identifies the latter case. 942 BOOL zoom = 943 ( 944 type == SIZE_MAXIMIZED 945 || 946 (type == SIZE_MINIMIZED && isZoomed()) 947 ) 948 && !m_forceResetZoomed; 949 950 // Set the new state and send appropriate Java event 951 jint oldState = java_awt_Frame_NORMAL; 952 if (isIconic()) { 953 oldState |= java_awt_Frame_ICONIFIED; 954 } 955 if (isZoomed()) { 956 oldState |= java_awt_Frame_MAXIMIZED_BOTH; 957 } 958 959 jint newState = java_awt_Frame_NORMAL; 960 if (iconify) { 961 newState |= java_awt_Frame_ICONIFIED; 962 } 963 if (zoom) { 964 newState |= java_awt_Frame_MAXIMIZED_BOTH; 965 } 966 967 setIconic(iconify); 968 setZoomed(zoom); 969 970 jint changed = oldState ^ newState; 971 if (changed != 0) { 972 DTRACE_PRINTLN2("AwtFrame::WmSize: reporting state change %x -> %x", 973 oldState, newState); 974 975 // sync target with peer 976 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 977 env->CallVoidMethod(GetPeer(env), AwtFrame::setExtendedStateMID, newState); 978 979 // report (de)iconification to old clients 980 if (changed & java_awt_Frame_ICONIFIED) { 981 if (newState & java_awt_Frame_ICONIFIED) { 982 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_ICONIFIED); 983 } else { 984 SendWindowEvent(java_awt_event_WindowEvent_WINDOW_DEICONIFIED); 985 } 986 } 987 988 // New (since 1.4) state change event 989 SendWindowStateEvent(oldState, newState); 990 } 991 992 // If window is in iconic state, do not send COMPONENT_RESIZED event 993 if (isIconic()) { 994 return mrDoDefault; 995 } 996 997 return AwtWindow::WmSize(type, w, h); 998 } 999 1000 MsgRouting AwtFrame::WmActivate(UINT nState, BOOL fMinimized, HWND opposite) 1001 { 1002 jint type; 1003 1004 if (nState != WA_INACTIVE) { 1005 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())) || 1006 CheckActivateActualFocusedWindow(opposite)) 1007 { 1008 return mrConsume; 1009 } 1010 type = java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS; 1011 AwtComponent::SetFocusedWindow(GetHWnd()); 1012 1013 } else { 1014 if (::IsWindow(AwtWindow::GetModalBlocker(opposite))) { 1015 return mrConsume; 1016 } else { 1017 // If deactivation happens because of press on grabbing 1018 // window - this is nonsense, since grabbing window is 1019 // assumed to have focus and watch for deactivation. But 1020 // this can happen - if grabbing window is proxied Window, 1021 // with Frame keeping real focus for it. 1022 if (m_grabbedWindow != NULL) { 1023 if (m_grabbedWindow->GetHWnd() == opposite) { 1024 // Do nothing 1025 } else { 1026 // Normally, we would rather check that this == 1027 // grabbed window, and focus is leaving it - 1028 // ungrab. But since we know about proxied 1029 // windows, we simply assume this is one of the 1030 // known cases. 1031 if (!m_grabbedWindow->IsOneOfOwnersOf((AwtWindow*)AwtComponent::GetComponent(opposite))) { 1032 m_grabbedWindow->Ungrab(); 1033 } 1034 } 1035 } 1036 CheckRetainActualFocusedWindow(opposite); 1037 1038 type = java_awt_event_WindowEvent_WINDOW_LOST_FOCUS; 1039 AwtComponent::SetFocusedWindow(NULL); 1040 sm_focusOwner = NULL; 1041 } 1042 } 1043 1044 SendWindowEvent(type, opposite); 1045 return mrConsume; 1046 } 1047 1048 BOOL AwtFrame::CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd) 1049 { 1050 if (m_actualFocusedWindow != NULL) { 1051 HWND hwnd = m_actualFocusedWindow->GetHWnd(); 1052 if (hwnd != NULL && ::IsWindowVisible(hwnd)) { 1053 SynthesizeWmActivate(TRUE, hwnd, deactivatedOpositeHWnd); 1054 return TRUE; 1055 } 1056 m_actualFocusedWindow = NULL; 1057 } 1058 return FALSE; 1059 } 1060 1061 void AwtFrame::CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd) 1062 { 1063 // If actual focused window is not this Frame 1064 if (AwtComponent::GetFocusedWindow() != GetHWnd()) { 1065 // Make sure the actual focused window is an owned window of this frame 1066 AwtWindow *focusedWindow = (AwtWindow *)AwtComponent::GetComponent(AwtComponent::GetFocusedWindow()); 1067 if (focusedWindow != NULL && focusedWindow->GetOwningFrameOrDialog() == this) { 1068 1069 // Check that the opposite window is not this frame, nor an owned window of this frame 1070 if (activatedOpositeHWnd != NULL) { 1071 AwtWindow *oppositeWindow = (AwtWindow *)AwtComponent::GetComponent(activatedOpositeHWnd); 1072 if (oppositeWindow && oppositeWindow != this && 1073 oppositeWindow->GetOwningFrameOrDialog() != this) 1074 { 1075 m_actualFocusedWindow = focusedWindow; 1076 } 1077 } else { 1078 m_actualFocusedWindow = focusedWindow; 1079 } 1080 } 1081 } 1082 } 1083 1084 BOOL AwtFrame::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest) 1085 { 1086 if (hittest == HTCLIENT) { 1087 // Don't let the actualFocusedWindow to steal focus if: 1088 // a) the frame is clicked in its client area; 1089 // b) focus is requested to some of the frame's child. 1090 m_actualFocusedWindow = NULL; 1091 } 1092 if (IsLightweightFrame()) { 1093 return TRUE; 1094 } 1095 if (isMouseEventCause && IsEmbeddedFrame() && m_isEmbeddedInIE) { 1096 HWND hwndProxy = GetProxyFocusOwner(); 1097 // Do nothing if this frame is focused already 1098 if (::GetFocus() != hwndProxy) { 1099 // Fix for JDK-8056915: 1100 // If window activated with mouse, set focus to plugin control window 1101 // first to preserve focus owner inside browser window 1102 if (SetFocusToPluginControl(::GetParent(GetHWnd()))) { 1103 return TRUE; 1104 } 1105 // Plugin control window is already focused, so do normal processing 1106 } 1107 } 1108 return AwtWindow::AwtSetActiveWindow(isMouseEventCause); 1109 } 1110 1111 MsgRouting AwtFrame::WmEnterMenuLoop(BOOL isTrackPopupMenu) 1112 { 1113 if ( !isTrackPopupMenu ) { 1114 m_isMenuDropped = TRUE; 1115 } 1116 return mrDoDefault; 1117 } 1118 1119 MsgRouting AwtFrame::WmExitMenuLoop(BOOL isTrackPopupMenu) 1120 { 1121 if ( !isTrackPopupMenu ) { 1122 m_isMenuDropped = FALSE; 1123 } 1124 return mrDoDefault; 1125 } 1126 1127 AwtMenuBar* AwtFrame::GetMenuBar() 1128 { 1129 return menuBar; 1130 } 1131 1132 void AwtFrame::SetMenuBar(AwtMenuBar* mb) 1133 { 1134 if (menuBar) { 1135 menuBar->SetFrame(NULL); 1136 } 1137 menuBar = mb; 1138 if (mb == NULL) { 1139 // Remove existing menu bar, if any. 1140 ::SetMenu(GetHWnd(), NULL); 1141 } else { 1142 AwtFrame* oldFrame = menuBar->GetFrame(); 1143 if (oldFrame && oldFrame != this) { 1144 oldFrame->SetMenuBar(NULL); 1145 } 1146 menuBar->SetFrame(this); 1147 if (menuBar->GetHMenu() != NULL) { 1148 ::SetMenu(GetHWnd(), menuBar->GetHMenu()); 1149 } 1150 } 1151 } 1152 1153 MsgRouting AwtFrame::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT& drawInfo) 1154 { 1155 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1156 1157 // if the item to be redrawn is the menu bar, then do it 1158 AwtMenuBar* awtMenubar = GetMenuBar(); 1159 if (drawInfo.CtlType == ODT_MENU && (awtMenubar != NULL) && 1160 (::GetMenu( GetHWnd() ) == (HMENU)drawInfo.hwndItem) ) 1161 { 1162 awtMenubar->DrawItem(drawInfo); 1163 return mrConsume; 1164 } 1165 1166 return AwtComponent::WmDrawItem(ctrlId, drawInfo); 1167 } 1168 1169 MsgRouting AwtFrame::WmMeasureItem(UINT ctrlId, MEASUREITEMSTRUCT& measureInfo) 1170 { 1171 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1172 AwtMenuBar* awtMenubar = GetMenuBar(); 1173 if ((measureInfo.CtlType == ODT_MENU) && (awtMenubar != NULL)) 1174 { 1175 // AwtMenu instance is stored in itemData. Use it to check if this 1176 // menu is the menu bar. 1177 AwtMenu * pMenu = (AwtMenu *) measureInfo.itemData; 1178 DASSERT(pMenu != NULL); 1179 if ( pMenu == awtMenubar ) 1180 { 1181 HWND hWnd = GetHWnd(); 1182 HDC hDC = ::GetDC(hWnd); 1183 DASSERT(hDC != NULL); 1184 awtMenubar->MeasureItem(hDC, measureInfo); 1185 VERIFY(::ReleaseDC(hWnd, hDC)); 1186 return mrConsume; 1187 } 1188 } 1189 1190 return AwtComponent::WmMeasureItem(ctrlId, measureInfo); 1191 } 1192 1193 MsgRouting AwtFrame::WmGetIcon(WPARAM iconType, LRESULT& retVal) 1194 { 1195 //Workaround windows bug: 1196 //when reseting from specific icon to class icon 1197 //taskbar is not updated 1198 if (iconType <= 2 /*ICON_SMALL2*/) { 1199 retVal = (LRESULT)GetEffectiveIcon(iconType); 1200 return mrConsume; 1201 } else { 1202 return mrDoDefault; 1203 } 1204 } 1205 1206 void AwtFrame::DoUpdateIcon() 1207 { 1208 //Workaround windows bug: 1209 //when reseting from specific icon to class icon 1210 //taskbar is not updated 1211 HICON hIcon = GetEffectiveIcon(ICON_BIG); 1212 HICON hIconSm = GetEffectiveIcon(ICON_SMALL); 1213 SendMessage(WM_SETICON, ICON_BIG, (LPARAM)hIcon); 1214 SendMessage(WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); 1215 } 1216 1217 HICON AwtFrame::GetEffectiveIcon(int iconType) 1218 { 1219 BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/)); 1220 HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon(); 1221 if (hIcon == NULL) { 1222 hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() : 1223 AwtToolkit::GetInstance().GetAwtIcon(); 1224 } 1225 return hIcon; 1226 } 1227 1228 static BOOL keepOnMinimize(jobject peer) { 1229 static BOOL checked = FALSE; 1230 static BOOL keep = FALSE; 1231 if (!checked) { 1232 keep = (JNU_GetStaticFieldByName(AwtToolkit::GetEnv(), NULL, 1233 "sun/awt/windows/WFramePeer", "keepOnMinimize", "Z").z) == JNI_TRUE; 1234 checked = TRUE; 1235 } 1236 return keep; 1237 } 1238 1239 MsgRouting AwtFrame::WmSysCommand(UINT uCmdType, int xPos, int yPos) 1240 { 1241 // ignore any WM_SYSCOMMAND if this window is blocked by modal dialog 1242 if (::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()))) { 1243 return mrConsume; 1244 } 1245 1246 if (uCmdType == (SYSCOMMAND_IMM & 0xFFF0)){ 1247 JNIEnv* env = AwtToolkit::GetEnv(); 1248 JNU_CallMethodByName(env, NULL, m_peerObject, 1249 "notifyIMMOptionChange", "()V"); 1250 DASSERT(!safe_ExceptionOccurred(env)); 1251 return mrConsume; 1252 } 1253 if ((uCmdType == SC_MINIMIZE) && keepOnMinimize(m_peerObject)) { 1254 ::ShowWindow(GetHWnd(),SW_SHOWMINIMIZED); 1255 return mrConsume; 1256 } 1257 return AwtWindow::WmSysCommand(uCmdType, xPos, yPos); 1258 } 1259 1260 LRESULT AwtFrame::WinThreadExecProc(ExecuteArgs * args) 1261 { 1262 switch( args->cmdId ) { 1263 case FRAME_SETMENUBAR: 1264 { 1265 jobject mbPeer = (jobject)args->param1; 1266 1267 // cancel any currently dropped down menus 1268 if (m_isMenuDropped) { 1269 SendMessage(WM_CANCELMODE); 1270 } 1271 1272 if (mbPeer == NULL) { 1273 // Remove existing menu bar, if any 1274 SetMenuBar(NULL); 1275 } else { 1276 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1277 AwtMenuBar* menuBar = (AwtMenuBar *)JNI_GET_PDATA(mbPeer); 1278 SetMenuBar(menuBar); 1279 } 1280 DrawMenuBar(); 1281 break; 1282 } 1283 1284 default: 1285 AwtWindow::WinThreadExecProc(args); 1286 break; 1287 } 1288 1289 return 0L; 1290 } 1291 1292 void AwtFrame::_SynthesizeWmActivate(void *param) 1293 { 1294 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1295 1296 SynthesizeWmActivateStruct *sas = (SynthesizeWmActivateStruct *)param; 1297 jobject self = sas->frame; 1298 jboolean doActivate = sas->doActivate; 1299 1300 AwtFrame *frame = NULL; 1301 1302 PDATA pData; 1303 JNI_CHECK_PEER_GOTO(self, ret); 1304 frame = (AwtFrame *)pData; 1305 1306 SynthesizeWmActivate(doActivate, frame->GetHWnd(), NULL); 1307 ret: 1308 env->DeleteGlobalRef(self); 1309 1310 delete sas; 1311 } 1312 1313 jobject AwtFrame::_GetBoundsPrivate(void *param) 1314 { 1315 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1316 1317 jobject self = (jobject)param; 1318 1319 jobject result = NULL; 1320 AwtFrame *f = NULL; 1321 1322 PDATA pData; 1323 JNI_CHECK_PEER_GOTO(self, ret); 1324 f = (AwtFrame *)pData; 1325 if (::IsWindow(f->GetHWnd())) 1326 { 1327 RECT rect; 1328 ::GetWindowRect(f->GetHWnd(), &rect); 1329 HWND parent = ::GetParent(f->GetHWnd()); 1330 if (::IsWindow(parent)) 1331 { 1332 POINT zero; 1333 zero.x = 0; 1334 zero.y = 0; 1335 ::ClientToScreen(parent, &zero); 1336 ::OffsetRect(&rect, -zero.x, -zero.y); 1337 } 1338 1339 result = JNU_NewObjectByName(env, "java/awt/Rectangle", "(IIII)V", 1340 rect.left, rect.top, rect.bottom-rect.top, rect.right-rect.left); 1341 } 1342 ret: 1343 env->DeleteGlobalRef(self); 1344 1345 if (result != NULL) 1346 { 1347 jobject resultGlobalRef = env->NewGlobalRef(result); 1348 env->DeleteLocalRef(result); 1349 return resultGlobalRef; 1350 } 1351 else 1352 { 1353 return NULL; 1354 } 1355 } 1356 1357 void AwtFrame::_SetState(void *param) 1358 { 1359 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1360 1361 SetStateStruct *sss = (SetStateStruct *)param; 1362 jobject self = sss->frame; 1363 jint state = sss->state; 1364 1365 AwtFrame *f = NULL; 1366 1367 PDATA pData; 1368 JNI_CHECK_PEER_GOTO(self, ret); 1369 f = (AwtFrame *)pData; 1370 HWND hwnd = f->GetHWnd(); 1371 if (::IsWindow(hwnd)) 1372 { 1373 DASSERT(!IsBadReadPtr(f, sizeof(AwtFrame))); 1374 1375 BOOL iconify = (state & java_awt_Frame_ICONIFIED) != 0; 1376 BOOL zoom = (state & java_awt_Frame_MAXIMIZED_BOTH) 1377 == java_awt_Frame_MAXIMIZED_BOTH; 1378 1379 DTRACE_PRINTLN4("WFramePeer.setState:%s%s ->%s%s", 1380 f->isIconic() ? " iconic" : "", 1381 f->isZoomed() ? " zoomed" : "", 1382 iconify ? " iconic" : "", 1383 zoom ? " zoomed" : ""); 1384 1385 if (::IsWindowVisible(hwnd)) { 1386 BOOL focusable = f->IsFocusableWindow(); 1387 1388 WINDOWPLACEMENT wp; 1389 ::ZeroMemory(&wp, sizeof(wp)); 1390 wp.length = sizeof(wp); 1391 ::GetWindowPlacement(hwnd, &wp); 1392 1393 // Iconify first. 1394 // If both iconify & zoom are TRUE, handle this case 1395 // with wp.flags field below. 1396 if (iconify) { 1397 wp.showCmd = focusable ? SW_MINIMIZE : SW_SHOWMINNOACTIVE; 1398 } else if (zoom) { 1399 wp.showCmd = focusable ? SW_SHOWMAXIMIZED : SW_MAXIMIZE; 1400 } else { // zoom == iconify == FALSE 1401 wp.showCmd = focusable ? SW_RESTORE : SW_SHOWNOACTIVATE; 1402 } 1403 if (zoom && iconify) { 1404 wp.flags |= WPF_RESTORETOMAXIMIZED; 1405 } else { 1406 wp.flags &= ~WPF_RESTORETOMAXIMIZED; 1407 } 1408 1409 if (!zoom) { 1410 f->m_forceResetZoomed = TRUE; 1411 } 1412 1413 // The SetWindowPlacement() causes the WmSize() invocation 1414 // which, in turn, actually updates the m_iconic & m_zoomed flags 1415 // as well as sends Java event (WINDOW_STATE_CHANGED.) 1416 ::SetWindowPlacement(hwnd, &wp); 1417 1418 f->m_forceResetZoomed = FALSE; 1419 } else { 1420 DTRACE_PRINTLN(" not visible, just recording the requested state"); 1421 1422 f->setIconic(iconify); 1423 f->setZoomed(zoom); 1424 } 1425 } 1426 ret: 1427 env->DeleteGlobalRef(self); 1428 1429 delete sss; 1430 } 1431 1432 jint AwtFrame::_GetState(void *param) 1433 { 1434 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1435 1436 jobject self = (jobject)param; 1437 1438 jint result = java_awt_Frame_NORMAL; 1439 AwtFrame *f = NULL; 1440 1441 PDATA pData; 1442 JNI_CHECK_PEER_GOTO(self, ret); 1443 f = (AwtFrame *)pData; 1444 if (::IsWindow(f->GetHWnd())) 1445 { 1446 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1447 if (f->isIconic()) { 1448 result |= java_awt_Frame_ICONIFIED; 1449 } 1450 if (f->isZoomed()) { 1451 result |= java_awt_Frame_MAXIMIZED_BOTH; 1452 } 1453 1454 DTRACE_PRINTLN2("WFramePeer.getState:%s%s", 1455 f->isIconic() ? " iconic" : "", 1456 f->isZoomed() ? " zoomed" : ""); 1457 } 1458 ret: 1459 env->DeleteGlobalRef(self); 1460 1461 return result; 1462 } 1463 1464 void AwtFrame::_SetMaximizedBounds(void *param) 1465 { 1466 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1467 1468 SetMaximizedBoundsStruct *smbs = (SetMaximizedBoundsStruct *)param; 1469 jobject self = smbs->frame; 1470 int x = smbs->x; 1471 int y = smbs->y; 1472 int width = smbs->width; 1473 int height = smbs->height; 1474 1475 AwtFrame *f = NULL; 1476 1477 PDATA pData; 1478 JNI_CHECK_PEER_GOTO(self, ret); 1479 f = (AwtFrame *)pData; 1480 if (::IsWindow(f->GetHWnd())) 1481 { 1482 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1483 f->SetMaximizedBounds(x, y, width, height); 1484 } 1485 ret: 1486 env->DeleteGlobalRef(self); 1487 1488 delete smbs; 1489 } 1490 1491 void AwtFrame::_ClearMaximizedBounds(void *param) 1492 { 1493 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1494 1495 jobject self = (jobject)param; 1496 1497 AwtFrame *f = NULL; 1498 1499 PDATA pData; 1500 JNI_CHECK_PEER_GOTO(self, ret); 1501 f = (AwtFrame *)pData; 1502 if (::IsWindow(f->GetHWnd())) 1503 { 1504 DASSERT(!::IsBadReadPtr(f, sizeof(AwtFrame))); 1505 f->ClearMaximizedBounds(); 1506 } 1507 ret: 1508 env->DeleteGlobalRef(self); 1509 } 1510 1511 void AwtFrame::_SetMenuBar(void *param) 1512 { 1513 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1514 1515 SetMenuBarStruct *smbs = (SetMenuBarStruct *)param; 1516 jobject self = smbs->frame; 1517 jobject menubar = smbs->menubar; 1518 1519 AwtFrame *f = NULL; 1520 1521 PDATA pData; 1522 JNI_CHECK_PEER_GOTO(self, ret); 1523 f = (AwtFrame *)pData; 1524 if (::IsWindow(f->GetHWnd())) 1525 { 1526 ExecuteArgs args; 1527 args.cmdId = FRAME_SETMENUBAR; 1528 args.param1 = (LPARAM)menubar; 1529 f->WinThreadExecProc(&args); 1530 } 1531 ret: 1532 env->DeleteGlobalRef(self); 1533 env->DeleteGlobalRef(menubar); 1534 1535 delete smbs; 1536 } 1537 1538 void AwtFrame::_SetIMMOption(void *param) 1539 { 1540 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1541 1542 SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param; 1543 jobject self = sios->frame; 1544 jstring option = sios->option; 1545 1546 int badAlloc = 0; 1547 LPCTSTR coption; 1548 LPCTSTR empty = TEXT("InputMethod"); 1549 AwtFrame *f = NULL; 1550 1551 PDATA pData; 1552 JNI_CHECK_PEER_GOTO(self, ret); 1553 JNI_CHECK_NULL_GOTO(option, "IMMOption argument", ret); 1554 1555 f = (AwtFrame *)pData; 1556 if (::IsWindow(f->GetHWnd())) 1557 { 1558 coption = JNU_GetStringPlatformChars(env, option, NULL); 1559 if (coption == NULL) 1560 { 1561 badAlloc = 1; 1562 } 1563 if (!badAlloc) 1564 { 1565 HMENU hSysMenu = ::GetSystemMenu(f->GetHWnd(), FALSE); 1566 ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption); 1567 1568 if (coption != empty) 1569 { 1570 JNU_ReleaseStringPlatformChars(env, option, coption); 1571 } 1572 } 1573 } 1574 ret: 1575 env->DeleteGlobalRef(self); 1576 env->DeleteGlobalRef(option); 1577 1578 delete sios; 1579 1580 if (badAlloc) 1581 { 1582 throw std::bad_alloc(); 1583 } 1584 } 1585 1586 void AwtFrame::_NotifyModalBlocked(void *param) 1587 { 1588 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 1589 1590 NotifyModalBlockedStruct *nmbs = (NotifyModalBlockedStruct *)param; 1591 jobject self = nmbs->frame; 1592 jobject peer = nmbs->peer; 1593 jobject blockerPeer = nmbs->blockerPeer; 1594 jboolean blocked = nmbs->blocked; 1595 1596 PDATA pData; 1597 1598 JNI_CHECK_PEER_GOTO(peer, ret); 1599 AwtFrame *f = (AwtFrame *)pData; 1600 1601 // dialog here may be NULL, for example, if the blocker is a native dialog 1602 // however, we need to install/unistall modal hooks anyway 1603 JNI_CHECK_PEER_GOTO(blockerPeer, ret); 1604 AwtDialog *d = (AwtDialog *)pData; 1605 1606 if ((f != NULL) && ::IsWindow(f->GetHWnd())) 1607 { 1608 // get an HWND of the toplevel window this embedded frame is within 1609 HWND fHWnd = f->GetHWnd(); 1610 while (::GetParent(fHWnd) != NULL) { 1611 fHWnd = ::GetParent(fHWnd); 1612 } 1613 // we must get a toplevel hwnd here, however due to some strange 1614 // behaviour of Java Plugin (a bug?) when running in IE at 1615 // this moment the embedded frame hasn't been placed into the 1616 // browser yet and fHWnd is not a toplevel, so we shouldn't install 1617 // the hook here 1618 if ((::GetWindowLong(fHWnd, GWL_STYLE) & WS_CHILD) == 0) { 1619 // if this toplevel is created in another thread, we should install 1620 // the modal hook into it to track window activation and mouse events 1621 DWORD fThread = ::GetWindowThreadProcessId(fHWnd, NULL); 1622 if (fThread != AwtToolkit::GetInstance().MainThread()) { 1623 // check if this thread has been already blocked 1624 BlockedThreadStruct *blockedThread = (BlockedThreadStruct *)sm_BlockedThreads.get((void *)((intptr_t)fThread)); 1625 if (blocked) { 1626 if (blockedThread == NULL) { 1627 blockedThread = new BlockedThreadStruct; 1628 blockedThread->framesCount = 1; 1629 blockedThread->modalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)AwtDialog::ModalFilterProc, 1630 0, fThread); 1631 blockedThread->mouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtDialog::MouseHookProc_NonTT, 1632 0, fThread); 1633 sm_BlockedThreads.put((void *)((intptr_t)fThread), blockedThread); 1634 } else { 1635 blockedThread->framesCount++; 1636 } 1637 } else { 1638 // see the comment above: if Java Plugin behaviour when running in IE 1639 // was right, blockedThread would be always not NULL here 1640 if (blockedThread != NULL) { 1641 DASSERT(blockedThread->framesCount > 0); 1642 if ((blockedThread->framesCount) == 1) { 1643 ::UnhookWindowsHookEx(blockedThread->modalHook); 1644 ::UnhookWindowsHookEx(blockedThread->mouseHook); 1645 sm_BlockedThreads.remove((void *)((intptr_t)fThread)); 1646 delete blockedThread; 1647 } else { 1648 blockedThread->framesCount--; 1649 } 1650 } 1651 } 1652 } 1653 } 1654 } 1655 ret: 1656 env->DeleteGlobalRef(self); 1657 env->DeleteGlobalRef(peer); 1658 env->DeleteGlobalRef(blockerPeer); 1659 1660 delete nmbs; 1661 } 1662 1663 /************************************************************************ 1664 * WFramePeer native methods 1665 */ 1666 1667 extern "C" { 1668 1669 /* 1670 * Class: java_awt_Frame 1671 * Method: initIDs 1672 * Signature: ()V 1673 */ 1674 JNIEXPORT void JNICALL 1675 Java_java_awt_Frame_initIDs(JNIEnv *env, jclass cls) 1676 { 1677 TRY; 1678 1679 AwtFrame::undecoratedID = env->GetFieldID(cls,"undecorated","Z"); 1680 DASSERT(AwtFrame::undecoratedID != NULL); 1681 1682 CATCH_BAD_ALLOC; 1683 } 1684 1685 /* 1686 * Class: sun_awt_windows_WFramePeer 1687 * Method: initIDs 1688 * Signature: ()V 1689 */ 1690 JNIEXPORT void JNICALL 1691 Java_sun_awt_windows_WFramePeer_initIDs(JNIEnv *env, jclass cls) 1692 { 1693 TRY; 1694 1695 AwtFrame::setExtendedStateMID = env->GetMethodID(cls, "setExtendedState", "(I)V"); 1696 DASSERT(AwtFrame::setExtendedStateMID); 1697 CHECK_NULL(AwtFrame::setExtendedStateMID); 1698 1699 AwtFrame::getExtendedStateMID = env->GetMethodID(cls, "getExtendedState", "()I"); 1700 DASSERT(AwtFrame::getExtendedStateMID); 1701 1702 CATCH_BAD_ALLOC; 1703 } 1704 1705 /* 1706 * Class: sun_awt_windows_WFramePeer 1707 * Method: setState 1708 * Signature: (I)V 1709 */ 1710 JNIEXPORT void JNICALL 1711 Java_sun_awt_windows_WFramePeer_setState(JNIEnv *env, jobject self, 1712 jint state) 1713 { 1714 TRY; 1715 1716 SetStateStruct *sss = new SetStateStruct; 1717 sss->frame = env->NewGlobalRef(self); 1718 sss->state = state; 1719 1720 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetState, sss); 1721 // global ref and sss are deleted in _SetState() 1722 1723 CATCH_BAD_ALLOC; 1724 } 1725 1726 /* 1727 * Class: sun_awt_windows_WFramePeer 1728 * Method: getState 1729 * Signature: ()I 1730 */ 1731 JNIEXPORT jint JNICALL 1732 Java_sun_awt_windows_WFramePeer_getState(JNIEnv *env, jobject self) 1733 { 1734 TRY; 1735 1736 jobject selfGlobalRef = env->NewGlobalRef(self); 1737 1738 return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall( 1739 (void*(*)(void*))AwtFrame::_GetState, 1740 (void *)selfGlobalRef))); 1741 // selfGlobalRef is deleted in _GetState() 1742 1743 CATCH_BAD_ALLOC_RET(java_awt_Frame_NORMAL); 1744 } 1745 1746 1747 /* 1748 * Class: sun_awt_windows_WFramePeer 1749 * Method: setMaximizedBounds 1750 * Signature: (IIII)V 1751 */ 1752 JNIEXPORT void JNICALL 1753 Java_sun_awt_windows_WFramePeer_setMaximizedBounds(JNIEnv *env, jobject self, 1754 jint x, jint y, jint width, jint height) 1755 { 1756 TRY; 1757 1758 SetMaximizedBoundsStruct *smbs = new SetMaximizedBoundsStruct; 1759 smbs->frame = env->NewGlobalRef(self); 1760 smbs->x = x; 1761 smbs->y = y; 1762 smbs->width = width; 1763 smbs->height = height; 1764 1765 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMaximizedBounds, smbs); 1766 // global ref and smbs are deleted in _SetMaximizedBounds() 1767 1768 CATCH_BAD_ALLOC; 1769 } 1770 1771 1772 /* 1773 * Class: sun_awt_windows_WFramePeer 1774 * Method: clearMaximizedBounds 1775 * Signature: ()V 1776 */ 1777 JNIEXPORT void JNICALL 1778 Java_sun_awt_windows_WFramePeer_clearMaximizedBounds(JNIEnv *env, jobject self) 1779 { 1780 TRY; 1781 1782 jobject selfGlobalRef = env->NewGlobalRef(self); 1783 1784 AwtToolkit::GetInstance().SyncCall(AwtFrame::_ClearMaximizedBounds, 1785 (void *)selfGlobalRef); 1786 // selfGlobalRef is deleted in _ClearMaximizedBounds() 1787 1788 CATCH_BAD_ALLOC; 1789 } 1790 1791 1792 /* 1793 * Class: sun_awt_windows_WFramePeer 1794 * Method: setMenuBar0 1795 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V 1796 */ 1797 JNIEXPORT void JNICALL 1798 Java_sun_awt_windows_WFramePeer_setMenuBar0(JNIEnv *env, jobject self, 1799 jobject mbPeer) 1800 { 1801 TRY; 1802 1803 SetMenuBarStruct *smbs = new SetMenuBarStruct; 1804 smbs->frame = env->NewGlobalRef(self); 1805 smbs->menubar = env->NewGlobalRef(mbPeer); 1806 1807 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetMenuBar, smbs); 1808 // global refs ans smbs are deleted in _SetMenuBar() 1809 1810 CATCH_BAD_ALLOC; 1811 } 1812 1813 /* 1814 * Class: sun_awt_windows_WFramePeer 1815 * Method: create 1816 * Signature: (Lsun/awt/windows/WComponentPeer;)V 1817 */ 1818 JNIEXPORT void JNICALL 1819 Java_sun_awt_windows_WFramePeer_createAwtFrame(JNIEnv *env, jobject self, 1820 jobject parent) 1821 { 1822 TRY; 1823 1824 AwtToolkit::CreateComponent(self, parent, 1825 (AwtToolkit::ComponentFactory) 1826 AwtFrame::Create); 1827 1828 CATCH_BAD_ALLOC; 1829 } 1830 1831 /* 1832 * Class: sun_awt_windows_WFramePeer 1833 * Method: getSysMenuHeight 1834 * Signature: ()I 1835 */ 1836 JNIEXPORT jint JNICALL 1837 Java_sun_awt_windows_WFramePeer_getSysMenuHeight(JNIEnv *env, jclass self) 1838 { 1839 TRY; 1840 1841 return ::GetSystemMetrics(SM_CYMENUSIZE); 1842 1843 CATCH_BAD_ALLOC_RET(0); 1844 } 1845 1846 /* 1847 * Class: sun_awt_windows_WFramePeer 1848 * Method: pSetIMMOption 1849 * Signature: (Ljava/lang/String;)V 1850 */ 1851 JNIEXPORT void JNICALL 1852 Java_sun_awt_windows_WFramePeer_pSetIMMOption(JNIEnv *env, jobject self, 1853 jstring option) 1854 { 1855 TRY; 1856 1857 SetIMMOptionStruct *sios = new SetIMMOptionStruct; 1858 sios->frame = env->NewGlobalRef(self); 1859 sios->option = (jstring)env->NewGlobalRef(option); 1860 1861 AwtToolkit::GetInstance().SyncCall(AwtFrame::_SetIMMOption, sios); 1862 // global refs and sios are deleted in _SetIMMOption() 1863 1864 CATCH_BAD_ALLOC; 1865 } 1866 1867 } /* extern "C" */ 1868 1869 1870 /************************************************************************ 1871 * WEmbeddedFrame native methods 1872 */ 1873 1874 extern "C" { 1875 1876 /* 1877 * Class: sun_awt_windows_WFramePeer 1878 * Method: initIDs 1879 * Signature: (Lsun/awt/windows/WMenuBarPeer;)V 1880 */ 1881 JNIEXPORT void JNICALL 1882 Java_sun_awt_windows_WEmbeddedFrame_initIDs(JNIEnv *env, jclass cls) 1883 { 1884 TRY; 1885 1886 AwtFrame::handleID = env->GetFieldID(cls, "handle", "J"); 1887 DASSERT(AwtFrame::handleID != NULL); 1888 CHECK_NULL(AwtFrame::handleID); 1889 1890 AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V"); 1891 DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL); 1892 CHECK_NULL(AwtFrame::activateEmbeddingTopLevelMID); 1893 1894 AwtFrame::isEmbeddedInIEID = env->GetFieldID(cls, "isEmbeddedInIE", "Z"); 1895 DASSERT(AwtFrame::isEmbeddedInIEID != NULL); 1896 1897 CATCH_BAD_ALLOC; 1898 } 1899 1900 JNIEXPORT void JNICALL 1901 Java_sun_awt_windows_WEmbeddedFrame_notifyModalBlockedImpl(JNIEnv *env, 1902 jobject self, 1903 jobject peer, 1904 jobject blockerPeer, 1905 jboolean blocked) 1906 { 1907 TRY; 1908 1909 NotifyModalBlockedStruct *nmbs = new NotifyModalBlockedStruct; 1910 nmbs->frame = env->NewGlobalRef(self); 1911 nmbs->peer = env->NewGlobalRef(peer); 1912 nmbs->blockerPeer = env->NewGlobalRef(blockerPeer); 1913 nmbs->blocked = blocked; 1914 1915 AwtToolkit::GetInstance().SyncCall(AwtFrame::_NotifyModalBlocked, nmbs); 1916 // global refs and nmbs are deleted in _NotifyModalBlocked() 1917 1918 CATCH_BAD_ALLOC; 1919 } 1920 1921 } /* extern "C" */ 1922 1923 1924 /************************************************************************ 1925 * WEmbeddedFramePeer native methods 1926 */ 1927 1928 extern "C" { 1929 1930 JNIEXPORT void JNICALL 1931 Java_sun_awt_windows_WEmbeddedFramePeer_create(JNIEnv *env, jobject self, 1932 jobject parent) 1933 { 1934 TRY; 1935 1936 JNI_CHECK_NULL_RETURN(self, "peer"); 1937 AwtToolkit::CreateComponent(self, parent, 1938 (AwtToolkit::ComponentFactory) 1939 AwtFrame::Create); 1940 1941 CATCH_BAD_ALLOC; 1942 } 1943 1944 JNIEXPORT jobject JNICALL 1945 Java_sun_awt_windows_WEmbeddedFramePeer_getBoundsPrivate(JNIEnv *env, jobject self) 1946 { 1947 TRY; 1948 1949 jobject result = (jobject)AwtToolkit::GetInstance().SyncCall( 1950 (void *(*)(void *))AwtFrame::_GetBoundsPrivate, 1951 env->NewGlobalRef(self)); 1952 // global ref is deleted in _GetBoundsPrivate 1953 1954 if (result != NULL) 1955 { 1956 jobject resultLocalRef = env->NewLocalRef(result); 1957 env->DeleteGlobalRef(result); 1958 return resultLocalRef; 1959 } 1960 else 1961 { 1962 return NULL; 1963 } 1964 1965 CATCH_BAD_ALLOC_RET(NULL); 1966 } 1967 1968 JNIEXPORT void JNICALL 1969 Java_sun_awt_windows_WFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, jboolean doActivate) 1970 { 1971 TRY; 1972 1973 SynthesizeWmActivateStruct *sas = new SynthesizeWmActivateStruct; 1974 sas->frame = env->NewGlobalRef(self); 1975 sas->doActivate = doActivate; 1976 1977 /* 1978 * WARNING: invoking this function without synchronization by m_Sync CriticalSection. 1979 * Taking this lock results in a deadlock. 1980 */ 1981 AwtToolkit::GetInstance().InvokeFunction(AwtFrame::_SynthesizeWmActivate, sas); 1982 // global ref and sas are deleted in _SynthesizeWmActivate() 1983 1984 CATCH_BAD_ALLOC; 1985 } 1986 1987 } /* extern "C" */ 1988 1989 static bool SetFocusToPluginControl(HWND hwndPlugin) 1990 { 1991 HWND hwndFocus = ::GetFocus(); 1992 1993 if (hwndFocus == hwndPlugin) { 1994 return false; 1995 } 1996 1997 ::SetFocus(hwndPlugin); 1998 DWORD dwError = ::GetLastError(); 1999 if (dwError != ERROR_SUCCESS) { 2000 // If direct call failed, use a special message to set focus 2001 return (::SendMessage(hwndPlugin, WM_AX_REQUEST_FOCUS_TO_EMBEDDER, 0, 0) == 0); 2002 } 2003 return true; 2004 }