| /* |
| * Copyright (c) 1996, 2014, 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 "awt_List.h" |
| #include "awt_Canvas.h" |
| #include "awt_Dimension.h" |
| #include "awt_Toolkit.h" |
| #include "awt_Window.h" |
| |
| #include "ComCtl32Util.h" |
| |
| /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. |
| */ |
| |
| /***********************************************************************/ |
| // struct for _AddItems() method |
| struct AddItemsStruct { |
| jobject list; |
| jobjectArray items; |
| jint index; |
| jint width; |
| }; |
| // struct for _DelItems() method |
| struct DelItemsStruct { |
| jobject list; |
| jint start, end; |
| }; |
| // struct for _IsSelected(), _Select(), _Deselect() and _MakeVisible() methods |
| struct SelectElementStruct { |
| jobject list; |
| jint index; |
| }; |
| // struct for _SetMultipleSelections() method |
| struct SetMultipleSelectionsStruct { |
| jobject list; |
| jboolean on; |
| }; |
| /************************************************************************ |
| * AwtList methods |
| */ |
| |
| AwtList::AwtList() { |
| isMultiSelect = FALSE; |
| isWrapperPrint = FALSE; |
| } |
| |
| AwtList::~AwtList() |
| { |
| } |
| |
| LPCTSTR AwtList::GetClassName() { |
| return TEXT("LISTBOX"); |
| } |
| |
| /* Create a new AwtList object and window. */ |
| AwtList* AwtList::Create(jobject peer, jobject parent) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject target = NULL; |
| AwtList* c = NULL; |
| |
| try { |
| if (env->EnsureLocalCapacity(1) < 0) { |
| return NULL; |
| } |
| |
| PDATA pData; |
| AwtCanvas* awtParent; |
| JNI_CHECK_PEER_GOTO(parent, done); |
| |
| awtParent = (AwtCanvas*)pData; |
| JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done); |
| |
| /* target is Hjava_awt_List * */ |
| target = env->GetObjectField(peer, AwtObject::targetID); |
| JNI_CHECK_NULL_GOTO(target, "null target", done); |
| |
| c = new AwtList(); |
| |
| { |
| |
| /* |
| * NOTE: WS_CLIPCHILDREN is excluded so that repaint requests |
| * from Java will pass through the wrap to the native listbox. |
| */ |
| DWORD wrapStyle = WS_CHILD | WS_CLIPSIBLINGS; |
| DWORD wrapExStyle = 0; |
| |
| DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL | |
| LBS_NOINTEGRALHEIGHT | LBS_NOTIFY | LBS_OWNERDRAWFIXED; |
| DWORD exStyle = WS_EX_CLIENTEDGE; |
| |
| /* |
| * NOTE: WS_VISIBLE is always set for the listbox. Listbox |
| * visibility is controlled by toggling the wrap's WS_VISIBLE bit. |
| */ |
| style |= WS_VISIBLE; |
| |
| if (GetRTL()) { |
| exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR; |
| if (GetRTLReadingOrder()) |
| exStyle |= WS_EX_RTLREADING; |
| } |
| |
| 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); |
| |
| c->CreateHWnd(env, L"", style, exStyle, |
| x, y, width, height, |
| awtParent->GetHWnd(), |
| NULL, |
| ::GetSysColor(COLOR_WINDOWTEXT), |
| ::GetSysColor(COLOR_WINDOW), |
| peer |
| ); |
| |
| /* suppress inheriting awtParent's color. */ |
| c->m_backgroundColorSet = TRUE; |
| c->UpdateBackground(env, target); |
| } |
| } catch (...) { |
| env->DeleteLocalRef(target); |
| throw; |
| } |
| |
| done: |
| env->DeleteLocalRef(target); |
| return c; |
| } |
| |
| void AwtList::SetDragCapture(UINT flags) |
| { |
| // don't want to interfere with other controls |
| if (::GetCapture() == NULL) { |
| ::SetCapture(GetListHandle()); |
| } |
| } |
| |
| void AwtList::ReleaseDragCapture(UINT flags) |
| { |
| if ((::GetCapture() == GetListHandle()) && ((flags & ALL_MK_BUTTONS) == 0)) { |
| ::ReleaseCapture(); |
| } |
| } |
| |
| void AwtList::Reshape(int x, int y, int w, int h) |
| { |
| AwtComponent::Reshape(x, y, w, h); |
| |
| /* |
| HWND hList = GetListHandle(); |
| if (hList != NULL) { |
| long flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS; |
| /* |
| * Fix for bug 4046446. |
| * / |
| SetWindowPos(hList, 0, 0, 0, w, h, flags); |
| } |
| */ |
| } |
| |
| //Netscape : Override the AwtComponent method so we can set the item height |
| //for each item in the list. Modified by echawkes to avoid race condition. |
| |
| void AwtList::SetFont(AwtFont* font) |
| { |
| DASSERT(font != NULL); |
| if (font->GetAscent() < 0) |
| { |
| AwtFont::SetupAscent(font); |
| } |
| HANDLE hFont = font->GetHFont(); |
| SendListMessage(WM_SETFONT, (WPARAM)hFont, MAKELPARAM(FALSE, 0)); |
| |
| HDC hDC = ::GetDC(GetHWnd()); |
| |
| TEXTMETRIC tm; |
| VERIFY(::SelectObject(hDC, hFont) != NULL); |
| VERIFY(::GetTextMetrics(hDC, &tm)); |
| |
| ::ReleaseDC(GetHWnd(), hDC); |
| |
| long h = tm.tmHeight + tm.tmExternalLeading; |
| // Listbox is LBS_OWNERDRAWFIXED so the items have the same height |
| VERIFY(SendListMessage(LB_SETITEMHEIGHT, 0, MAKELPARAM(h, 0)) != LB_ERR); |
| VERIFY(::RedrawWindow(GetHWnd(), NULL, NULL, RDW_INVALIDATE |RDW_FRAME |RDW_ERASE)); |
| } |
| |
| void AwtList::SetMultiSelect(BOOL ms) { |
| if (ms == isMultiSelect) { |
| return; |
| } |
| |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| /* Copy current box's contents to string array */ |
| const int nCount = GetCount(); |
| LPTSTR * strings = new LPTSTR[nCount]; |
| int i; |
| |
| for(i = 0; i < nCount; i++) { |
| LRESULT len = SendListMessage(LB_GETTEXTLEN, i); |
| LPTSTR text = NULL; |
| try { |
| text = new TCHAR[len + 1]; |
| } catch (std::bad_alloc&) { |
| // free char * already allocated |
| for (int j = 0; j < i; j++) { |
| delete [] strings[j]; |
| } |
| delete [] strings; |
| throw; |
| } |
| |
| VERIFY(SendListMessage(LB_GETTEXT, i, (LPARAM)text) != LB_ERR); |
| strings[i] = text; |
| } |
| |
| // index for selected item after multi-select mode change |
| int toSelect = SendListMessage(LB_GETCURSEL); |
| if (!isMultiSelect) |
| { |
| // MSDN: for single-select lists LB_GETCURSEL returns |
| // index of selected item or LB_ERR if no item is selected |
| if (toSelect == LB_ERR) |
| { |
| toSelect = -1; |
| } |
| } |
| else |
| { |
| // MSDN: for multi-select lists LB_GETCURSEL returns index |
| // of the focused item or 0 if no items are selected; if |
| // some item has focus and is not selected then LB_GETCURSEL |
| // return its index, so we need IsItemSelected too |
| if ((toSelect == LB_ERR) || |
| (SendListMessage(LB_GETSELCOUNT) == 0) || |
| (IsItemSelected(toSelect) == 0)) |
| { |
| toSelect = -1; |
| } |
| } |
| |
| isMultiSelect = ms; |
| |
| HWND parentHWnd = GetParent()->GetHWnd(); |
| |
| /* Save old list box's attributes */ |
| RECT rect; |
| GetWindowRect(GetListHandle(), &rect); |
| MapWindowPoints(0, parentHWnd, (LPPOINT)&rect, 2); |
| |
| HANDLE font = (HANDLE)SendListMessage(WM_GETFONT); |
| LRESULT itemHeight = SendListMessage(LB_GETITEMHEIGHT, 0); |
| DWORD style = ::GetWindowLong(GetListHandle(), GWL_STYLE) | WS_VSCROLL | WS_HSCROLL; |
| if (isMultiSelect) { |
| style |= LBS_MULTIPLESEL; |
| } else { |
| style &= ~LBS_MULTIPLESEL; |
| } |
| DWORD exStyle = ::GetWindowLong(GetListHandle(), GWL_EXSTYLE); |
| |
| jobject peer = GetPeer(env); |
| |
| UnsubclassHWND(); |
| AwtToolkit::DestroyComponentHWND(m_hwnd); |
| CreateHWnd(env, L"", style, exStyle, |
| rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, |
| parentHWnd, |
| NULL, |
| ::GetSysColor(COLOR_WINDOWTEXT), |
| ::GetSysColor(COLOR_WINDOW), |
| peer); |
| |
| SendListMessage(WM_SETFONT, (WPARAM)font, (LPARAM)FALSE); |
| SendListMessage(LB_SETITEMHEIGHT, 0, MAKELPARAM(itemHeight, 0)); |
| SendListMessage(LB_RESETCONTENT); |
| for (i = 0; i < nCount; i++) { |
| InsertString(i, strings[i]); |
| delete [] strings[i]; |
| } |
| delete[] strings; |
| if (toSelect != -1) { |
| Select(toSelect); |
| } |
| |
| AdjustHorizontalScrollbar(); |
| } |
| |
| /* |
| * There currently is no good place to cache java.awt.Dimension field |
| * ids. If this method gets called a lot, one such place should be found. |
| * -- br 07/18/97. |
| */ |
| jobject AwtList::PreferredItemSize(JNIEnv *env) |
| { |
| jobject peer = GetPeer(env); |
| jobject dimension = JNU_CallMethodByName(env, NULL, peer, "preferredSize", |
| "(I)Ljava/awt/Dimension;", |
| 1).l; |
| |
| DASSERT(!safe_ExceptionOccurred(env)); |
| if (dimension == NULL) { |
| return NULL; |
| } |
| /* This size is too big for each item height. */ |
| (env)->SetIntField(dimension, AwtDimension::heightID, GetFontHeight(env)); |
| |
| return dimension; |
| } |
| |
| // Every time something gets added to the list, we increase the max width |
| // of items that have ever been added. If it surpasses the width of the |
| // listbox, we show the scrollbar. When things get deleted, we shrink |
| // the scroll region back down and hide the scrollbar, if needed. |
| void AwtList::AdjustHorizontalScrollbar() |
| { |
| // The border width is added to the horizontal extent to ensure that we |
| // can view all of the text when we move the horz. scrollbar to the end. |
| int cxBorders = GetSystemMetrics( SM_CXBORDER ) * 2; |
| RECT rect; |
| VERIFY(::GetClientRect(GetListHandle(), &rect)); |
| LRESULT iHorzExt = SendListMessage(LB_GETHORIZONTALEXTENT, 0, 0L ) - cxBorders; |
| if ( (m_nMaxWidth > rect.left) // if strings wider than listbox |
| || (iHorzExt != m_nMaxWidth) ) // or scrollbar not needed anymore. |
| { |
| SendListMessage(LB_SETHORIZONTALEXTENT, m_nMaxWidth + cxBorders, 0L); |
| } |
| } |
| |
| // This function goes through all strings in the list to find the width, |
| // in pixels, of the longest string in the list. |
| void AwtList::UpdateMaxItemWidth() |
| { |
| m_nMaxWidth = 0; |
| |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| if (env->EnsureLocalCapacity(2) < 0) |
| return; |
| |
| HDC hDC = ::GetDC(GetHWnd()); |
| |
| jobject self = GetPeer(env); |
| DASSERT(self); |
| |
| /* target is java.awt.List */ |
| jobject target = env->GetObjectField(self, AwtObject::targetID); |
| jobject font = GET_FONT(target, self); |
| |
| int nCount = GetCount(); |
| for ( int i=0; i < nCount; i++ ) |
| { |
| jstring jstr = GetItemString( env, target, i ); |
| SIZE size = AwtFont::getMFStringSize( hDC, font, jstr ); |
| if ( size.cx > m_nMaxWidth ) |
| m_nMaxWidth = size.cx; |
| env->DeleteLocalRef( jstr ); |
| } |
| |
| // free up the shared DC and release local refs |
| ::ReleaseDC(GetHWnd(), hDC); |
| env->DeleteLocalRef( target ); |
| env->DeleteLocalRef( font ); |
| |
| // Now adjust the horizontal scrollbar extent |
| AdjustHorizontalScrollbar(); |
| } |
| |
| MsgRouting |
| AwtList::WmSize(UINT type, int w, int h) |
| { |
| AdjustHorizontalScrollbar(); |
| return AwtComponent::WmSize(type, w, h); |
| } |
| |
| MsgRouting |
| AwtList::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo) |
| { |
| AwtComponent::DrawListItem((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), drawInfo); |
| return mrConsume; |
| } |
| |
| MsgRouting |
| AwtList::OwnerMeasureItem(UINT /*ctrlId*/, MEASUREITEMSTRUCT& measureInfo) |
| { |
| AwtComponent::MeasureListItem((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), measureInfo); |
| return mrConsume; |
| } |
| |
| MsgRouting |
| AwtList::WmNcHitTest(UINT x, UINT y, LRESULT& retVal) |
| { |
| if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) { |
| retVal = HTCLIENT; |
| return mrConsume; |
| } |
| return AwtComponent::WmNcHitTest(x, y, retVal); |
| } |
| |
| MsgRouting |
| AwtList::WmMouseUp(UINT flags, int x, int y, int button) |
| { |
| MsgRouting result = mrDoDefault; |
| // if this list is in the modal blocked window, this message should be consumed, |
| // however AwtComponent::WmMouseUp must be called anyway |
| if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) { |
| result = mrConsume; |
| } else { |
| if (button == LEFT_BUTTON) { |
| WmCommand(0, GetListHandle(), LBN_SELCHANGE); |
| } |
| } |
| MsgRouting compResult = AwtComponent::WmMouseUp(flags, x, y, button); |
| return (result == mrConsume) ? result : compResult; |
| } |
| |
| MsgRouting |
| AwtList::WmMouseDown(UINT flags, int x, int y, int button) |
| { |
| MsgRouting mrResult = AwtComponent::WmMouseDown(flags, x, y, button); |
| |
| if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) |
| { |
| return mrConsume; |
| } |
| |
| /* |
| * As we consume WM_LBUTONDOWN the list won't trigger ActionEvent by double click. |
| * We trigger it ourselves. (see also 6240202) |
| */ |
| int clickCount = GetClickCount(); |
| if (button == LEFT_BUTTON && clickCount >= 2 && clickCount % 2 == 0) { |
| WmCommand(0, GetListHandle(), LBN_DBLCLK); |
| } |
| return mrResult; |
| } |
| |
| MsgRouting |
| AwtList::WmCtlColor(HDC hDC, HWND hCtrl, UINT ctlColor, HBRUSH& retBrush) |
| { |
| DASSERT(ctlColor == CTLCOLOR_LISTBOX); |
| DASSERT(hCtrl == GetListHandle()); |
| ::SetBkColor(hDC, GetBackgroundColor()); |
| ::SetTextColor(hDC, GetColor()); |
| retBrush = GetBackgroundBrush(); |
| return mrConsume; |
| } |
| |
| BOOL AwtList::IsFocusingMouseMessage(MSG *pMsg) |
| { |
| return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK; |
| } |
| |
| MsgRouting AwtList::HandleEvent(MSG *msg, BOOL synthetic) |
| { |
| if (IsFocusingMouseMessage(msg)) { |
| LONG item = static_cast<LONG>(SendListMessage(LB_ITEMFROMPOINT, 0, msg->lParam)); |
| if (item != LB_ERR) { |
| if (isMultiSelect) { |
| if (IsItemSelected(item)) { |
| Deselect(item); |
| } else { |
| Select(item); |
| } |
| } else { |
| Select(item); |
| } |
| } |
| delete msg; |
| return mrConsume; |
| } |
| if (msg->message == WM_KEYDOWN && msg->wParam == VK_RETURN) { |
| WmNotify(LBN_DBLCLK); |
| } |
| return AwtComponent::HandleEvent(msg, synthetic); |
| } |
| |
| // Fix for 4665745. |
| // Override WmPrint to catch when the list control (not wrapper) should |
| // operate WM_PRINT to be compatible with the "smooth scrolling" feature. |
| MsgRouting AwtList::WmPrint(HDC hDC, LPARAM flags) |
| { |
| if (!isWrapperPrint && |
| (flags & PRF_CLIENT) && |
| (GetStyleEx() & WS_EX_CLIENTEDGE)) |
| { |
| int nOriginalDC = ::SaveDC(hDC); |
| DASSERT(nOriginalDC != 0); |
| // Save a copy of the DC for WmPrintClient |
| VERIFY(::SaveDC(hDC)); |
| DefWindowProc(WM_PRINT, (WPARAM) hDC, |
| (flags & (PRF_CLIENT | PRF_CHECKVISIBLE | PRF_ERASEBKGND))); |
| VERIFY(::RestoreDC(hDC, nOriginalDC)); |
| |
| flags &= ~PRF_CLIENT; |
| } |
| |
| return AwtComponent::WmPrint(hDC, flags); |
| } |
| |
| MsgRouting |
| AwtList::WmNotify(UINT notifyCode) |
| { |
| if (notifyCode == LBN_SELCHANGE || notifyCode == LBN_DBLCLK) { |
| /* Fixed an asserion failure when clicking on an empty List. */ |
| int nCurrentSelection = SendListMessage(LB_GETCURSEL); |
| if (nCurrentSelection != LB_ERR && GetCount() > 0) { |
| if (notifyCode == LBN_SELCHANGE) { |
| DoCallback("handleListChanged", "(I)V", nCurrentSelection); |
| } |
| else if (notifyCode == LBN_DBLCLK) { |
| DoCallback("handleAction", "(IJI)V", nCurrentSelection, |
| TimeHelper::getMessageTimeUTC(), |
| (jint)AwtComponent::GetJavaModifiers()); |
| } |
| } |
| } |
| return mrDoDefault; |
| } |
| |
| BOOL AwtList::InheritsNativeMouseWheelBehavior() {return true;} |
| |
| jint AwtList::_GetMaxWidth(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject self = (jobject)param; |
| |
| jint result = 0; |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList *)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| result = l->GetMaxWidth(); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| return result; |
| } |
| |
| void AwtList::_UpdateMaxItemWidth(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject self = (jobject)param; |
| |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList *)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| l->UpdateMaxItemWidth(); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| } |
| |
| void AwtList::_AddItems(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| AddItemsStruct *ais = (AddItemsStruct *)param; |
| jobject self = ais->list; |
| jobjectArray items = ais->items; |
| jint index = ais->index; |
| jint width = ais->width; |
| |
| int badAlloc = 0; |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| JNI_CHECK_NULL_GOTO(items, "null items", ret); |
| l = (AwtList*)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| int itemCount = env->GetArrayLength(items); |
| if (itemCount > 0) |
| { |
| AwtList* l = (AwtList*)pData; |
| l->SendListMessage(WM_SETREDRAW, (WPARAM)FALSE, 0); |
| for (jsize i=0; i < itemCount; i++) |
| { |
| LPTSTR itemPtr = NULL; |
| jstring item = (jstring)env->GetObjectArrayElement(items, i); |
| if (env->ExceptionCheck()) goto ret; |
| if (item == NULL) goto next_item; |
| itemPtr = (LPTSTR)JNU_GetStringPlatformChars(env, item, 0); |
| if (itemPtr == NULL) |
| { |
| badAlloc = 1; |
| } |
| else |
| { |
| l->InsertString(index+i, itemPtr); |
| JNU_ReleaseStringPlatformChars(env, item, itemPtr); |
| } |
| env->DeleteLocalRef(item); |
| next_item: |
| ; |
| } |
| l->SendListMessage(WM_SETREDRAW, (WPARAM)TRUE, 0); |
| l->InvalidateList(NULL, TRUE); |
| l->CheckMaxWidth(width); |
| } |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| env->DeleteGlobalRef(items); |
| |
| delete ais; |
| |
| if (badAlloc) |
| { |
| throw std::bad_alloc(); |
| } |
| } |
| |
| void AwtList::_DelItems(void *param) |
| { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| DelItemsStruct *dis = (DelItemsStruct *)param; |
| jobject self = dis->list; |
| jint start = dis->start; |
| jint end = dis->end; |
| |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList*)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| int count = l->GetCount(); |
| |
| if (start == 0 && end == count) |
| { |
| l->SendListMessage(LB_RESETCONTENT); |
| } |
| else |
| { |
| for (int i = start; i <= end; i++) |
| { |
| l->SendListMessage(LB_DELETESTRING, start); |
| } |
| } |
| |
| l->UpdateMaxItemWidth(); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| delete dis; |
| } |
| |
| void AwtList::_Select(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SelectElementStruct *ses = (SelectElementStruct *)param; |
| jobject self = ses->list; |
| jint index = ses->index; |
| |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList*)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| l->Select(index); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| delete ses; |
| } |
| |
| void AwtList::_Deselect(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SelectElementStruct *ses = (SelectElementStruct *)param; |
| jobject self = ses->list; |
| jint index = ses->index; |
| |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList*)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| l->Deselect(index); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| delete ses; |
| } |
| |
| void AwtList::_MakeVisible(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SelectElementStruct *ses = (SelectElementStruct *)param; |
| jobject self = ses->list; |
| jint index = ses->index; |
| |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList*)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| l->SendListMessage(LB_SETTOPINDEX, index); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| delete ses; |
| } |
| |
| jboolean AwtList::_IsSelected(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SelectElementStruct *ses = (SelectElementStruct *)param; |
| jobject self = ses->list; |
| jint index = ses->index; |
| |
| jboolean result = JNI_FALSE; |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList*)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| result = l->IsItemSelected(index); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| delete ses; |
| |
| return result; |
| } |
| |
| void AwtList::_SetMultipleSelections(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SetMultipleSelectionsStruct *sms = (SetMultipleSelectionsStruct *)param; |
| jobject self = sms->list; |
| jboolean on = sms->on; |
| |
| AwtList *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtList*)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| AwtToolkit::GetInstance().SendMessage(WM_AWT_LIST_SETMULTISELECT, |
| (WPARAM)self, on); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| delete sms; |
| } |
| |
| /************************************************************************ |
| * WListPeer native methods |
| * |
| * This class seems to have numerous bugs in it, but they are all bugs |
| * which were present before conversion to JNI. -br. |
| */ |
| |
| extern "C" { |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: getMaxWidth |
| * Signature: ()I |
| */ |
| JNIEXPORT jint JNICALL |
| Java_sun_awt_windows_WListPeer_getMaxWidth(JNIEnv *env, jobject self) |
| { |
| TRY; |
| |
| jobject selfGlobalRef = env->NewGlobalRef(self); |
| |
| return (jint)AwtToolkit::GetInstance().SyncCall( |
| (void *(*)(void *))AwtList::_GetMaxWidth, |
| (void *)selfGlobalRef); |
| // selfGlobalRef is deleted in _GetMaxWidth |
| |
| CATCH_BAD_ALLOC_RET(0); |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: updateMaxItemWidth |
| * Signature: ()V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_updateMaxItemWidth(JNIEnv *env, jobject self) |
| { |
| TRY; |
| |
| jobject selfGlobalRef = env->NewGlobalRef(self); |
| |
| AwtToolkit::GetInstance().SyncCall(AwtList::_UpdateMaxItemWidth, |
| (void *)selfGlobalRef); |
| // selfGlobalRef is deleted in _UpdateMaxItemWidth |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: addItems |
| * Signature: ([Ljava/lang/String;II)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_addItems(JNIEnv *env, jobject self, |
| jobjectArray items, jint index, jint width) |
| { |
| TRY; |
| |
| AddItemsStruct *ais = new AddItemsStruct; |
| ais->list = env->NewGlobalRef(self); |
| ais->items = (jobjectArray)env->NewGlobalRef(items); |
| ais->index = index; |
| ais->width = width; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtList::_AddItems, ais); |
| // global refs and ais are deleted in _AddItems() |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: delItems |
| * Signature: (II)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_delItems(JNIEnv *env, jobject self, |
| jint start, jint end) |
| { |
| TRY; |
| |
| DelItemsStruct *dis = new DelItemsStruct; |
| dis->list = env->NewGlobalRef(self); |
| dis->start = start; |
| dis->end = end; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtList::_DelItems, dis); |
| // global ref and dis are deleted in _DelItems |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: select |
| * Signature: (I)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_select(JNIEnv *env, jobject self, |
| jint pos) |
| { |
| TRY; |
| |
| SelectElementStruct *ses = new SelectElementStruct; |
| ses->list = env->NewGlobalRef(self); |
| ses->index = pos; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtList::_Select, ses); |
| // global ref and ses are deleted in _Select |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: deselect |
| * Signature: (I)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_deselect(JNIEnv *env, jobject self, |
| jint pos) |
| { |
| TRY; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_RETURN(self); |
| |
| SelectElementStruct *ses = new SelectElementStruct; |
| ses->list = env->NewGlobalRef(self); |
| ses->index = pos; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtList::_Deselect, ses); |
| // global ref and ses are deleted in _Deselect |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: makeVisible |
| * Signature: (I)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_makeVisible(JNIEnv *env, jobject self, |
| jint pos) |
| { |
| TRY; |
| |
| SelectElementStruct *ses = new SelectElementStruct; |
| ses->list = env->NewGlobalRef(self); |
| ses->index = pos; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtList::_MakeVisible, ses); |
| // global ref and ses are deleted in _MakeVisible |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: setMultipleSelections |
| * Signature: (Z)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_setMultipleSelections(JNIEnv *env, jobject self, |
| jboolean on) |
| { |
| TRY; |
| |
| SetMultipleSelectionsStruct *sms = new SetMultipleSelectionsStruct; |
| sms->list = env->NewGlobalRef(self); |
| sms->on = on; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtList::_SetMultipleSelections, sms); |
| // global ref and sms are deleted in AwtList::_SetMultipleSelections |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: create |
| * Signature: (Lsun/awt/windows/WComponentPeer;)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WListPeer_create(JNIEnv *env, jobject self, |
| jobject parent) |
| { |
| TRY; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_RETURN(parent); |
| AwtToolkit::CreateComponent(self, parent, |
| (AwtToolkit::ComponentFactory)AwtList::Create); |
| JNI_CHECK_PEER_CREATION_RETURN(self); |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WListPeer |
| * Method: isSelected |
| * Signature: (I)Z |
| */ |
| JNIEXPORT jboolean JNICALL |
| Java_sun_awt_windows_WListPeer_isSelected(JNIEnv *env, jobject self, |
| jint index) |
| { |
| TRY; |
| |
| SelectElementStruct *ses = new SelectElementStruct; |
| ses->list = env->NewGlobalRef(self); |
| ses->index = index; |
| |
| return (jboolean)AwtToolkit::GetInstance().SyncCall( |
| (void *(*)(void *))AwtList::_IsSelected, ses); |
| // global ref and ses are deleted in _IsSelected |
| |
| CATCH_BAD_ALLOC_RET(FALSE); |
| } |
| |
| } /* extern "C" */ |