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