1 /* 2 * Copyright (c) 1996, 2017, 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 "jni_util.h" 27 #include "awt_Toolkit.h" 28 #include "awt_Dialog.h" 29 #include "awt_Window.h" 30 31 #include <windowsx.h> 32 33 #include "java_awt_Dialog.h" 34 35 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 36 */ 37 38 /************************************************************************/ 39 // Struct for _SetIMMOption() method 40 struct SetIMMOptionStruct { 41 jobject dialog; 42 jstring option; 43 }; 44 /************************************************************************ 45 * AwtDialog fields 46 */ 47 48 jfieldID AwtDialog::titleID; 49 jfieldID AwtDialog::undecoratedID; 50 51 #if defined(DEBUG) 52 // counts how many nested modal dialogs are open, a sanity 53 // check to ensure the somewhat complicated disable/enable 54 // code is working properly 55 int AwtModalityNestCounter = 0; 56 #endif 57 58 HHOOK AWTModalHook; 59 HHOOK AWTMouseHook; 60 61 int VisibleModalDialogsCount = 0; 62 63 /************************************************************************ 64 * AwtDialog class methods 65 */ 66 67 AwtDialog::AwtDialog() { 68 m_modalWnd = NULL; 69 } 70 71 AwtDialog::~AwtDialog() 72 { 73 } 74 75 void AwtDialog::Dispose() 76 { 77 if (m_modalWnd != NULL) { 78 WmEndModal(); 79 } 80 AwtFrame::Dispose(); 81 } 82 83 LPCTSTR AwtDialog::GetClassName() { 84 return AWT_DIALOG_WINDOW_CLASS_NAME; 85 } 86 87 void AwtDialog::FillClassInfo(WNDCLASSEX *lpwc) 88 { 89 AwtWindow::FillClassInfo(lpwc); 90 //Fixed 6280303: REGRESSION: Java cup icon appears in title bar of dialogs 91 // Dialog inherits icon from its owner dinamically 92 lpwc->hIcon = NULL; 93 lpwc->hIconSm = NULL; 94 } 95 96 /* 97 * Create a new AwtDialog object and window. 98 */ 99 AwtDialog* AwtDialog::Create(jobject peer, jobject parent) 100 { 101 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 102 103 jobject target = NULL; 104 AwtDialog* dialog = NULL; 105 106 try { 107 if (env->EnsureLocalCapacity(2) < 0) { 108 return NULL; 109 } 110 111 PDATA pData; 112 AwtWindow* awtParent = NULL; 113 HWND hwndParent = NULL; 114 target = env->GetObjectField(peer, AwtObject::targetID); 115 JNI_CHECK_NULL_GOTO(target, "null target", done); 116 117 if (parent != NULL) { 118 JNI_CHECK_PEER_GOTO(parent, done); 119 awtParent = (AwtWindow *)(JNI_GET_PDATA(parent)); 120 HWND oHWnd = awtParent->GetOverriddenHWnd(); 121 hwndParent = oHWnd ? oHWnd : awtParent->GetHWnd(); 122 } else { 123 // There is no way to prevent a parentless dialog from showing on 124 // the taskbar other than to specify an invisible parent and set 125 // WS_POPUP style for the dialog. Using toolkit window here. That 126 // will also excludes the dialog from appearing in window list while 127 // ALT+TAB'ing 128 // From the other point, it may be confusing when the dialog without 129 // an owner is missing on the toolbar. So, do not set any fake 130 // parent window here. 131 // hwndParent = AwtToolkit::GetInstance().GetHWnd(); 132 } 133 dialog = new AwtDialog(); 134 135 { 136 int colorId = COLOR_3DFACE; 137 DWORD style = WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN; 138 if (hwndParent != NULL) { 139 style |= WS_POPUP; 140 } 141 style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX); 142 DWORD exStyle = WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME; 143 144 if (GetRTL()) { 145 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; 146 if (GetRTLReadingOrder()) 147 exStyle |= WS_EX_RTLREADING; 148 } 149 150 151 if (env->GetBooleanField(target, AwtDialog::undecoratedID) == JNI_TRUE) { 152 style = WS_POPUP | WS_CLIPCHILDREN; 153 exStyle = 0; 154 dialog->m_isUndecorated = TRUE; 155 } 156 157 jint x = env->GetIntField(target, AwtComponent::xID); 158 jint y = env->GetIntField(target, AwtComponent::yID); 159 jint width = env->GetIntField(target, AwtComponent::widthID); 160 jint height = env->GetIntField(target, AwtComponent::heightID); 161 162 dialog->CreateHWnd(env, L"", 163 style, exStyle, 164 x, y, width, height, 165 hwndParent, 166 NULL, 167 ::GetSysColor(COLOR_WINDOWTEXT), 168 ::GetSysColor(colorId), 169 peer); 170 171 dialog->RecalcNonClient(); 172 dialog->UpdateSystemMenu(); 173 174 /* 175 * Initialize icon as inherited from parent if it exists 176 */ 177 if (parent != NULL) { 178 dialog->m_hIcon = awtParent->GetHIcon(); 179 dialog->m_hIconSm = awtParent->GetHIconSm(); 180 dialog->m_iconInherited = TRUE; 181 } 182 dialog->DoUpdateIcon(); 183 184 } 185 } catch (...) { 186 env->DeleteLocalRef(target); 187 throw; 188 } 189 190 done: 191 env->DeleteLocalRef(target); 192 193 return dialog; 194 } 195 196 MsgRouting AwtDialog::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { 197 // By the request from Swing team, click on the Dialog's title should generate Ungrab 198 if (m_grabbedWindow != NULL/* && !m_grabbedWindow->IsOneOfOwnersOf(this)*/) { 199 m_grabbedWindow->Ungrab(); 200 } 201 202 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) { 203 // Dialog is non-maximizable 204 if ((button & DBL_CLICK) && hitTest == HTCAPTION) { 205 return mrConsume; 206 } 207 } 208 return AwtFrame::WmNcMouseDown(hitTest, x, y, button); 209 } 210 211 LRESULT CALLBACK AwtDialog::ModalFilterProc(int code, 212 WPARAM wParam, LPARAM lParam) 213 { 214 HWND hWnd = (HWND)wParam; 215 HWND blocker = AwtWindow::GetModalBlocker(hWnd); 216 if (::IsWindow(blocker) && 217 ((code == HCBT_ACTIVATE) || 218 (code == HCBT_SETFOCUS))) 219 { 220 // fix for 6270632: this window and all its blockers can be minimized by 221 // "show desktop" button, so we should restore them first 222 if (::IsIconic(hWnd)) { 223 ::ShowWindow(hWnd, SW_RESTORE); 224 } 225 PopupBlockers(blocker, TRUE, ::GetForegroundWindow(), FALSE); 226 // return 1 to prevent the system from allowing the operation 227 return 1; 228 } 229 return CallNextHookEx(0, code, wParam, lParam); 230 } 231 232 LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, 233 WPARAM wParam, LPARAM lParam) 234 { 235 if (nCode >= 0) 236 { 237 MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT *)lParam; 238 HWND hWnd = mhs->hwnd; 239 if ((wParam == WM_LBUTTONDOWN) || 240 (wParam == WM_MBUTTONDOWN) || 241 (wParam == WM_RBUTTONDOWN) || 242 (wParam == WM_MOUSEACTIVATE) || 243 (wParam == WM_MOUSEWHEEL) || 244 (wParam == WM_MOUSEHWHEEL) || 245 (wParam == WM_NCLBUTTONDOWN) || 246 (wParam == WM_NCMBUTTONDOWN) || 247 (wParam == WM_NCRBUTTONDOWN)) 248 { 249 HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); 250 if (::IsWindow(blocker)) { 251 BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd); 252 PopupBlockers(blocker, FALSE, ::GetForegroundWindow(), onTaskbar); 253 // return a nonzero value to prevent the system from passing 254 // the message to the target window procedure 255 return 1; 256 } 257 } 258 } 259 260 return CallNextHookEx(0, nCode, wParam, lParam); 261 } 262 263 /* 264 * The function goes through the hierarchy of the blockers and 265 * popups all the blockers. Note that the function starts from the top 266 * blocker and goes down to the blocker which is the bottom one. 267 * Using another traversal algorithm (bottom->top) may cause to flickering 268 * as the bottom blocker will cover the top blocker for a while. 269 */ 270 void AwtDialog::PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) 271 { 272 HWND nextBlocker = AwtWindow::GetModalBlocker(blocker); 273 BOOL nextBlockerExists = ::IsWindow(nextBlocker); 274 if (nextBlockerExists) { 275 PopupBlockers(nextBlocker, isModalHook, prevFGWindow, onTaskbar); 276 } 277 PopupBlocker(blocker, nextBlocker, isModalHook, prevFGWindow, onTaskbar); 278 } 279 280 /* 281 * The function popups the blocker, for a non-blocked blocker we need 282 * to activate the blocker but if a blocker is blocked, then we need 283 * to change z-order of the blocker placing the blocker under the next blocker. 284 */ 285 void AwtDialog::PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) 286 { 287 if (blocker == AwtToolkit::GetInstance().GetHWnd()) { 288 return; 289 } 290 291 // fix for 6494032 292 if (isModalHook && !::IsWindowVisible(blocker)) { 293 ::ShowWindow(blocker, SW_SHOWNA); 294 } 295 296 BOOL nextBlockerExists = ::IsWindow(nextBlocker); 297 UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; 298 299 if (nextBlockerExists) { 300 // Fix for 6829546: if blocker is a top-most window, but window isn't, then 301 // calling ::SetWindowPos(dialog, blocker, ...) makes window top-most as well 302 BOOL topmostNextBlocker = (::GetWindowLong(nextBlocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; 303 BOOL topmostBlocker = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; 304 if (!topmostNextBlocker || topmostBlocker) { 305 ::SetWindowPos(blocker, nextBlocker, 0, 0, 0, 0, flags); 306 } else { 307 ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags); 308 } 309 } else { 310 ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags); 311 // no beep/flash if the mouse was clicked in the taskbar menu 312 // or the dialog is currently inactive 313 if (!isModalHook && !onTaskbar && (blocker == prevFGWindow)) { 314 AnimateModalBlocker(blocker); 315 } 316 ::BringWindowToTop(blocker); 317 ::SetForegroundWindow(blocker); 318 } 319 } 320 321 void AwtDialog::AnimateModalBlocker(HWND window) 322 { 323 ::MessageBeep(MB_OK); 324 // some heuristics: 3 times x 64 milliseconds 325 AwtWindow::FlashWindowEx(window, 3, 64, FLASHW_CAPTION); 326 } 327 328 LRESULT CALLBACK AwtDialog::MouseHookProc_NonTT(int nCode, 329 WPARAM wParam, LPARAM lParam) 330 { 331 static HWND lastHWnd = NULL; 332 if (nCode >= 0) 333 { 334 MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT *)lParam; 335 HWND hWnd = mhs->hwnd; 336 HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); 337 if (::IsWindow(blocker)) { 338 if ((wParam == WM_MOUSEMOVE) || 339 (wParam == WM_NCMOUSEMOVE)) 340 { 341 if (lastHWnd != hWnd) { 342 static HCURSOR hArrowCur = ::LoadCursor(NULL, IDC_ARROW); 343 ::SetCursor(hArrowCur); 344 lastHWnd = hWnd; 345 } 346 ::PostMessage(hWnd, WM_SETCURSOR, (WPARAM)hWnd, 0); 347 } else if (wParam == WM_MOUSELEAVE) { 348 lastHWnd = NULL; 349 } 350 351 AwtDialog::MouseHookProc(nCode, wParam, lParam); 352 return 1; 353 } 354 } 355 356 return CallNextHookEx(0, nCode, wParam, lParam); 357 } 358 359 void AwtDialog::Show() 360 { 361 m_visible = true; 362 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 363 364 BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID); 365 if (locationByPlatform) { 366 moveToDefaultLocation(); 367 } 368 EnableTranslucency(TRUE); 369 if (IsFocusableWindow() && (IsAutoRequestFocus() || IsFocusedWindowModalBlocker())) { 370 ::ShowWindow(GetHWnd(), SW_SHOW); 371 } else { 372 ::ShowWindow(GetHWnd(), SW_SHOWNA); 373 } 374 } 375 376 void AwtDialog::DoUpdateIcon() 377 { 378 AwtFrame::DoUpdateIcon(); 379 //Workaround windows bug: 380 //Decorations are not updated correctly for owned dialogs 381 //when changing dlg with icon <--> dlg without icon 382 RECT winRect; 383 RECT clientRect; 384 ::GetWindowRect(GetHWnd(), &winRect); 385 ::GetClientRect(GetHWnd(), &clientRect); 386 ::MapWindowPoints(HWND_DESKTOP, GetHWnd(), (LPPOINT)&winRect, 2); 387 HRGN winRgn = CreateRectRgnIndirect(&winRect); 388 HRGN clientRgn = CreateRectRgnIndirect(&clientRect); 389 ::CombineRgn(winRgn, winRgn, clientRgn, RGN_DIFF); 390 ::RedrawWindow(GetHWnd(), NULL, winRgn, RDW_FRAME | RDW_INVALIDATE); 391 ::DeleteObject(winRgn); 392 ::DeleteObject(clientRgn); 393 } 394 395 HICON AwtDialog::GetEffectiveIcon(int iconType) 396 { 397 HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER); 398 BOOL isResizable = ((GetStyle() & WS_THICKFRAME) != 0); 399 BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/)); 400 HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon(); 401 if ((hIcon == NULL) && (isResizable || (hOwner == NULL))) { 402 //Java cup icon is not loaded in window class for dialogs 403 //It needs to be set explicitly for resizable dialogs 404 //and ownerless dialogs 405 hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() : 406 AwtToolkit::GetInstance().GetAwtIcon(); 407 } else if ((hIcon != NULL) && IsIconInherited() && !isResizable) { 408 //Non-resizable dialogs without explicitely set icon 409 //Should have no icon 410 hIcon = NULL; 411 } 412 return hIcon; 413 } 414 415 void AwtDialog::CheckInstallModalHook() { 416 VisibleModalDialogsCount++; 417 if (VisibleModalDialogsCount == 1) { 418 AWTModalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)ModalFilterProc, 419 0, AwtToolkit::MainThread()); 420 AWTMouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, 421 0, AwtToolkit::MainThread()); 422 } 423 } 424 425 void AwtDialog::CheckUninstallModalHook() { 426 if (VisibleModalDialogsCount == 1) { 427 UnhookWindowsHookEx(AWTModalHook); 428 UnhookWindowsHookEx(AWTMouseHook); 429 } 430 VisibleModalDialogsCount--; 431 } 432 433 void AwtDialog::ModalPerformActivation(HWND hWnd) 434 { 435 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 436 437 AwtWindow *w = (AwtWindow *)AwtComponent::GetComponent(hWnd); 438 if ((w != NULL) && w->IsEmbeddedFrame()) { 439 jobject target = w->GetTarget(env); 440 env->CallVoidMethod(target, AwtFrame::activateEmbeddingTopLevelMID); 441 env->DeleteLocalRef(target); 442 } else { 443 ::BringWindowToTop(hWnd); 444 ::SetForegroundWindow(hWnd); 445 } 446 } 447 448 void AwtDialog::ModalActivateNextWindow(HWND dialogHWnd, 449 jobject dialogTarget, jobject dialogPeer) 450 { 451 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 452 453 jboolean exc; 454 jlongArray windows = (jlongArray) JNU_CallStaticMethodByName 455 (env, 456 &exc, 457 "sun/awt/windows/WWindowPeer", 458 "getActiveWindowHandles", 459 "(Ljava/awt/Component;)[J", 460 dialogTarget).l; 461 if (exc == JNI_TRUE) { 462 throw std::bad_alloc(); 463 } 464 if (windows == NULL) { 465 return; 466 } 467 468 jboolean isCopy; 469 jlong *ws = env->GetLongArrayElements(windows, &isCopy); 470 if (ws == NULL) { 471 throw std::bad_alloc(); 472 } 473 int windowsCount = env->GetArrayLength(windows); 474 for (int i = windowsCount - 1; i >= 0; i--) { 475 HWND w = (HWND)ws[i]; 476 if ((w != dialogHWnd) && ModalCanBeActivated(w)) { 477 AwtDialog::ModalPerformActivation(w); 478 break; 479 } 480 } 481 env->ReleaseLongArrayElements(windows, ws, 0); 482 483 env->DeleteLocalRef(windows); 484 } 485 486 MsgRouting AwtDialog::WmShowModal() 487 { 488 DASSERT(::GetCurrentThreadId() == AwtToolkit::MainThread()); 489 490 // fix for 6213128: release capture (got by popups, choices, etc) when 491 // modal dialog is shown 492 HWND capturer = ::GetCapture(); 493 if (capturer != NULL) { 494 ::ReleaseCapture(); 495 } 496 497 SendMessage(WM_AWT_COMPONENT_SHOW); 498 499 CheckInstallModalHook(); 500 501 m_modalWnd = GetHWnd(); 502 503 return mrConsume; 504 } 505 506 MsgRouting AwtDialog::WmEndModal() 507 { 508 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 509 510 DASSERT( ::GetCurrentThreadId() == AwtToolkit::MainThread() ); 511 DASSERT( ::IsWindow(m_modalWnd) ); 512 513 m_modalWnd = NULL; 514 515 CheckUninstallModalHook(); 516 517 HWND parentHWnd = ::GetParent(GetHWnd()); 518 jobject peer = GetPeer(env); 519 jobject target = GetTarget(env); 520 if (::GetForegroundWindow() == GetHWnd()) { 521 ModalActivateNextWindow(GetHWnd(), target, peer); 522 } 523 // hide the dialog 524 SendMessage(WM_AWT_COMPONENT_HIDE); 525 526 env->DeleteLocalRef(target); 527 528 return mrConsume; 529 } 530 531 void AwtDialog::SetResizable(BOOL isResizable) 532 { 533 // call superclass 534 AwtFrame::SetResizable(isResizable); 535 536 LONG style = GetStyle(); 537 LONG xstyle = GetStyleEx(); 538 if (isResizable || IsUndecorated()) { 539 // remove modal frame 540 xstyle &= ~WS_EX_DLGMODALFRAME; 541 } else { 542 // add modal frame 543 xstyle |= WS_EX_DLGMODALFRAME; 544 } 545 // dialogs are never minimizable/maximizable, so remove those bits 546 style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX); 547 SetStyle(style); 548 SetStyleEx(xstyle); 549 RedrawNonClient(); 550 } 551 552 // Adjust system menu so that: 553 // Non-resizable dialogs only have Move and Close items 554 // Resizable dialogs have the full system menu with 555 // Maximize, Minimize items disabled (the items 556 // get disabled by the native system). 557 // This perfectly mimics the native MS Windows behavior. 558 // Normally, Win32 dialog system menu handling is done via 559 // CreateDialog/DefDlgProc, but our dialogs are using DefWindowProc 560 // so we handle the system menu ourselves 561 void AwtDialog::UpdateSystemMenu() 562 { 563 HWND hWndSelf = GetHWnd(); 564 BOOL isResizable = IsResizable(); 565 566 // before restoring the default menu, check if there is an 567 // InputMethodManager menu item already. Note that it assumes 568 // that the length of the InputMethodManager menu item string 569 // should not be longer than 256 bytes. 570 MENUITEMINFO mii; 571 memset(&mii, 0, sizeof(MENUITEMINFO)); 572 TCHAR immItem[256]; 573 BOOL hasImm; 574 mii.cbSize = sizeof(MENUITEMINFO); 575 mii.fMask = MIIM_TYPE; 576 mii.cch = sizeof(immItem); 577 mii.dwTypeData = immItem; 578 hasImm = ::GetMenuItemInfo(GetSystemMenu(hWndSelf, FALSE), 579 SYSCOMMAND_IMM, FALSE, &mii); 580 581 // restore the default menu 582 ::GetSystemMenu(hWndSelf, TRUE); 583 // now get a working copy of the menu 584 HMENU hMenuSys = GetSystemMenu(hWndSelf, FALSE); 585 586 if (!isResizable) { 587 // remove inapplicable sizing commands 588 ::DeleteMenu(hMenuSys, SC_MINIMIZE, MF_BYCOMMAND); 589 ::DeleteMenu(hMenuSys, SC_RESTORE, MF_BYCOMMAND); 590 ::DeleteMenu(hMenuSys, SC_MAXIMIZE, MF_BYCOMMAND); 591 ::DeleteMenu(hMenuSys, SC_SIZE, MF_BYCOMMAND); 592 // remove separator if only 3 items left (Move, Separator, and Close) 593 if (::GetMenuItemCount(hMenuSys) == 3) { 594 MENUITEMINFO mi; 595 memset(&mi, 0, sizeof(MENUITEMINFO)); 596 mi.cbSize = sizeof(MENUITEMINFO); 597 mi.fMask = MIIM_TYPE; 598 ::GetMenuItemInfo(hMenuSys, 1, TRUE, &mi); 599 if (mi.fType & MFT_SEPARATOR) { 600 ::DeleteMenu(hMenuSys, 1, MF_BYPOSITION); 601 } 602 } 603 } 604 605 // if there was the InputMethodManager menu item, restore it. 606 if (hasImm) { 607 ::AppendMenu(hMenuSys, MF_STRING, SYSCOMMAND_IMM, immItem); 608 } 609 } 610 611 // Override WmStyleChanged to adjust system menu for sizable/non-resizable dialogs 612 MsgRouting AwtDialog::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 613 { 614 UpdateSystemMenu(); 615 DoUpdateIcon(); 616 return mrConsume; 617 } 618 619 MsgRouting AwtDialog::WmSize(UINT type, int w, int h) 620 { 621 if (type == SIZE_MAXIMIZED || type == SIZE_MINIMIZED 622 || (type == SIZE_RESTORED && !IsResizing())) 623 { 624 UpdateSystemMenu(); // adjust to reflect restored vs. maximized state 625 } 626 627 return AwtFrame::WmSize(type, w, h); 628 } 629 630 LRESULT AwtDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 631 { 632 MsgRouting mr = mrDoDefault; 633 LRESULT retValue = 0L; 634 635 switch(message) { 636 case WM_AWT_DLG_SHOWMODAL: 637 mr = WmShowModal(); 638 break; 639 case WM_AWT_DLG_ENDMODAL: 640 mr = WmEndModal(); 641 break; 642 } 643 644 if (mr != mrConsume) { 645 retValue = AwtFrame::WindowProc(message, wParam, lParam); 646 } 647 return retValue; 648 } 649 650 void AwtDialog::_ShowModal(void *param) 651 { 652 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 653 654 jobject self = (jobject)param; 655 656 AwtDialog *d = NULL; 657 658 PDATA pData; 659 JNI_CHECK_PEER_GOTO(self, ret); 660 d = (AwtDialog *)pData; 661 if (::IsWindow(d->GetHWnd())) { 662 d->SendMessage(WM_AWT_DLG_SHOWMODAL); 663 } 664 ret: 665 env->DeleteGlobalRef(self); 666 } 667 668 void AwtDialog::_EndModal(void *param) 669 { 670 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 671 672 jobject self = (jobject)param; 673 674 AwtDialog *d = NULL; 675 676 PDATA pData; 677 JNI_CHECK_PEER_GOTO(self, ret); 678 d = (AwtDialog *)pData; 679 if (::IsWindow(d->GetHWnd())) { 680 d->SendMessage(WM_AWT_DLG_ENDMODAL); 681 } 682 ret: 683 env->DeleteGlobalRef(self); 684 } 685 686 void AwtDialog::_SetIMMOption(void *param) 687 { 688 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 689 690 SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param; 691 jobject self = sios->dialog; 692 jstring option = sios->option; 693 694 int badAlloc = 0; 695 LPCTSTR coption; 696 LPCTSTR empty = TEXT("InputMethod"); 697 AwtDialog *d = NULL; 698 699 PDATA pData; 700 JNI_CHECK_PEER_GOTO(self, ret); 701 JNI_CHECK_NULL_GOTO(option, "null IMMOption", ret); 702 703 d = (AwtDialog *)pData; 704 if (::IsWindow(d->GetHWnd())) 705 { 706 coption = JNU_GetStringPlatformChars(env, option, NULL); 707 if (coption == NULL) 708 { 709 badAlloc = 1; 710 } 711 if (!badAlloc) 712 { 713 HMENU hSysMenu = ::GetSystemMenu(d->GetHWnd(), FALSE); 714 ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption); 715 716 if (coption != empty) 717 { 718 JNU_ReleaseStringPlatformChars(env, option, coption); 719 } 720 } 721 } 722 ret: 723 env->DeleteGlobalRef(self); 724 env->DeleteGlobalRef(option); 725 726 delete sios; 727 728 if (badAlloc) 729 { 730 throw std::bad_alloc(); 731 } 732 } 733 734 /************************************************************************ 735 * Dialog native methods 736 */ 737 738 extern "C" { 739 740 JNIEXPORT void JNICALL 741 Java_java_awt_Dialog_initIDs(JNIEnv *env, jclass cls) 742 { 743 TRY; 744 745 /* java.awt.Dialog fields and methods */ 746 AwtDialog::titleID 747 = env->GetFieldID(cls, "title", "Ljava/lang/String;"); 748 DASSERT(AwtDialog::titleID != NULL); 749 CHECK_NULL(AwtDialog::titleID); 750 751 AwtDialog::undecoratedID 752 = env->GetFieldID(cls,"undecorated","Z"); 753 DASSERT(AwtDialog::undecoratedID != NULL); 754 CHECK_NULL(AwtDialog::undecoratedID); 755 756 CATCH_BAD_ALLOC; 757 } 758 759 } /* extern "C" */ 760 761 762 /************************************************************************ 763 * DialogPeer native methods 764 */ 765 766 extern "C" { 767 768 /* 769 * Class: sun_awt_windows_WDialogPeer 770 * Method: create 771 * Signature: (Lsun/awt/windows/WComponentPeer;)V 772 */ 773 JNIEXPORT void JNICALL 774 Java_sun_awt_windows_WDialogPeer_createAwtDialog(JNIEnv *env, jobject self, 775 jobject parent) 776 { 777 TRY; 778 779 PDATA pData; 780 AwtToolkit::CreateComponent(self, parent, 781 (AwtToolkit::ComponentFactory) 782 AwtDialog::Create); 783 JNI_CHECK_PEER_CREATION_RETURN(self); 784 785 CATCH_BAD_ALLOC; 786 } 787 788 /* 789 * Class: sun_awt_windows_WDialogPeer 790 * Method: _show 791 * Signature: ()V 792 */ 793 JNIEXPORT void JNICALL 794 Java_sun_awt_windows_WDialogPeer_showModal(JNIEnv *env, jobject self) 795 { 796 TRY; 797 798 jobject selfGlobalRef = env->NewGlobalRef(self); 799 800 AwtToolkit::GetInstance().SyncCall(AwtDialog::_ShowModal, 801 (void *)selfGlobalRef); 802 // selfGlobalRef is deleted in _ShowModal 803 804 CATCH_BAD_ALLOC; 805 } 806 807 /* 808 * Class: sun_awt_windows_WDialogPeer 809 * Method: _hide 810 * Signature: ()V 811 */ 812 JNIEXPORT void JNICALL 813 Java_sun_awt_windows_WDialogPeer_endModal(JNIEnv *env, jobject self) 814 { 815 TRY; 816 817 jobject selfGlobalRef = env->NewGlobalRef(self); 818 819 AwtToolkit::GetInstance().SyncCall(AwtDialog::_EndModal, 820 (void *)selfGlobalRef); 821 // selfGlobalRef is deleted in _EndModal 822 823 CATCH_BAD_ALLOC; 824 } 825 826 /* 827 * Class: sun_awt_windows_WFramePeer 828 * Method: pSetIMMOption 829 * Signature: (Ljava/lang/String;)V 830 */ 831 JNIEXPORT void JNICALL 832 Java_sun_awt_windows_WDialogPeer_pSetIMMOption(JNIEnv *env, jobject self, 833 jstring option) 834 { 835 TRY; 836 837 SetIMMOptionStruct *sios = new SetIMMOptionStruct; 838 sios->dialog = env->NewGlobalRef(self); 839 sios->option = (jstring)env->NewGlobalRef(option); 840 841 AwtToolkit::GetInstance().SyncCall(AwtDialog::_SetIMMOption, sios); 842 // global refs and sios are deleted in _SetIMMOption 843 844 CATCH_BAD_ALLOC; 845 } 846 } /* extern "C" */