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 }