| /* |
| * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include "jni_util.h" |
| #include "awt_Toolkit.h" |
| #include "awt_Dialog.h" |
| #include "awt_Window.h" |
| |
| #include <windowsx.h> |
| |
| #include "java_awt_Dialog.h" |
| |
| /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. |
| */ |
| |
| /************************************************************************/ |
| // Struct for _SetIMMOption() method |
| struct SetIMMOptionStruct { |
| jobject dialog; |
| jstring option; |
| }; |
| /************************************************************************ |
| * AwtDialog fields |
| */ |
| |
| jfieldID AwtDialog::titleID; |
| jfieldID AwtDialog::undecoratedID; |
| |
| #if defined(DEBUG) |
| // counts how many nested modal dialogs are open, a sanity |
| // check to ensure the somewhat complicated disable/enable |
| // code is working properly |
| int AwtModalityNestCounter = 0; |
| #endif |
| |
| HHOOK AWTModalHook; |
| HHOOK AWTMouseHook; |
| |
| int VisibleModalDialogsCount = 0; |
| |
| /************************************************************************ |
| * AwtDialog class methods |
| */ |
| |
| AwtDialog::AwtDialog() { |
| m_modalWnd = NULL; |
| } |
| |
| AwtDialog::~AwtDialog() |
| { |
| } |
| |
| void AwtDialog::Dispose() |
| { |
| if (m_modalWnd != NULL) { |
| WmEndModal(); |
| } |
| AwtFrame::Dispose(); |
| } |
| |
| LPCTSTR AwtDialog::GetClassName() { |
| return AWT_DIALOG_WINDOW_CLASS_NAME; |
| } |
| |
| void AwtDialog::FillClassInfo(WNDCLASSEX *lpwc) |
| { |
| AwtWindow::FillClassInfo(lpwc); |
| //Fixed 6280303: REGRESSION: Java cup icon appears in title bar of dialogs |
| // Dialog inherits icon from its owner dinamically |
| lpwc->hIcon = NULL; |
| lpwc->hIconSm = NULL; |
| } |
| |
| /* |
| * Create a new AwtDialog object and window. |
| */ |
| AwtDialog* AwtDialog::Create(jobject peer, jobject parent) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject target = NULL; |
| AwtDialog* dialog = NULL; |
| |
| try { |
| if (env->EnsureLocalCapacity(2) < 0) { |
| return NULL; |
| } |
| |
| PDATA pData; |
| AwtWindow* awtParent = NULL; |
| HWND hwndParent = NULL; |
| target = env->GetObjectField(peer, AwtObject::targetID); |
| JNI_CHECK_NULL_GOTO(target, "null target", done); |
| |
| if (parent != NULL) { |
| JNI_CHECK_PEER_GOTO(parent, done); |
| awtParent = (AwtWindow *)(JNI_GET_PDATA(parent)); |
| hwndParent = awtParent->GetHWnd(); |
| } else { |
| // There is no way to prevent a parentless dialog from showing on |
| // the taskbar other than to specify an invisible parent and set |
| // WS_POPUP style for the dialog. Using toolkit window here. That |
| // will also excludes the dialog from appearing in window list while |
| // ALT+TAB'ing |
| // From the other point, it may be confusing when the dialog without |
| // an owner is missing on the toolbar. So, do not set any fake |
| // parent window here. |
| // hwndParent = AwtToolkit::GetInstance().GetHWnd(); |
| } |
| dialog = new AwtDialog(); |
| |
| { |
| int colorId = COLOR_3DFACE; |
| DWORD style = WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN; |
| if (hwndParent != NULL) { |
| style |= WS_POPUP; |
| } |
| style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX); |
| DWORD exStyle = WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME; |
| |
| if (GetRTL()) { |
| exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; |
| if (GetRTLReadingOrder()) |
| exStyle |= WS_EX_RTLREADING; |
| } |
| |
| |
| if (env->GetBooleanField(target, AwtDialog::undecoratedID) == JNI_TRUE) { |
| style = WS_POPUP | WS_CLIPCHILDREN; |
| exStyle = 0; |
| dialog->m_isUndecorated = TRUE; |
| } |
| |
| jint x = env->GetIntField(target, AwtComponent::xID); |
| jint y = env->GetIntField(target, AwtComponent::yID); |
| jint width = env->GetIntField(target, AwtComponent::widthID); |
| jint height = env->GetIntField(target, AwtComponent::heightID); |
| |
| dialog->CreateHWnd(env, L"", |
| style, exStyle, |
| x, y, width, height, |
| hwndParent, |
| NULL, |
| ::GetSysColor(COLOR_WINDOWTEXT), |
| ::GetSysColor(colorId), |
| peer); |
| |
| dialog->RecalcNonClient(); |
| dialog->UpdateSystemMenu(); |
| |
| /* |
| * Initialize icon as inherited from parent if it exists |
| */ |
| if (parent != NULL) { |
| dialog->m_hIcon = awtParent->GetHIcon(); |
| dialog->m_hIconSm = awtParent->GetHIconSm(); |
| dialog->m_iconInherited = TRUE; |
| } |
| dialog->DoUpdateIcon(); |
| |
| } |
| } catch (...) { |
| env->DeleteLocalRef(target); |
| throw; |
| } |
| |
| done: |
| env->DeleteLocalRef(target); |
| |
| return dialog; |
| } |
| |
| MsgRouting AwtDialog::WmNcMouseDown(WPARAM hitTest, int x, int y, int button) { |
| // By the request from Swing team, click on the Dialog's title should generate Ungrab |
| if (m_grabbedWindow != NULL/* && !m_grabbedWindow->IsOneOfOwnersOf(this)*/) { |
| m_grabbedWindow->Ungrab(); |
| } |
| |
| if (!IsFocusableWindow() && (button & LEFT_BUTTON)) { |
| // Dialog is non-maximizable |
| if ((button & DBL_CLICK) && hitTest == HTCAPTION) { |
| return mrConsume; |
| } |
| } |
| return AwtFrame::WmNcMouseDown(hitTest, x, y, button); |
| } |
| |
| LRESULT CALLBACK AwtDialog::ModalFilterProc(int code, |
| WPARAM wParam, LPARAM lParam) |
| { |
| HWND hWnd = (HWND)wParam; |
| HWND blocker = AwtWindow::GetModalBlocker(hWnd); |
| if (::IsWindow(blocker) && |
| ((code == HCBT_ACTIVATE) || |
| (code == HCBT_SETFOCUS))) |
| { |
| // fix for 6270632: this window and all its blockers can be minimized by |
| // "show desktop" button, so we should restore them first |
| if (::IsIconic(hWnd)) { |
| ::ShowWindow(hWnd, SW_RESTORE); |
| } |
| PopupBlockers(blocker, TRUE, ::GetForegroundWindow(), FALSE); |
| // return 1 to prevent the system from allowing the operation |
| return 1; |
| } |
| return CallNextHookEx(0, code, wParam, lParam); |
| } |
| |
| LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, |
| WPARAM wParam, LPARAM lParam) |
| { |
| if (nCode >= 0) |
| { |
| MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT *)lParam; |
| HWND hWnd = mhs->hwnd; |
| if ((wParam == WM_LBUTTONDOWN) || |
| (wParam == WM_MBUTTONDOWN) || |
| (wParam == WM_RBUTTONDOWN) || |
| (wParam == WM_MOUSEACTIVATE) || |
| (wParam == WM_MOUSEWHEEL) || |
| (wParam == WM_NCLBUTTONDOWN) || |
| (wParam == WM_NCMBUTTONDOWN) || |
| (wParam == WM_NCRBUTTONDOWN)) |
| { |
| HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); |
| if (::IsWindow(blocker)) { |
| BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd); |
| PopupBlockers(blocker, FALSE, ::GetForegroundWindow(), onTaskbar); |
| // return a nonzero value to prevent the system from passing |
| // the message to the target window procedure |
| return 1; |
| } |
| } |
| } |
| |
| return CallNextHookEx(0, nCode, wParam, lParam); |
| } |
| |
| /* |
| * The function goes through the hierarchy of the blockers and |
| * popups all the blockers. Note that the function starts from the top |
| * blocker and goes down to the blocker which is the bottom one. |
| * Using another traversal algorithm (bottom->top) may cause to flickering |
| * as the bottom blocker will cover the top blocker for a while. |
| */ |
| void AwtDialog::PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) |
| { |
| HWND nextBlocker = AwtWindow::GetModalBlocker(blocker); |
| BOOL nextBlockerExists = ::IsWindow(nextBlocker); |
| if (nextBlockerExists) { |
| PopupBlockers(nextBlocker, isModalHook, prevFGWindow, onTaskbar); |
| } |
| PopupBlocker(blocker, nextBlocker, isModalHook, prevFGWindow, onTaskbar); |
| } |
| |
| /* |
| * The function popups the blocker, for a non-blocked blocker we need |
| * to activate the blocker but if a blocker is blocked, then we need |
| * to change z-order of the blocker placing the blocker under the next blocker. |
| */ |
| void AwtDialog::PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) |
| { |
| if (blocker == AwtToolkit::GetInstance().GetHWnd()) { |
| return; |
| } |
| |
| // fix for 6494032 |
| if (isModalHook && !::IsWindowVisible(blocker)) { |
| ::ShowWindow(blocker, SW_SHOWNA); |
| } |
| |
| BOOL nextBlockerExists = ::IsWindow(nextBlocker); |
| UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; |
| |
| if (nextBlockerExists) { |
| // Fix for 6829546: if blocker is a top-most window, but window isn't, then |
| // calling ::SetWindowPos(dialog, blocker, ...) makes window top-most as well |
| BOOL topmostNextBlocker = (::GetWindowLong(nextBlocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; |
| BOOL topmostBlocker = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; |
| if (!topmostNextBlocker || topmostBlocker) { |
| ::SetWindowPos(blocker, nextBlocker, 0, 0, 0, 0, flags); |
| } else { |
| ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags); |
| } |
| } else { |
| ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags); |
| // no beep/flash if the mouse was clicked in the taskbar menu |
| // or the dialog is currently inactive |
| if (!isModalHook && !onTaskbar && (blocker == prevFGWindow)) { |
| AnimateModalBlocker(blocker); |
| } |
| ::BringWindowToTop(blocker); |
| ::SetForegroundWindow(blocker); |
| } |
| } |
| |
| void AwtDialog::AnimateModalBlocker(HWND window) |
| { |
| ::MessageBeep(MB_OK); |
| // some heuristics: 3 times x 64 milliseconds |
| AwtWindow::FlashWindowEx(window, 3, 64, FLASHW_CAPTION); |
| } |
| |
| LRESULT CALLBACK AwtDialog::MouseHookProc_NonTT(int nCode, |
| WPARAM wParam, LPARAM lParam) |
| { |
| static HWND lastHWnd = NULL; |
| if (nCode >= 0) |
| { |
| MOUSEHOOKSTRUCT *mhs = (MOUSEHOOKSTRUCT *)lParam; |
| HWND hWnd = mhs->hwnd; |
| HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); |
| if (::IsWindow(blocker)) { |
| if ((wParam == WM_MOUSEMOVE) || |
| (wParam == WM_NCMOUSEMOVE)) |
| { |
| if (lastHWnd != hWnd) { |
| static HCURSOR hArrowCur = ::LoadCursor(NULL, IDC_ARROW); |
| ::SetCursor(hArrowCur); |
| lastHWnd = hWnd; |
| } |
| ::PostMessage(hWnd, WM_SETCURSOR, (WPARAM)hWnd, 0); |
| } else if (wParam == WM_MOUSELEAVE) { |
| lastHWnd = NULL; |
| } |
| |
| AwtDialog::MouseHookProc(nCode, wParam, lParam); |
| return 1; |
| } |
| } |
| |
| return CallNextHookEx(0, nCode, wParam, lParam); |
| } |
| |
| void AwtDialog::Show() |
| { |
| m_visible = true; |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| BOOL locationByPlatform = env->GetBooleanField(GetTarget(env), AwtWindow::locationByPlatformID); |
| if (locationByPlatform) { |
| moveToDefaultLocation(); |
| } |
| EnableTranslucency(TRUE); |
| if (IsFocusableWindow() && (IsAutoRequestFocus() || IsFocusedWindowModalBlocker())) { |
| ::ShowWindow(GetHWnd(), SW_SHOW); |
| } else { |
| ::ShowWindow(GetHWnd(), SW_SHOWNA); |
| } |
| } |
| |
| void AwtDialog::DoUpdateIcon() |
| { |
| AwtFrame::DoUpdateIcon(); |
| //Workaround windows bug: |
| //Decorations are not updated correctly for owned dialogs |
| //when changing dlg with icon <--> dlg without icon |
| RECT winRect; |
| RECT clientRect; |
| ::GetWindowRect(GetHWnd(), &winRect); |
| ::GetClientRect(GetHWnd(), &clientRect); |
| ::MapWindowPoints(HWND_DESKTOP, GetHWnd(), (LPPOINT)&winRect, 2); |
| HRGN winRgn = CreateRectRgnIndirect(&winRect); |
| HRGN clientRgn = CreateRectRgnIndirect(&clientRect); |
| ::CombineRgn(winRgn, winRgn, clientRgn, RGN_DIFF); |
| ::RedrawWindow(GetHWnd(), NULL, winRgn, RDW_FRAME | RDW_INVALIDATE); |
| ::DeleteObject(winRgn); |
| ::DeleteObject(clientRgn); |
| } |
| |
| HICON AwtDialog::GetEffectiveIcon(int iconType) |
| { |
| HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER); |
| BOOL isResizable = ((GetStyle() & WS_THICKFRAME) != 0); |
| BOOL smallIcon = ((iconType == ICON_SMALL) || (iconType == 2/*ICON_SMALL2*/)); |
| HICON hIcon = (smallIcon) ? GetHIconSm() : GetHIcon(); |
| if ((hIcon == NULL) && (isResizable || (hOwner == NULL))) { |
| //Java cup icon is not loaded in window class for dialogs |
| //It needs to be set explicitly for resizable dialogs |
| //and ownerless dialogs |
| hIcon = (smallIcon) ? AwtToolkit::GetInstance().GetAwtIconSm() : |
| AwtToolkit::GetInstance().GetAwtIcon(); |
| } else if ((hIcon != NULL) && IsIconInherited() && !isResizable) { |
| //Non-resizable dialogs without explicitely set icon |
| //Should have no icon |
| hIcon = NULL; |
| } |
| return hIcon; |
| } |
| |
| void AwtDialog::CheckInstallModalHook() { |
| VisibleModalDialogsCount++; |
| if (VisibleModalDialogsCount == 1) { |
| AWTModalHook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)ModalFilterProc, |
| 0, AwtToolkit::MainThread()); |
| AWTMouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHookProc, |
| 0, AwtToolkit::MainThread()); |
| } |
| } |
| |
| void AwtDialog::CheckUninstallModalHook() { |
| if (VisibleModalDialogsCount == 1) { |
| UnhookWindowsHookEx(AWTModalHook); |
| UnhookWindowsHookEx(AWTMouseHook); |
| } |
| VisibleModalDialogsCount--; |
| } |
| |
| void AwtDialog::ModalPerformActivation(HWND hWnd) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| AwtWindow *w = (AwtWindow *)AwtComponent::GetComponent(hWnd); |
| if ((w != NULL) && w->IsEmbeddedFrame()) { |
| jobject target = w->GetTarget(env); |
| env->CallVoidMethod(target, AwtFrame::activateEmbeddingTopLevelMID); |
| env->DeleteLocalRef(target); |
| } else { |
| ::BringWindowToTop(hWnd); |
| ::SetForegroundWindow(hWnd); |
| } |
| } |
| |
| void AwtDialog::ModalActivateNextWindow(HWND dialogHWnd, |
| jobject dialogTarget, jobject dialogPeer) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jboolean exc; |
| jlongArray windows = (jlongArray) JNU_CallStaticMethodByName |
| (env, |
| &exc, |
| "sun/awt/windows/WWindowPeer", |
| "getActiveWindowHandles", |
| "(Ljava/awt/Component;)[J", |
| dialogTarget).l; |
| if (exc == JNI_TRUE) { |
| throw std::bad_alloc(); |
| } |
| if (windows == NULL) { |
| return; |
| } |
| |
| jboolean isCopy; |
| jlong *ws = env->GetLongArrayElements(windows, &isCopy); |
| if (ws == NULL) { |
| throw std::bad_alloc(); |
| } |
| int windowsCount = env->GetArrayLength(windows); |
| for (int i = windowsCount - 1; i >= 0; i--) { |
| HWND w = (HWND)ws[i]; |
| if ((w != dialogHWnd) && ModalCanBeActivated(w)) { |
| AwtDialog::ModalPerformActivation(w); |
| break; |
| } |
| } |
| env->ReleaseLongArrayElements(windows, ws, 0); |
| |
| env->DeleteLocalRef(windows); |
| } |
| |
| MsgRouting AwtDialog::WmShowModal() |
| { |
| DASSERT(::GetCurrentThreadId() == AwtToolkit::MainThread()); |
| |
| // fix for 6213128: release capture (got by popups, choices, etc) when |
| // modal dialog is shown |
| HWND capturer = ::GetCapture(); |
| if (capturer != NULL) { |
| ::ReleaseCapture(); |
| } |
| |
| SendMessage(WM_AWT_COMPONENT_SHOW); |
| |
| CheckInstallModalHook(); |
| |
| m_modalWnd = GetHWnd(); |
| |
| return mrConsume; |
| } |
| |
| MsgRouting AwtDialog::WmEndModal() |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| DASSERT( ::GetCurrentThreadId() == AwtToolkit::MainThread() ); |
| DASSERT( ::IsWindow(m_modalWnd) ); |
| |
| m_modalWnd = NULL; |
| |
| CheckUninstallModalHook(); |
| |
| HWND parentHWnd = ::GetParent(GetHWnd()); |
| jobject peer = GetPeer(env); |
| jobject target = GetTarget(env); |
| if (::GetForegroundWindow() == GetHWnd()) { |
| ModalActivateNextWindow(GetHWnd(), target, peer); |
| } |
| // hide the dialog |
| SendMessage(WM_AWT_COMPONENT_HIDE); |
| |
| env->DeleteLocalRef(target); |
| |
| return mrConsume; |
| } |
| |
| void AwtDialog::SetResizable(BOOL isResizable) |
| { |
| // call superclass |
| AwtFrame::SetResizable(isResizable); |
| |
| LONG style = GetStyle(); |
| LONG xstyle = GetStyleEx(); |
| if (isResizable || IsUndecorated()) { |
| // remove modal frame |
| xstyle &= ~WS_EX_DLGMODALFRAME; |
| } else { |
| // add modal frame |
| xstyle |= WS_EX_DLGMODALFRAME; |
| } |
| // dialogs are never minimizable/maximizable, so remove those bits |
| style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX); |
| SetStyle(style); |
| SetStyleEx(xstyle); |
| RedrawNonClient(); |
| } |
| |
| // Adjust system menu so that: |
| // Non-resizable dialogs only have Move and Close items |
| // Resizable dialogs have the full system menu with |
| // Maximize, Minimize items disabled (the items |
| // get disabled by the native system). |
| // This perfectly mimics the native MS Windows behavior. |
| // Normally, Win32 dialog system menu handling is done via |
| // CreateDialog/DefDlgProc, but our dialogs are using DefWindowProc |
| // so we handle the system menu ourselves |
| void AwtDialog::UpdateSystemMenu() |
| { |
| HWND hWndSelf = GetHWnd(); |
| BOOL isResizable = IsResizable(); |
| |
| // before restoring the default menu, check if there is an |
| // InputMethodManager menu item already. Note that it assumes |
| // that the length of the InputMethodManager menu item string |
| // should not be longer than 256 bytes. |
| MENUITEMINFO mii; |
| memset(&mii, 0, sizeof(MENUITEMINFO)); |
| TCHAR immItem[256]; |
| BOOL hasImm; |
| mii.cbSize = sizeof(MENUITEMINFO); |
| mii.fMask = MIIM_TYPE; |
| mii.cch = sizeof(immItem); |
| mii.dwTypeData = immItem; |
| hasImm = ::GetMenuItemInfo(GetSystemMenu(hWndSelf, FALSE), |
| SYSCOMMAND_IMM, FALSE, &mii); |
| |
| // restore the default menu |
| ::GetSystemMenu(hWndSelf, TRUE); |
| // now get a working copy of the menu |
| HMENU hMenuSys = GetSystemMenu(hWndSelf, FALSE); |
| |
| if (!isResizable) { |
| // remove inapplicable sizing commands |
| ::DeleteMenu(hMenuSys, SC_MINIMIZE, MF_BYCOMMAND); |
| ::DeleteMenu(hMenuSys, SC_RESTORE, MF_BYCOMMAND); |
| ::DeleteMenu(hMenuSys, SC_MAXIMIZE, MF_BYCOMMAND); |
| ::DeleteMenu(hMenuSys, SC_SIZE, MF_BYCOMMAND); |
| // remove separator if only 3 items left (Move, Separator, and Close) |
| if (::GetMenuItemCount(hMenuSys) == 3) { |
| MENUITEMINFO mi; |
| memset(&mi, 0, sizeof(MENUITEMINFO)); |
| mi.cbSize = sizeof(MENUITEMINFO); |
| mi.fMask = MIIM_TYPE; |
| ::GetMenuItemInfo(hMenuSys, 1, TRUE, &mi); |
| if (mi.fType & MFT_SEPARATOR) { |
| ::DeleteMenu(hMenuSys, 1, MF_BYPOSITION); |
| } |
| } |
| } |
| |
| // if there was the InputMethodManager menu item, restore it. |
| if (hasImm) { |
| ::AppendMenu(hMenuSys, MF_STRING, SYSCOMMAND_IMM, immItem); |
| } |
| } |
| |
| // Override WmStyleChanged to adjust system menu for sizable/non-resizable dialogs |
| MsgRouting AwtDialog::WmStyleChanged(int wStyleType, LPSTYLESTRUCT lpss) |
| { |
| UpdateSystemMenu(); |
| DoUpdateIcon(); |
| return mrConsume; |
| } |
| |
| MsgRouting AwtDialog::WmSize(UINT type, int w, int h) |
| { |
| if (type == SIZE_MAXIMIZED || type == SIZE_MINIMIZED |
| || (type == SIZE_RESTORED && !IsResizing())) |
| { |
| UpdateSystemMenu(); // adjust to reflect restored vs. maximized state |
| } |
| |
| return AwtFrame::WmSize(type, w, h); |
| } |
| |
| LRESULT AwtDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) |
| { |
| MsgRouting mr = mrDoDefault; |
| LRESULT retValue = 0L; |
| |
| switch(message) { |
| case WM_AWT_DLG_SHOWMODAL: |
| mr = WmShowModal(); |
| break; |
| case WM_AWT_DLG_ENDMODAL: |
| mr = WmEndModal(); |
| break; |
| } |
| |
| if (mr != mrConsume) { |
| retValue = AwtFrame::WindowProc(message, wParam, lParam); |
| } |
| return retValue; |
| } |
| |
| void AwtDialog::_ShowModal(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject self = (jobject)param; |
| |
| AwtDialog *d = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| d = (AwtDialog *)pData; |
| if (::IsWindow(d->GetHWnd())) { |
| d->SendMessage(WM_AWT_DLG_SHOWMODAL); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| } |
| |
| void AwtDialog::_EndModal(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject self = (jobject)param; |
| |
| AwtDialog *d = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| d = (AwtDialog *)pData; |
| if (::IsWindow(d->GetHWnd())) { |
| d->SendMessage(WM_AWT_DLG_ENDMODAL); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| } |
| |
| void AwtDialog::_SetIMMOption(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SetIMMOptionStruct *sios = (SetIMMOptionStruct *)param; |
| jobject self = sios->dialog; |
| jstring option = sios->option; |
| |
| int badAlloc = 0; |
| LPCTSTR coption; |
| LPCTSTR empty = TEXT("InputMethod"); |
| AwtDialog *d = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| JNI_CHECK_NULL_GOTO(option, "null IMMOption", ret); |
| |
| d = (AwtDialog *)pData; |
| if (::IsWindow(d->GetHWnd())) |
| { |
| coption = JNU_GetStringPlatformChars(env, option, NULL); |
| if (coption == NULL) |
| { |
| badAlloc = 1; |
| } |
| if (!badAlloc) |
| { |
| HMENU hSysMenu = ::GetSystemMenu(d->GetHWnd(), FALSE); |
| ::AppendMenu(hSysMenu, MF_STRING, SYSCOMMAND_IMM, coption); |
| |
| if (coption != empty) |
| { |
| JNU_ReleaseStringPlatformChars(env, option, coption); |
| } |
| } |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| env->DeleteGlobalRef(option); |
| |
| delete sios; |
| |
| if (badAlloc) |
| { |
| throw std::bad_alloc(); |
| } |
| } |
| |
| /************************************************************************ |
| * Dialog native methods |
| */ |
| |
| extern "C" { |
| |
| JNIEXPORT void JNICALL |
| Java_java_awt_Dialog_initIDs(JNIEnv *env, jclass cls) |
| { |
| TRY; |
| |
| /* java.awt.Dialog fields and methods */ |
| AwtDialog::titleID |
| = env->GetFieldID(cls, "title", "Ljava/lang/String;"); |
| DASSERT(AwtDialog::titleID != NULL); |
| CHECK_NULL(AwtDialog::titleID); |
| |
| AwtDialog::undecoratedID |
| = env->GetFieldID(cls,"undecorated","Z"); |
| DASSERT(AwtDialog::undecoratedID != NULL); |
| CHECK_NULL(AwtDialog::undecoratedID); |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| } /* extern "C" */ |
| |
| |
| /************************************************************************ |
| * DialogPeer native methods |
| */ |
| |
| extern "C" { |
| |
| /* |
| * Class: sun_awt_windows_WDialogPeer |
| * Method: create |
| * Signature: (Lsun/awt/windows/WComponentPeer;)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WDialogPeer_createAwtDialog(JNIEnv *env, jobject self, |
| jobject parent) |
| { |
| TRY; |
| |
| PDATA pData; |
| AwtToolkit::CreateComponent(self, parent, |
| (AwtToolkit::ComponentFactory) |
| AwtDialog::Create); |
| JNI_CHECK_PEER_CREATION_RETURN(self); |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WDialogPeer |
| * Method: _show |
| * Signature: ()V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WDialogPeer_showModal(JNIEnv *env, jobject self) |
| { |
| TRY; |
| |
| jobject selfGlobalRef = env->NewGlobalRef(self); |
| |
| AwtToolkit::GetInstance().SyncCall(AwtDialog::_ShowModal, |
| (void *)selfGlobalRef); |
| // selfGlobalRef is deleted in _ShowModal |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WDialogPeer |
| * Method: _hide |
| * Signature: ()V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WDialogPeer_endModal(JNIEnv *env, jobject self) |
| { |
| TRY; |
| |
| jobject selfGlobalRef = env->NewGlobalRef(self); |
| |
| AwtToolkit::GetInstance().SyncCall(AwtDialog::_EndModal, |
| (void *)selfGlobalRef); |
| // selfGlobalRef is deleted in _EndModal |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WFramePeer |
| * Method: pSetIMMOption |
| * Signature: (Ljava/lang/String;)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WDialogPeer_pSetIMMOption(JNIEnv *env, jobject self, |
| jstring option) |
| { |
| TRY; |
| |
| SetIMMOptionStruct *sios = new SetIMMOptionStruct; |
| sios->dialog = env->NewGlobalRef(self); |
| sios->option = (jstring)env->NewGlobalRef(option); |
| |
| AwtToolkit::GetInstance().SyncCall(AwtDialog::_SetIMMOption, sios); |
| // global refs and sios are deleted in _SetIMMOption |
| |
| CATCH_BAD_ALLOC; |
| } |
| } /* extern "C" */ |