62 // Struct for _Remove() method 63 struct RemoveStruct { 64 jobject choice; 65 jint index; 66 }; 67 68 /************************************************************************/ 69 70 /* Bug #4509045: set if SetDragCapture captured mouse */ 71 72 BOOL AwtChoice::mouseCapture = FALSE; 73 74 /* Bug #4338368: consume the spurious MouseUp when the choice loses focus */ 75 76 BOOL AwtChoice::skipNextMouseUp = FALSE; 77 78 BOOL AwtChoice::sm_isMouseMoveInList = FALSE; 79 80 static const UINT MINIMUM_NUMBER_OF_VISIBLE_ITEMS = 8; 81 82 /************************************************************************* 83 * AwtChoice class methods 84 */ 85 86 AwtChoice::AwtChoice() { 87 m_hList = NULL; 88 m_listDefWindowProc = NULL; 89 m_selectedItem = -1; 90 } 91 92 LPCTSTR AwtChoice::GetClassName() { 93 return TEXT("COMBOBOX"); /* System provided combobox class */ 94 } 95 96 void AwtChoice::Dispose() { 97 if (m_hList != NULL && m_listDefWindowProc != NULL) { 98 ComCtl32Util::GetInstance().UnsubclassHWND(m_hList, ListWindowProc, m_listDefWindowProc); 99 } 100 AwtComponent::Dispose(); 101 } 102 103 AwtChoice* AwtChoice::Create(jobject peer, jobject parent) { 104 105 106 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 107 108 jobject target = NULL; 109 AwtChoice* c = NULL; 110 RECT rc; 111 112 try { 113 if (env->EnsureLocalCapacity(1) < 0) { 114 return NULL; 115 } 116 AwtCanvas* awtParent; 117 118 JNI_CHECK_NULL_GOTO(parent, "null parent", done); 119 120 awtParent = (AwtCanvas*)JNI_GET_PDATA(parent); 121 JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done); 122 123 target = env->GetObjectField(peer, AwtObject::targetID); 124 JNI_CHECK_NULL_GOTO(target, "null target", done); 125 421 case WM_LBUTTONUP: { 422 lastClickX = -1; 423 lastClickY = -1; 424 425 AwtChoice *c = (AwtChoice *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); 426 if (c != NULL) { 427 // forward the msg to the choice 428 c->WindowProc(message, wParam, lParam); 429 } 430 } 431 } 432 return ComCtl32Util::GetInstance().DefWindowProc(NULL, hwnd, message, wParam, lParam); 433 434 CATCH_BAD_ALLOC_RET(0); 435 } 436 437 438 MsgRouting AwtChoice::WmNotify(UINT notifyCode) 439 { 440 if (notifyCode == CBN_SELCHANGE) { 441 int selectedItem = (int)SendMessage(CB_GETCURSEL); 442 if (selectedItem != CB_ERR && m_selectedItem != selectedItem){ 443 m_selectedItem = selectedItem; 444 DoCallback("handleAction", "(I)V", selectedItem); 445 } 446 } else if (notifyCode == CBN_DROPDOWN) { 447 448 if (m_hList == NULL) { 449 COMBOBOXINFO cbi; 450 cbi.cbSize = sizeof(COMBOBOXINFO); 451 ::GetComboBoxInfo(GetHWnd(), &cbi); 452 m_hList = cbi.hwndList; 453 m_listDefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(m_hList, ListWindowProc); 454 DASSERT(::GetWindowLongPtr(m_hList, GWLP_USERDATA) == NULL); 455 ::SetWindowLongPtr(m_hList, GWLP_USERDATA, (LONG_PTR)this); 456 } 457 sm_isMouseMoveInList = FALSE; 458 459 // Clicking in the dropdown list steals focus from the proxy. 460 // So, set the focus-restore flag up. 461 SetRestoreFocus(TRUE); 462 } else if (notifyCode == CBN_CLOSEUP) { 463 SetRestoreFocus(FALSE); 464 } 677 678 AwtChoice *c = NULL; 679 680 PDATA pData; 681 JNI_CHECK_PEER_GOTO(choice, done); 682 683 c = (AwtChoice *)pData; 684 if (::IsWindow(c->GetHWnd()) && c->SendMessage(CB_GETDROPPEDSTATE, 0, 0)) { 685 c->SendMessage(CB_SHOWDROPDOWN, FALSE, 0); 686 } 687 688 done: 689 env->DeleteGlobalRef(choice); 690 } 691 692 /************************************************************************ 693 * WChoicePeer native methods 694 */ 695 696 extern "C" { 697 698 /* 699 * Class: sun_awt_windows_WChoicePeer 700 * Method: select 701 * Signature: (I)V 702 */ 703 JNIEXPORT void JNICALL 704 Java_sun_awt_windows_WChoicePeer_select(JNIEnv *env, jobject self, 705 jint index) 706 { 707 TRY; 708 709 SelectStruct *ss = new SelectStruct; 710 ss->choice = env->NewGlobalRef(self); 711 ss->index = index; 712 713 AwtToolkit::GetInstance().SyncCall(AwtChoice::_Select, ss); 714 // global refs and ss are removed in _Select 715 716 CATCH_BAD_ALLOC; | 62 // Struct for _Remove() method 63 struct RemoveStruct { 64 jobject choice; 65 jint index; 66 }; 67 68 /************************************************************************/ 69 70 /* Bug #4509045: set if SetDragCapture captured mouse */ 71 72 BOOL AwtChoice::mouseCapture = FALSE; 73 74 /* Bug #4338368: consume the spurious MouseUp when the choice loses focus */ 75 76 BOOL AwtChoice::skipNextMouseUp = FALSE; 77 78 BOOL AwtChoice::sm_isMouseMoveInList = FALSE; 79 80 static const UINT MINIMUM_NUMBER_OF_VISIBLE_ITEMS = 8; 81 82 namespace { 83 jfieldID selectedIndexID; 84 } 85 86 /************************************************************************* 87 * AwtChoice class methods 88 */ 89 90 AwtChoice::AwtChoice() { 91 m_hList = NULL; 92 m_listDefWindowProc = NULL; 93 } 94 95 LPCTSTR AwtChoice::GetClassName() { 96 return TEXT("COMBOBOX"); /* System provided combobox class */ 97 } 98 99 void AwtChoice::Dispose() { 100 if (m_hList != NULL && m_listDefWindowProc != NULL) { 101 ComCtl32Util::GetInstance().UnsubclassHWND(m_hList, ListWindowProc, m_listDefWindowProc); 102 } 103 AwtComponent::Dispose(); 104 } 105 106 AwtChoice* AwtChoice::Create(jobject peer, jobject parent) { 107 108 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 109 110 jobject target = NULL; 111 AwtChoice* c = NULL; 112 RECT rc; 113 114 try { 115 if (env->EnsureLocalCapacity(1) < 0) { 116 return NULL; 117 } 118 AwtCanvas* awtParent; 119 120 JNI_CHECK_NULL_GOTO(parent, "null parent", done); 121 122 awtParent = (AwtCanvas*)JNI_GET_PDATA(parent); 123 JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done); 124 125 target = env->GetObjectField(peer, AwtObject::targetID); 126 JNI_CHECK_NULL_GOTO(target, "null target", done); 127 423 case WM_LBUTTONUP: { 424 lastClickX = -1; 425 lastClickY = -1; 426 427 AwtChoice *c = (AwtChoice *)::GetWindowLongPtr(hwnd, GWLP_USERDATA); 428 if (c != NULL) { 429 // forward the msg to the choice 430 c->WindowProc(message, wParam, lParam); 431 } 432 } 433 } 434 return ComCtl32Util::GetInstance().DefWindowProc(NULL, hwnd, message, wParam, lParam); 435 436 CATCH_BAD_ALLOC_RET(0); 437 } 438 439 440 MsgRouting AwtChoice::WmNotify(UINT notifyCode) 441 { 442 if (notifyCode == CBN_SELCHANGE) { 443 int selectedIndex = (int)SendMessage(CB_GETCURSEL); 444 445 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 446 jobject target = GetTarget(env); 447 int previousIndex = env->GetIntField(target, selectedIndexID); 448 449 if (selectedIndex != CB_ERR && selectedIndex != previousIndex){ 450 DoCallback("handleAction", "(I)V", selectedIndex); 451 } 452 } else if (notifyCode == CBN_DROPDOWN) { 453 454 if (m_hList == NULL) { 455 COMBOBOXINFO cbi; 456 cbi.cbSize = sizeof(COMBOBOXINFO); 457 ::GetComboBoxInfo(GetHWnd(), &cbi); 458 m_hList = cbi.hwndList; 459 m_listDefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(m_hList, ListWindowProc); 460 DASSERT(::GetWindowLongPtr(m_hList, GWLP_USERDATA) == NULL); 461 ::SetWindowLongPtr(m_hList, GWLP_USERDATA, (LONG_PTR)this); 462 } 463 sm_isMouseMoveInList = FALSE; 464 465 // Clicking in the dropdown list steals focus from the proxy. 466 // So, set the focus-restore flag up. 467 SetRestoreFocus(TRUE); 468 } else if (notifyCode == CBN_CLOSEUP) { 469 SetRestoreFocus(FALSE); 470 } 683 684 AwtChoice *c = NULL; 685 686 PDATA pData; 687 JNI_CHECK_PEER_GOTO(choice, done); 688 689 c = (AwtChoice *)pData; 690 if (::IsWindow(c->GetHWnd()) && c->SendMessage(CB_GETDROPPEDSTATE, 0, 0)) { 691 c->SendMessage(CB_SHOWDROPDOWN, FALSE, 0); 692 } 693 694 done: 695 env->DeleteGlobalRef(choice); 696 } 697 698 /************************************************************************ 699 * WChoicePeer native methods 700 */ 701 702 extern "C" { 703 704 JNIEXPORT void JNICALL 705 Java_java_awt_Choice_initIDs(JNIEnv *env, jclass cls) 706 { 707 TRY; 708 selectedIndexID = env->GetFieldID(cls, "selectedIndex", "I"); 709 DASSERT(selectedIndexID); 710 CATCH_BAD_ALLOC; 711 } 712 713 /* 714 * Class: sun_awt_windows_WChoicePeer 715 * Method: select 716 * Signature: (I)V 717 */ 718 JNIEXPORT void JNICALL 719 Java_sun_awt_windows_WChoicePeer_select(JNIEnv *env, jobject self, 720 jint index) 721 { 722 TRY; 723 724 SelectStruct *ss = new SelectStruct; 725 ss->choice = env->NewGlobalRef(self); 726 ss->index = index; 727 728 AwtToolkit::GetInstance().SyncCall(AwtChoice::_Select, ss); 729 // global refs and ss are removed in _Select 730 731 CATCH_BAD_ALLOC; |