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