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_NCLBUTTONDOWN) || 244 (wParam == WM_NCMBUTTONDOWN) || 245 (wParam == WM_NCRBUTTONDOWN)) 246 { 247 HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); 248 if (::IsWindow(blocker)) { 249 BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd); 250 PopupBlockers(blocker, FALSE, ::GetForegroundWindow(), onTaskbar); 251 // return a nonzero value to prevent the system from passing 252 // the message to the target window procedure 253 return 1; 254 } 255 } 256 } 257 258 return CallNextHookEx(0, nCode, wParam, lParam); 259 } 260 261 /* 262 * The function goes through the hierarchy of the blockers and 263 * popups all the blockers. Note that the function starts from the top 264 * blocker and goes down to the blocker which is the bottom one. 265 * Using another traversal algorithm (bottom->top) may cause to flickering 266 * as the bottom blocker will cover the top blocker for a while. 267 */ 268 void AwtDialog::PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) 269 { 270 HWND nextBlocker = AwtWindow::GetModalBlocker(blocker); 271 BOOL nextBlockerExists = ::IsWindow(nextBlocker); 272 if (nextBlockerExists) { 273 PopupBlockers(nextBlocker, isModalHook, prevFGWindow, onTaskbar); 274 } 275 PopupBlocker(blocker, nextBlocker, isModalHook, prevFGWindow, onTaskbar); 276 } 277 278 /* 279 * The function popups the blocker, for a non-blocked blocker we need 280 * to activate the blocker but if a blocker is blocked, then we need 281 * to change z-order of the blocker placing the blocker under the next blocker. 282 */ 283 void AwtDialog::PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) 284 { 285 if (blocker == AwtToolkit::GetInstance().GetHWnd()) { 286 return; 287 } 288 289 // fix for 6494032 290 if (isModalHook && !::IsWindowVisible(blocker)) { 291 ::ShowWindow(blocker, SW_SHOWNA); 292 } 293 294 BOOL nextBlockerExists = ::IsWindow(nextBlocker); 295 UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; 296 297 if (nextBlockerExists) { 298 // Fix for 6829546: if blocker is a top-most window, but window isn't, then 299 // calling ::SetWindowPos(dialog, blocker, ...) makes window top-most as well 300 BOOL topmostNextBlocker = (::GetWindowLong(nextBlocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; 301 BOOL topmostBlocker = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; 302 if (!topmostNextBlocker || topmostBlocker) { 303 ::SetWindowPos(blocker, nextBlocker, 0, 0, 0, 0, flags); 304 } else { 305 ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags); 306 } 307 } else { 308 ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags); 309 // no beep/flash if the mouse was clicked in the taskbar menu 310 // or the dialog is currently inactive 311 if (!isModalHook && !onTaskbar && (blocker == prevFGWindow)) { 312 AnimateModalBlocker(blocker); 313 } 314 ::BringWindowToTop(blocker); 315 ::SetForegroundWindow(blocker); 316 } 317 } 318 319 void AwtDialog::AnimateModalBlocker(HWND window) 320 { 321 ::MessageBeep(MB_OK); 322 // some heuristics: 3 times x 64 milliseconds 323 AwtWindow::FlashWindowEx(window, 3, 64, FLASHW_CAPTION); 324 } 325 326 LRESULT CALLBACK AwtDialog::MouseHookProc_NonTT(int nCode, 327 WPARAM wParam, LPARAM lParam) 328 { 329 static HWND lastHWnd = NULL; 330 if (nCode >= 0) 331 { 332 MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT *)lParam; 333 HWND hWnd = mhs->hwnd; 334 HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); 335 if (::IsWindow(blocker)) { 336 if ((wParam == WM_MOUSEMOVE) || 337 (wParam == WM_NCMOUSEMOVE)) 338 { 339 if (lastHWnd != hWnd) { 340 static HCURSOR hArrowCur = ::LoadCursor(NULL, IDC_ARROW); 341 ::SetCursor(hArrowCur); 342 lastHWnd = hWnd; 343 } 344 ::PostMessage(hWnd, WM_SETCURSOR, (WPARAM)hWnd, 0); 345 } else if (wParam == WM_MOUSELEAVE) { 346 lastHWnd = NULL; 347 } 348 349 AwtDialog::MouseHookProc(nCode, wParam, lParam); 350 return 1; 351 } 352 } 353 354 return CallNextHookEx(0, nCode, wParam, lParam); 355 } 356 357 void AwtDialog::Show() 358 { 359 m_visible = true; 360 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 361 362 BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID); 363 if (locationByPlatform) { 364 moveToDefaultLocation(); 365 } 366 EnableTranslucency(TRUE); 367 if (IsFocusableWindow() && (IsAutoRequestFocus() || IsFocusedWindowModalBlocker())) { 368 ::ShowWindow(GetHWnd(), SW_SHOW); 369 } else { 370 ::ShowWindow(GetHWnd(), SW_SHOWNA); 371 } 372 } 373 374 void AwtDialog::DoUpdateIcon() 375 { 376 AwtFrame::DoUpdateIcon(); 377 //Workaround windows bug: 378 //Decorations are not updated correctly for owned dialogs 379 //when changing dlg with icon <--> dlg without icon 380 RECT winRect; 381 RECT clientRect; 382 ::GetWindowRect(GetHWnd(), &winRect); 383 ::GetClientRect(GetHWnd(), &clientRect); 384 ::MapWindowPoints(HWND_DESKTOP, GetHWnd(), (LPPOINT)&winRect, 2); 385 HRGN winRgn = CreateRectRgnIndirect(&winRect); 386 HRGN clientRgn = CreateRectRgnIndirect(&clientRect); 387 ::CombineRgn(winRgn, winRgn, clientRgn, RGN_DIFF); 388 ::RedrawWindow(GetHWnd(), NULL, winRgn, RDW_FRAME | RDW_INVALIDATE); 389 ::DeleteObject(winRgn); 390 ::DeleteObject(clientRgn); 391 } 392 393 HICON AwtDialog::GetEffectiveIcon(int iconType) 394 { 395 HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER); 396 BOOL isResizable = ((GetStyle() & WS_THICKFRAME) != 0); 397 BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/)); 398 HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon(); 399 if ((hIcon == NULL) && (isResizable || (hOwner == NULL))) { 400 //Java cup icon is not loaded in window class for dialogs 401 //It needs to be set explicitly for resizable dialogs 402 //and ownerless dialogs 403 hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() : 404 AwtToolkit::GetInstance().GetAwtIcon(); 405 } else if ((hIcon != NULL) && IsIconInherited() && !isResizable) { 406 //Non-resizable dialogs without explicitely set icon 407 //Should have no icon 408 hIcon = NULL; 409 } 410 return hIcon; 411 } 412 413 void AwtDialog::CheckInstallModalHook() { 414 VisibleModalDialogsCount++; 415 if (VisibleModalDialogsCount == 1) { 416 AWTModalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)ModalFilterProc, 417 0, AwtToolkit::MainThread()); 418 AWTMouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, 419 0, AwtToolkit::MainThread()); 420 } 421 } 422 423 void AwtDialog::CheckUninstallModalHook() { 424 if (VisibleModalDialogsCount == 1) { 425 UnhookWindowsHookEx(AWTModalHook); 426 UnhookWindowsHookEx(AWTMouseHook); 427 } 428 VisibleModalDialogsCount--; 429 } 430 431 void AwtDialog::ModalPerformActivation(HWND hWnd) 432 { 433 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 434 435 AwtWindow *w = (AwtWindow *)AwtComponent::GetComponent(hWnd); 436 if ((w != NULL) && w->IsEmbeddedFrame()) { 437 jobject target = w->GetTarget(env); 438 env->CallVoidMethod(target, AwtFrame::activateEmbeddingTopLevelMID); 439 env->DeleteLocalRef(target); 440 } else { 441 ::BringWindowToTop(hWnd); 442 ::SetForegroundWindow(hWnd); 443 } 444 } 445 446 void AwtDialog::ModalActivateNextWindow(HWND dialogHWnd, 447 jobject dialogTarget, jobject dialogPeer) 448 { 449 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 450 451 jboolean exc; 452 jlongArray windows = (jlongArray) JNU_CallStaticMethodByName 453 (env, 454 &exc, 455 "sun/awt/windows/WWindowPeer", 456 "getActiveWindowHandles", 457 "(Ljava/awt/Component;)[J", 458 dialogTarget).l; 459 if (exc == JNI_TRUE) { 460 throw std::bad_alloc(); 461 } 462 if (windows == NULL) { 463 return; 464 } 465 466 jboolean isCopy; 467 jlong *ws = env->GetLongArrayElements(windows, &isCopy); 468 if (ws == NULL) { 469 throw std::bad_alloc(); 470 } 471 int windowsCount = env->GetArrayLength(windows); 472 for (int i = windowsCount - 1; i >= 0; i--) { 473 HWND w = (HWND)ws[i]; 474 if ((w != dialogHWnd) && ModalCanBeActivated(w)) { 475 AwtDialog::ModalPerformActivation(w); 476 break; 477 } 478 } 479 env->ReleaseLongArrayElements(windows, ws, 0); 480 481 env->DeleteLocalRef(windows); 482 } 483 484 MsgRouting AwtDialog::WmShowModal() 485 { 486 DASSERT(::GetCurrentThreadId() == AwtToolkit::MainThread()); 487 488 // fix for 6213128: release capture (got by popups, choices, etc) when 489 // modal dialog is shown 490 HWND capturer = ::GetCapture(); 491 if (capturer != NULL) { 492 ::ReleaseCapture(); 493 } 494 495 SendMessage(WM_AWT_COMPONENT_SHOW); 496 497 CheckInstallModalHook(); 498 499 m_modalWnd = GetHWnd(); 500 501 return mrConsume; 502 } 503 504 MsgRouting AwtDialog::WmEndModal() 505 { 506 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 507 508 DASSERT( ::GetCurrentThreadId() == AwtToolkit::MainThread() ); 509 DASSERT( ::IsWindow(m_modalWnd) ); 510 511 m_modalWnd = NULL; 512 513 CheckUninstallModalHook(); 514 515 HWND parentHWnd = ::GetParent(GetHWnd()); 516 jobject peer = GetPeer(env); 517 jobject target = GetTarget(env); 518 if (::GetForegroundWindow() == GetHWnd()) { 519 ModalActivateNextWindow(GetHWnd(), target, peer); 520 } 521 // hide the dialog 522 SendMessage(WM_AWT_COMPONENT_HIDE); 523 524 env->DeleteLocalRef(target); 525 526 return mrConsume; 527 } 528 529 void AwtDialog::SetResizable(BOOL isResizable) 530 { 531 // call superclass 532 AwtFrame::SetResizable(isResizable); 533 534 LONG style = GetStyle(); 535 LONG xstyle = GetStyleEx(); 536 if (isResizable || IsUndecorated()) { 537 // remove modal frame 538 xstyle &= ~WS_EX_DLGMODALFRAME; 539 } else { 540 // add modal frame 541 xstyle |= WS_EX_DLGMODALFRAME; 542 } 543 // dialogs are never minimizable/maximizable, so remove those bits 544 style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX); 545 SetStyle(style); 546 SetStyleEx(xstyle); 547 RedrawNonClient(); 548 } 549 550 // Adjust system menu so that: 551 // Non-resizable dialogs only have Move and Close items 552 // Resizable dialogs have the full system menu with 553 // Maximize, Minimize items disabled (the items 554 // get disabled by the native system). 555 // This perfectly mimics the native MS Windows behavior. 556 // Normally, Win32 dialog system menu handling is done via 557 // CreateDialog/DefDlgProc, but our dialogs are using DefWindowProc 558 // so we handle the system menu ourselves 559 void AwtDialog::UpdateSystemMenu() 560 { 561 HWND hWndSelf = GetHWnd(); 562 BOOL isResizable = IsResizable(); 563 564 // before restoring the default menu, check if there is an 565 // InputMethodManager menu item already. Note that it assumes 566 // that the length of the InputMethodManager menu item string 567 // should not be longer than 256 bytes. 568 MENUITEMINFO mii; 569 memset(&mii, 0, sizeof(MENUITEMINFO)); 570 TCHAR immItem[256]; 571 BOOL hasImm; 572 mii.cbSize = sizeof(MENUITEMINFO); 573 mii.fMask = MIIM_TYPE; 574 mii.cch = sizeof(immItem); 575 mii.dwTypeData = immItem; 576 hasImm = ::GetMenuItemInfo(GetSystemMenu(hWndSelf, FALSE), 577 SYSCOMMAND_IMM, FALSE, &mii); 578 579 // restore the default menu 580 ::GetSystemMenu(hWndSelf, TRUE); 581 // now get a working copy of the menu 582 HMENU hMenuSys = GetSystemMenu(hWndSelf, FALSE); 583 584 if (!isResizable) { 585 // remove inapplicable sizing commands 586 ::DeleteMenu(hMenuSys, SC_MINIMIZE, MF_BYCOMMAND); 587 ::DeleteMenu(hMenuSys, SC_RESTORE, MF_BYCOMMAND); 588 ::DeleteMenu(hMenuSys, SC_MAXIMIZE, MF_BYCOMMAND); 589 ::DeleteMenu(hMenuSys, SC_SIZE, MF_BYCOMMAND); 590 // remove separator if only 3 items left (Move, Separator, and Close) 591 if (::GetMenuItemCount(hMenuSys) == 3) { 592 MENUITEMINFO mi; 593 memset(&mi, 0, sizeof(MENUITEMINFO)); 594 mi.cbSize = sizeof(MENUITEMINFO); 595 mi.fMask = MIIM_TYPE; 596 ::GetMenuItemInfo(hMenuSys, 1, TRUE, &mi); 597 if (mi.fType & MFT_SEPARATOR) { 598 ::DeleteMenu(hMenuSys, 1, MF_BYPOSITION); 599 } 600 } 601 } 602 603 // if there was the InputMethodManager menu item, restore it. 604 if (hasImm) { 605 ::AppendMenu(hMenuSys, MF_STRING, SYSCOMMAND_IMM, immItem); 606 } 607 } 608 609 // Override WmStyleChanged to adjust system menu for sizable/non-resizable dialogs 610 MsgRouting AwtDialog::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 611 { 612 UpdateSystemMenu(); 613 DoUpdateIcon(); 614 return mrConsume; 615 } 616 617 MsgRouting AwtDialog::WmSize(UINT type, int w, int h) 618 { 619 if (type == SIZE_MAXIMIZED || type == SIZE_MINIMIZED 620 || (type == SIZE_RESTORED && !IsResizing())) 621 { 622 UpdateSystemMenu(); // adjust to reflect restored vs. maximized state 623 } 624 625 return AwtFrame::WmSize(type, w, h); 626 } 627 628 LRESULT AwtDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 629 { 630 MsgRouting mr = mrDoDefault; 631 LRESULT retValue = 0L; 632 633 switch(message) { 634 case WM_AWT_DLG_SHOWMODAL: 635 mr = WmShowModal(); 636 break; 637 case WM_AWT_DLG_ENDMODAL: 638 mr = WmEndModal(); 639 break; 640 } 641 642 if (mr != mrConsume) { 643 retValue = AwtFrame::WindowProc(message, wParam, lParam); 644 } 645 return retValue; 646 } 647 648 void AwtDialog::_ShowModal(void *param) 649 { 650 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 651 652 jobject self = (jobject)param; 653 654 AwtDialog *d = NULL; 655 656 PDATA pData; 657 JNI_CHECK_PEER_GOTO(self, ret); 658 d = (AwtDialog *)pData; 659 if (::IsWindow(d->GetHWnd())) { 660 d->SendMessage(WM_AWT_DLG_SHOWMODAL); 661 } 662 ret: 663 env->DeleteGlobalRef(self); 664 } 665 666 void AwtDialog::_EndModal(void *param) 667 { 668 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 669 670 jobject self = (jobject)param; 671 672 AwtDialog *d = NULL; 673 674 PDATA pData; 675 JNI_CHECK_PEER_GOTO(self, ret); 676 d = (AwtDialog *)pData; 677 if (::IsWindow(d->GetHWnd())) { 678 d->SendMessage(WM_AWT_DLG_ENDMODAL); 679 } 680 ret: 681 env->DeleteGlobalRef(self); 682 } 683 684 void AwtDialog::_SetIMMOption(void *param) 685 { 686 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 687 688 SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param; 689 jobject self = sios->dialog; 690 jstring option = sios->option; 691 692 int badAlloc = 0; 693 LPCTSTR coption; 694 LPCTSTR empty = TEXT("InputMethod"); 695 AwtDialog *d = NULL; 696 697 PDATA pData; 698 JNI_CHECK_PEER_GOTO(self, ret); 699 JNI_CHECK_NULL_GOTO(option, "null IMMOption", ret); 700 701 d = (AwtDialog *)pData; 702 if (::IsWindow(d->GetHWnd())) 703 { 704 coption = JNU_GetStringPlatformChars(env, option, NULL); 705 if (coption == NULL) 706 { 707 badAlloc = 1; 708 } 709 if (!badAlloc) 710 { 711 HMENU hSysMenu = ::GetSystemMenu(d->GetHWnd(), FALSE); 712 ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption); 713 714 if (coption != empty) 715 { 716 JNU_ReleaseStringPlatformChars(env, option, coption); 717 } 718 } 719 } 720 ret: 721 env->DeleteGlobalRef(self); 722 env->DeleteGlobalRef(option); 723 724 delete sios; 725 726 if (badAlloc) 727 { 728 throw std::bad_alloc(); 729 } 730 } 731 732 /************************************************************************ 733 * Dialog native methods 734 */ 735 736 extern "C" { 737 738 JNIEXPORT void JNICALL 739 Java_java_awt_Dialog_initIDs(JNIEnv *env, jclass cls) 740 { 741 TRY; 742 743 /* java.awt.Dialog fields and methods */ 744 AwtDialog::titleID 745 = env->GetFieldID(cls, "title", "Ljava/lang/String;"); 746 DASSERT(AwtDialog::titleID != NULL); 747 CHECK_NULL(AwtDialog::titleID); 748 749 AwtDialog::undecoratedID 750 = env->GetFieldID(cls,"undecorated","Z"); 751 DASSERT(AwtDialog::undecoratedID != NULL); 752 CHECK_NULL(AwtDialog::undecoratedID); 753 754 CATCH_BAD_ALLOC; 755 } 756 757 } /* extern "C" */ 758 759 760 /************************************************************************ 761 * DialogPeer native methods 762 */ 763 764 extern "C" { 765 766 /* 767 * Class: sun_awt_windows_WDialogPeer 768 * Method: create 769 * Signature: (Lsun/awt/windows/WComponentPeer;)V 770 */ 771 JNIEXPORT void JNICALL 772 Java_sun_awt_windows_WDialogPeer_createAwtDialog(JNIEnv *env, jobject self, 773 jobject parent) 774 { 775 TRY; 776 777 PDATA pData; 778 AwtToolkit::CreateComponent(self, parent, 779 (AwtToolkit::ComponentFactory) 780 AwtDialog::Create); 781 JNI_CHECK_PEER_CREATION_RETURN(self); 782 783 CATCH_BAD_ALLOC; 784 } 785 786 /* 787 * Class: sun_awt_windows_WDialogPeer 788 * Method: _show 789 * Signature: ()V 790 */ 791 JNIEXPORT void JNICALL 792 Java_sun_awt_windows_WDialogPeer_showModal(JNIEnv *env, jobject self) 793 { 794 TRY; 795 796 jobject selfGlobalRef = env->NewGlobalRef(self); 797 798 AwtToolkit::GetInstance().SyncCall(AwtDialog::_ShowModal, 799 (void *)selfGlobalRef); 800 // selfGlobalRef is deleted in _ShowModal 801 802 CATCH_BAD_ALLOC; 803 } 804 805 /* 806 * Class: sun_awt_windows_WDialogPeer 807 * Method: _hide 808 * Signature: ()V 809 */ 810 JNIEXPORT void JNICALL 811 Java_sun_awt_windows_WDialogPeer_endModal(JNIEnv *env, jobject self) 812 { 813 TRY; 814 815 jobject selfGlobalRef = env->NewGlobalRef(self); 816 817 AwtToolkit::GetInstance().SyncCall(AwtDialog::_EndModal, 818 (void *)selfGlobalRef); 819 // selfGlobalRef is deleted in _EndModal 820 821 CATCH_BAD_ALLOC; 822 } 823 824 /* 825 * Class: sun_awt_windows_WFramePeer 826 * Method: pSetIMMOption 827 * Signature: (Ljava/lang/String;)V 828 */ 829 JNIEXPORT void JNICALL 830 Java_sun_awt_windows_WDialogPeer_pSetIMMOption(JNIEnv *env, jobject self, 831 jstring option) 832 { 833 TRY; 834 835 SetIMMOptionStruct *sios = new SetIMMOptionStruct; 836 sios->dialog = env->NewGlobalRef(self); 837 sios->option = (jstring)env->NewGlobalRef(option); 838 839 AwtToolkit::GetInstance().SyncCall(AwtDialog::_SetIMMOption, sios); 840 // global refs and sios are deleted in _SetIMMOption 841 842 CATCH_BAD_ALLOC; 843 } 844 } /* extern "C" */