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