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