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