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