1 /* 2 * Copyright 1996-2008 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 #include "awt_Toolkit.h" 27 #include "awt_Dialog.h" 28 #include "awt_Window.h" 29 30 #include <windowsx.h> 31 32 #include "java_awt_Dialog.h" 33 34 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 35 */ 36 37 /************************************************************************/ 38 // Struct for _SetIMMOption() method 39 struct SetIMMOptionStruct { 40 jobject dialog; 41 jstring option; 42 }; 43 /************************************************************************ 44 * AwtDialog fields 45 */ 46 47 jfieldID AwtDialog::titleID; 48 jfieldID AwtDialog::undecoratedID; 49 50 #if defined(DEBUG) 51 // counts how many nested modal dialogs are open, a sanity 52 // check to ensure the somewhat complicated disable/enable 53 // code is working properly 54 int AwtModalityNestCounter = 0; 55 #endif 56 57 HHOOK AWTModalHook; 58 HHOOK AWTMouseHook; 59 60 int VisibleModalDialogsCount = 0; 61 62 /************************************************************************ 63 * AwtDialog class methods 64 */ 65 66 AwtDialog::AwtDialog() { 67 m_modalWnd = NULL; 68 } 69 70 AwtDialog::~AwtDialog() 71 { 72 } 73 74 void AwtDialog::Dispose() 75 { 76 if (m_modalWnd != NULL) { 77 WmEndModal(); 78 } 79 AwtFrame::Dispose(); 80 } 81 82 LPCTSTR AwtDialog::GetClassName() { 83 return AWT_DIALOG_WINDOW_CLASS_NAME; 84 } 85 86 void AwtDialog::FillClassInfo(WNDCLASSEX *lpwc) 87 { 88 AwtWindow::FillClassInfo(lpwc); 89 //Fixed 6280303: REGRESSION: Java cup icon appears in title bar of dialogs 90 // Dialog inherits icon from its owner dinamically 91 lpwc->hIcon = NULL; 92 lpwc->hIconSm = NULL; 93 } 94 95 /* 96 * Create a new AwtDialog object and window. 97 */ 98 AwtDialog* AwtDialog::Create(jobject peer, jobject parent) 99 { 100 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 101 102 jobject background = NULL; 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 background = env->GetObjectField(target, 185 AwtComponent::backgroundID); 186 if (background == NULL) { 187 JNU_CallMethodByName(env, NULL, 188 peer, "setDefaultColor", "()V"); 189 } 190 } 191 } catch (...) { 192 env->DeleteLocalRef(background); 193 env->DeleteLocalRef(target); 194 throw; 195 } 196 197 done: 198 env->DeleteLocalRef(background); 199 env->DeleteLocalRef(target); 200 201 return dialog; 202 } 203 204 MsgRouting AwtDialog::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { 205 // By the request from Swing team, click on the Dialog's title should generate Ungrab 206 if (m_grabbedWindow != NULL/* && !m_grabbedWindow->IsOneOfOwnersOf(this)*/) { 207 m_grabbedWindow->Ungrab(); 208 } 209 210 if (!IsFocusableWindow() && (button & LEFT_BUTTON)) { 211 // Dialog is non-maximizable 212 if ((button & DBL_CLICK) && hitTest == HTCAPTION) { 213 return mrConsume; 214 } 215 } 216 return AwtFrame::WmNcMouseDown(hitTest, x, y, button); 217 } 218 219 LRESULT CALLBACK AwtDialog::ModalFilterProc(int code, 220 WPARAM wParam, LPARAM lParam) 221 { 222 HWND hWnd = (HWND)wParam; 223 HWND blocker = AwtWindow::GetModalBlocker(hWnd); 224 if (::IsWindow(blocker) && 225 ((code == HCBT_ACTIVATE) || 226 (code == HCBT_SETFOCUS))) 227 { 228 // fix for 6270632: this window and all its blockers can be minimized by 229 // "show desktop" button, so we should restore them first 230 if (::IsIconic(hWnd)) { 231 ::ShowWindow(hWnd, SW_RESTORE); 232 } 233 PopupAllDialogs(blocker, TRUE, ::GetForegroundWindow(), FALSE); 234 // return 1 to prevent the system from allowing the operation 235 return 1; 236 } 237 return CallNextHookEx(0, code, wParam, lParam); 238 } 239 240 LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, 241 WPARAM wParam, LPARAM lParam) 242 { 243 if (nCode >= 0) 244 { 245 MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT *)lParam; 246 HWND hWnd = mhs->hwnd; 247 if ((wParam == WM_LBUTTONDOWN) || 248 (wParam == WM_MBUTTONDOWN) || 249 (wParam == WM_RBUTTONDOWN) || 250 (wParam == WM_MOUSEACTIVATE) || 251 (wParam == WM_MOUSEWHEEL) || 252 (wParam == WM_NCLBUTTONDOWN) || 253 (wParam == WM_NCMBUTTONDOWN) || 254 (wParam == WM_NCRBUTTONDOWN)) 255 { 256 HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); 257 if (::IsWindow(blocker)) { 258 BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd); 259 PopupAllDialogs(hWnd, FALSE, ::GetForegroundWindow(), onTaskbar); 260 // return a nonzero value to prevent the system from passing 261 // the message to the target window procedure 262 return 1; 263 } 264 } 265 } 266 267 return CallNextHookEx(0, nCode, wParam, lParam); 268 } 269 270 /* 271 * The function goes through the heirarchy of the blocker dialogs and 272 * popups all the dialogs. Note that the function starts from the top 273 * blocker dialog and goes down to the dialog which is the bottom dialog. 274 * Using another traversal may cause to the flickering issue as a bottom 275 * dialog will cover a top dialog for some period of time. 276 */ 277 void AwtDialog::PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) 278 { 279 HWND blocker = AwtWindow::GetModalBlocker(dialog); 280 BOOL isBlocked = ::IsWindow(blocker); 281 if (isBlocked) { 282 PopupAllDialogs(blocker, isModalHook, prevFGWindow, onTaskbar); 283 } 284 PopupOneDialog(dialog, blocker, isModalHook, prevFGWindow, onTaskbar); 285 } 286 287 /* 288 * The function popups the dialog, it distinguishes non-blocked dialogs 289 * and activates the dialogs (sets as foreground window). If the dialog is 290 * blocked, then it changes the Z-order of the dialog. 291 */ 292 void AwtDialog::PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) 293 { 294 if (dialog == AwtToolkit::GetInstance().GetHWnd()) { 295 return; 296 } 297 298 // fix for 6494032 299 if (isModalHook && !::IsWindowVisible(dialog)) { 300 ::ShowWindow(dialog, SW_SHOWNA); 301 } 302 303 BOOL isBlocked = ::IsWindow(blocker); 304 UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; 305 306 if (isBlocked) { 307 ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags); 308 } else { 309 ::SetWindowPos(dialog, 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 && (dialog == prevFGWindow)) { 313 AnimateModalBlocker(dialog); 314 } 315 ::BringWindowToTop(dialog); 316 ::SetForegroundWindow(dialog); 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 jclass wwindowPeerCls = env->FindClass("sun/awt/windows/WWindowPeer"); 453 jmethodID getActiveWindowsMID = env->GetStaticMethodID(wwindowPeerCls, 454 "getActiveWindowHandles", "()[J"); 455 DASSERT(getActiveWindowsMID != NULL); 456 jlongArray windows = (jlongArray)(env->CallStaticObjectMethod(wwindowPeerCls, 457 getActiveWindowsMID)); 458 if (windows == NULL) { 459 return; 460 } 461 462 jboolean isCopy; 463 jlong *ws = env->GetLongArrayElements(windows, &isCopy); 464 int windowsCount = env->GetArrayLength(windows); 465 for (int i = windowsCount - 1; i >= 0; i--) { 466 HWND w = (HWND)ws[i]; 467 if ((w != dialogHWnd) && ModalCanBeActivated(w)) { 468 AwtDialog::ModalPerformActivation(w); 469 break; 470 } 471 } 472 env->ReleaseLongArrayElements(windows, ws, 0); 473 474 env->DeleteLocalRef(windows); 475 } 476 477 MsgRouting AwtDialog::WmShowModal() 478 { 479 DASSERT(::GetCurrentThreadId() == AwtToolkit::MainThread()); 480 481 // fix for 6213128: release capture (got by popups, choices, etc) when 482 // modal dialog is shown 483 HWND capturer = ::GetCapture(); 484 if (capturer != NULL) { 485 ::ReleaseCapture(); 486 } 487 488 SendMessage(WM_AWT_COMPONENT_SHOW); 489 490 CheckInstallModalHook(); 491 492 m_modalWnd = GetHWnd(); 493 494 return mrConsume; 495 } 496 497 MsgRouting AwtDialog::WmEndModal() 498 { 499 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 500 501 DASSERT( ::GetCurrentThreadId() == AwtToolkit::MainThread() ); 502 DASSERT( ::IsWindow(m_modalWnd) ); 503 504 m_modalWnd = NULL; 505 506 CheckUninstallModalHook(); 507 508 HWND parentHWnd = ::GetParent(GetHWnd()); 509 jobject peer = GetPeer(env); 510 jobject target = GetTarget(env); 511 if (::GetForegroundWindow() == GetHWnd()) { 512 ModalActivateNextWindow(GetHWnd(), target, peer); 513 } 514 // hide the dialog 515 SendMessage(WM_AWT_COMPONENT_HIDE); 516 517 env->DeleteLocalRef(target); 518 519 return mrConsume; 520 } 521 522 void AwtDialog::SetResizable(BOOL isResizable) 523 { 524 // call superclass 525 AwtFrame::SetResizable(isResizable); 526 527 LONG style = GetStyle(); 528 LONG xstyle = GetStyleEx(); 529 if (isResizable || IsUndecorated()) { 530 // remove modal frame 531 xstyle &= ~WS_EX_DLGMODALFRAME; 532 } else { 533 // add modal frame 534 xstyle |= WS_EX_DLGMODALFRAME; 535 } 536 // dialogs are never minimizable/maximizable, so remove those bits 537 style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX); 538 SetStyle(style); 539 SetStyleEx(xstyle); 540 RedrawNonClient(); 541 } 542 543 // Adjust system menu so that: 544 // Non-resizable dialogs only have Move and Close items 545 // Resizable dialogs have the full system menu with 546 // Maximize, Minimize items disabled (the items 547 // get disabled by the native system). 548 // This perfectly mimics the native MS Windows behavior. 549 // Normally, Win32 dialog system menu handling is done via 550 // CreateDialog/DefDlgProc, but our dialogs are using DefWindowProc 551 // so we handle the system menu ourselves 552 void AwtDialog::UpdateSystemMenu() 553 { 554 HWND hWndSelf = GetHWnd(); 555 BOOL isResizable = IsResizable(); 556 557 // before restoring the default menu, check if there is an 558 // InputMethodManager menu item already. Note that it assumes 559 // that the length of the InputMethodManager menu item string 560 // should not be longer than 256 bytes. 561 MENUITEMINFO mii; 562 memset(&mii, 0, sizeof(MENUITEMINFO)); 563 TCHAR immItem[256]; 564 BOOL hasImm; 565 mii.cbSize = sizeof(MENUITEMINFO); 566 mii.fMask = MIIM_TYPE; 567 mii.cch = sizeof(immItem); 568 mii.dwTypeData = immItem; 569 hasImm = ::GetMenuItemInfo(GetSystemMenu(hWndSelf, FALSE), 570 SYSCOMMAND_IMM, FALSE, &mii); 571 572 // restore the default menu 573 ::GetSystemMenu(hWndSelf, TRUE); 574 // now get a working copy of the menu 575 HMENU hMenuSys = GetSystemMenu(hWndSelf, FALSE); 576 577 if (!isResizable) { 578 // remove inapplicable sizing commands 579 ::DeleteMenu(hMenuSys, SC_MINIMIZE, MF_BYCOMMAND); 580 ::DeleteMenu(hMenuSys, SC_RESTORE, MF_BYCOMMAND); 581 ::DeleteMenu(hMenuSys, SC_MAXIMIZE, MF_BYCOMMAND); 582 ::DeleteMenu(hMenuSys, SC_SIZE, MF_BYCOMMAND); 583 // remove separator if only 3 items left (Move, Separator, and Close) 584 if (::GetMenuItemCount(hMenuSys) == 3) { 585 MENUITEMINFO mi; 586 memset(&mi, 0, sizeof(MENUITEMINFO)); 587 mi.cbSize = sizeof(MENUITEMINFO); 588 mi.fMask = MIIM_TYPE; 589 ::GetMenuItemInfo(hMenuSys, 1, TRUE, &mi); 590 if (mi.fType & MFT_SEPARATOR) { 591 ::DeleteMenu(hMenuSys, 1, MF_BYPOSITION); 592 } 593 } 594 } 595 596 // if there was the InputMethodManager menu item, restore it. 597 if (hasImm) { 598 ::AppendMenu(hMenuSys, MF_STRING, SYSCOMMAND_IMM, immItem); 599 } 600 } 601 602 // Override WmStyleChanged to adjust system menu for sizable/non-resizable dialogs 603 MsgRouting AwtDialog::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) 604 { 605 UpdateSystemMenu(); 606 DoUpdateIcon(); 607 return mrConsume; 608 } 609 610 MsgRouting AwtDialog::WmSize(UINT type, int w, int h) 611 { 612 if (type == SIZE_MAXIMIZED || type == SIZE_MINIMIZED 613 || (type == SIZE_RESTORED && !IsResizing())) 614 { 615 UpdateSystemMenu(); // adjust to reflect restored vs. maximized state 616 } 617 618 return AwtFrame::WmSize(type, w, h); 619 } 620 621 LRESULT AwtDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 622 { 623 MsgRouting mr = mrDoDefault; 624 LRESULT retValue = 0L; 625 626 switch(message) { 627 case WM_AWT_DLG_SHOWMODAL: 628 mr = WmShowModal(); 629 break; 630 case WM_AWT_DLG_ENDMODAL: 631 mr = WmEndModal(); 632 break; 633 } 634 635 if (mr != mrConsume) { 636 retValue = AwtFrame::WindowProc(message, wParam, lParam); 637 } 638 return retValue; 639 } 640 641 void AwtDialog::_ShowModal(void *param) 642 { 643 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 644 645 jobject self = (jobject)param; 646 647 AwtDialog *d = NULL; 648 649 PDATA pData; 650 JNI_CHECK_PEER_GOTO(self, ret); 651 d = (AwtDialog *)pData; 652 if (::IsWindow(d->GetHWnd())) { 653 d->SendMessage(WM_AWT_DLG_SHOWMODAL); 654 } 655 ret: 656 env->DeleteGlobalRef(self); 657 } 658 659 void AwtDialog::_EndModal(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_ENDMODAL); 672 } 673 ret: 674 env->DeleteGlobalRef(self); 675 } 676 677 void AwtDialog::_SetIMMOption(void *param) 678 { 679 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 680 681 SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param; 682 jobject self = sios->dialog; 683 jstring option = sios->option; 684 685 int badAlloc = 0; 686 LPCTSTR coption; 687 LPCTSTR empty = TEXT("InputMethod"); 688 AwtDialog *d = NULL; 689 690 PDATA pData; 691 JNI_CHECK_PEER_GOTO(self, ret); 692 JNI_CHECK_NULL_GOTO(option, "null IMMOption", ret); 693 694 d = (AwtDialog *)pData; 695 if (::IsWindow(d->GetHWnd())) 696 { 697 coption = JNU_GetStringPlatformChars(env, option, NULL); 698 if (coption == NULL) 699 { 700 badAlloc = 1; 701 } 702 if (!badAlloc) 703 { 704 HMENU hSysMenu = ::GetSystemMenu(d->GetHWnd(), FALSE); 705 ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption); 706 707 if (coption != empty) 708 { 709 JNU_ReleaseStringPlatformChars(env, option, coption); 710 } 711 } 712 } 713 ret: 714 env->DeleteGlobalRef(self); 715 env->DeleteGlobalRef(option); 716 717 delete sios; 718 719 if (badAlloc) 720 { 721 throw std::bad_alloc(); 722 } 723 } 724 725 /************************************************************************ 726 * Dialog native methods 727 */ 728 729 extern "C" { 730 731 JNIEXPORT void JNICALL 732 Java_java_awt_Dialog_initIDs(JNIEnv *env, jclass cls) 733 { 734 TRY; 735 736 /* java.awt.Dialog fields and methods */ 737 AwtDialog::titleID 738 = env->GetFieldID(cls, "title", "Ljava/lang/String;"); 739 AwtDialog::undecoratedID 740 = env->GetFieldID(cls,"undecorated","Z"); 741 742 DASSERT(AwtDialog::undecoratedID != NULL); 743 DASSERT(AwtDialog::titleID != NULL); 744 745 CATCH_BAD_ALLOC; 746 } 747 748 } /* extern "C" */ 749 750 751 /************************************************************************ 752 * DialogPeer native methods 753 */ 754 755 extern "C" { 756 757 /* 758 * Class: sun_awt_windows_WDialogPeer 759 * Method: create 760 * Signature: (Lsun/awt/windows/WComponentPeer;)V 761 */ 762 JNIEXPORT void JNICALL 763 Java_sun_awt_windows_WDialogPeer_create(JNIEnv *env, jobject self, 764 jobject parent) 765 { 766 TRY; 767 768 PDATA pData; 769 AwtToolkit::CreateComponent(self, parent, 770 (AwtToolkit::ComponentFactory) 771 AwtDialog::Create); 772 JNI_CHECK_PEER_CREATION_RETURN(self); 773 774 CATCH_BAD_ALLOC; 775 } 776 777 /* 778 * Class: sun_awt_windows_WDialogPeer 779 * Method: _show 780 * Signature: ()V 781 */ 782 JNIEXPORT void JNICALL 783 Java_sun_awt_windows_WDialogPeer_showModal(JNIEnv *env, jobject self) 784 { 785 TRY; 786 787 jobject selfGlobalRef = env->NewGlobalRef(self); 788 789 AwtToolkit::GetInstance().SyncCall(AwtDialog::_ShowModal, 790 (void *)selfGlobalRef); 791 // selfGlobalRef is deleted in _ShowModal 792 793 CATCH_BAD_ALLOC; 794 } 795 796 /* 797 * Class: sun_awt_windows_WDialogPeer 798 * Method: _hide 799 * Signature: ()V 800 */ 801 JNIEXPORT void JNICALL 802 Java_sun_awt_windows_WDialogPeer_endModal(JNIEnv *env, jobject self) 803 { 804 TRY; 805 806 jobject selfGlobalRef = env->NewGlobalRef(self); 807 808 AwtToolkit::GetInstance().SyncCall(AwtDialog::_EndModal, 809 (void *)selfGlobalRef); 810 // selfGlobalRef is deleted in _EndModal 811 812 CATCH_BAD_ALLOC; 813 } 814 815 /* 816 * Class: sun_awt_windows_WFramePeer 817 * Method: pSetIMMOption 818 * Signature: (Ljava/lang/String;)V 819 */ 820 JNIEXPORT void JNICALL 821 Java_sun_awt_windows_WDialogPeer_pSetIMMOption(JNIEnv *env, jobject self, 822 jstring option) 823 { 824 TRY; 825 826 SetIMMOptionStruct *sios = new SetIMMOptionStruct; 827 sios->dialog = env->NewGlobalRef(self); 828 sios->option = (jstring)env->NewGlobalRef(option); 829 830 AwtToolkit::GetInstance().SyncCall(AwtDialog::_SetIMMOption, sios); 831 // global refs and sios are deleted in _SetIMMOption 832 833 CATCH_BAD_ALLOC; 834 } 835 } /* extern "C" */