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