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