JNIEXPORT void JNICALL
Java_sun_awt_pocketpc_PPCChoicePeer_select( JNIEnv *env,
        jobject self,
        jint index )
{
    CHECK_PEER( self );
    AwtChoice *c = PDATA( AwtChoice, self );
    c->SendMessage( CB_SETCURSEL, index );
    return;
}
// Create a new AwtChoice object and window.
AwtChoice*
AwtChoice::Create( jobject peer, jobject hParent )
{
    JNIEnv *env;
    if ( JVM->AttachCurrentThread( (void **)&env, 0 ) != 0 ) {
        return 0;
    }
    CHECK_NULL_RETURN( hParent, "null hParent" );
    AwtCanvas *parent = PDATA( AwtCanvas, hParent );
    CHECK_NULL_RETURN( parent, "null parent" );
    jobject target = env->GetObjectField( peer,
                                          WCachedIDs.PPCObjectPeer_targetFID );
    CHECK_NULL_RETURN( target, "null target" );

    AwtChoice *c = new AwtChoice();
    CHECK_NULL_RETURN( c, "AwtChoice() failed" );

#ifndef WINCE
    DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL |
                  CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED;
#else
    // WINCE does not support OWNERDRAW combo boxes.
    DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL |
                  CBS_DROPDOWNLIST;
#endif // !WINCE

    // In OWNER_DRAW, the size of the edit control part of the choice
    // must be determinded in its creation, when the parent cannot get
    // the choice's instance from its handle.  So record the pair of
    // the ID and the instance of the choice.
    UINT myId = parent->CreateControlID();
    ASSERT( myId > 0 );
    c->m_myControlID = myId;
    parent->PushChild( myId, c );

    c->CreateHWnd( TEXT(""), style, 0,
                   env->CallIntMethod( target,
                                       WCachedIDs.java_awt_Component_getXMID ),
                   env->CallIntMethod( target,
                                       WCachedIDs.java_awt_Component_getYMID ),
                   env->CallIntMethod( target,
                                       WCachedIDs.java_awt_Component_getWidthMID ),
                   env->CallIntMethod( target,
                                       WCachedIDs.java_awt_Component_getHeightMID ),
                   parent->GetHWnd(),
                   (HMENU)myId,
                   ::GetSysColor( COLOR_WINDOWTEXT ),
                   ::GetSysColor( COLOR_WINDOW ),
                   peer
                 );
    c->m_backgroundColorSet = TRUE;  // suppress inheriting parent's color.
    return c;
}
/*
 * Class:     sun_awt_windows_WChoicePeer
 * Method:    select
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WChoicePeer_select(JNIEnv *env, jobject self,
					jint index)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtChoice* c = (AwtChoice*)pData;
    c->SendMessage(CB_SETCURSEL, index);

    CATCH_BAD_ALLOC;
}
/*
 * Class:     sun_awt_windows_WChoicePeer
 * Method:    removeAll
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WChoicePeer_removeAll(JNIEnv *env, jobject self)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtChoice* c = (AwtChoice *)pData;
    c->SendMessage(CB_RESETCONTENT, 0, 0);
    c->ResetDropDownHeight();
    c->VerifyState();

    CATCH_BAD_ALLOC;
}
JNIEXPORT void JNICALL
Java_sun_awt_pocketpc_PPCChoicePeer_reshape( JNIEnv *env,
        jobject self,
        jint x,
        jint y,
        jint width,
        jint height )
{
    CHECK_PEER( self );
    AwtChoice *c = PDATA( AwtChoice, self );
    c->Reshape( x, y, width, height );
    c->VerifyState();
    return;
}
JNIEXPORT void JNICALL
Java_sun_awt_pocketpc_PPCChoicePeer_remove( JNIEnv *env,
        jobject self,
        jint index )
{
    CHECK_PEER( self );
    AwtChoice* c = PDATA( AwtChoice, self );
    c->SendMessage( CB_DELETESTRING, index, 0 );
    c->ResetDropDownHeight();
#ifdef DEBUG
    c->VerifyState();
#endif // DEBUG
    return;
}
/*
 * Class:     sun_awt_windows_WChoicePeer
 * Method:    reshape
 * Signature: (IIII)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WChoicePeer_reshape(JNIEnv *env, jobject self,
					 jint x, jint y,
					 jint width, jint height)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtChoice* c = (AwtChoice *)pData;
    c->Reshape(x, y, width, height);
    c->VerifyState();

    CATCH_BAD_ALLOC;
}
/*
 * Class:     sun_awt_windows_WChoicePeer
 * Method:    remove
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WChoicePeer_remove(JNIEnv *env, jobject self,
					jint index)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtChoice* c = (AwtChoice *)pData;
    c->SendMessage(CB_DELETESTRING, index, 0);
    c->ResetDropDownHeight();
    c->VerifyState();

    CATCH_BAD_ALLOC;
}
JNIEXPORT void JNICALL
Java_sun_awt_pocketpc_PPCChoicePeer_addItem( JNIEnv *env,
        jobject self,
        jstring itemText,
        jint index )
{
    CHECK_PEER( self );
    CHECK_NULL( itemText, "null itemText" );

    AwtChoice *c = PDATA( AwtChoice, self );
    c->SendMessage( CB_INSERTSTRING, index, JavaStringBuffer( env, itemText ) );
    c->ResetDropDownHeight();
#ifdef DEBUG
    c->VerifyState();
#endif // DEBUG
    return;
}
/*
 * Class:     sun_awt_windows_WChoicePeer
 * Method:    addItems
 * Signature: ([Ljava/lang/String;I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WChoicePeer_addItems(JNIEnv *env, jobject self,
					  jobjectArray items, jint index)
{
    TRY;

    JNI_CHECK_NULL_RETURN(items, "null items");

    PDATA pData;
    jsize i;
    JNI_CHECK_PEER_RETURN(self);

    AwtChoice* c = (AwtChoice*)pData;
    int itemCount = env->GetArrayLength(items);
   if (itemCount > 0) {
       c->SendMessage(WM_SETREDRAW, (WPARAM)FALSE, 0);
       for (i=0; i<itemCount; i++) {
           jstring item = (jstring)env->GetObjectArrayElement(items, i);
           JNI_CHECK_NULL_RETURN(item, "null item");
           c->SendMessage(CB_INSERTSTRING, index+i, JavaStringBuffer(env, item));
	   env->DeleteLocalRef(item);
       }
       c->SendMessage(WM_SETREDRAW, (WPARAM)TRUE, 0);
       InvalidateRect(c->GetHWnd(), NULL, TRUE);
       c->ResetDropDownHeight();
       c->VerifyState();
    }

    CATCH_BAD_ALLOC;
}
AwtChoice* AwtChoice::Create(jobject peer, jobject parent) {


    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject target = NULL;
    AwtChoice* c = NULL;
    RECT rc;

    try {
        if (env->EnsureLocalCapacity(1) < 0) {
	    return NULL;
	}
	AwtCanvas* awtParent;

	JNI_CHECK_NULL_GOTO(parent, "null parent", done);

	awtParent = (AwtCanvas*)JNI_GET_PDATA(parent);
	JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);

	target = env->GetObjectField(peer, AwtObject::targetID);
	JNI_CHECK_NULL_GOTO(target, "null target", done);

	c = new AwtChoice();

	{
	    DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL |
	                  CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED;
	    DWORD exStyle = 0;
	    if (GetRTL()) {
	        exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
		if (GetRTLReadingOrder())
		    exStyle |= WS_EX_RTLREADING;
	    }

	    /*
	     * In OWNER_DRAW, the size of the edit control part of the
	     * choice must be determinded in its creation, when the parent
	     * cannot get the choice's instance from its handle.  So
	     * record the pair of the ID and the instance of the choice.
	     */
	    UINT myId = awtParent->CreateControlID();
	    DASSERT(myId > 0);
	    c->m_myControlID = myId;
	    awtParent->PushChild(myId, c);

	    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);
	    
            jobject dimension = JNU_CallMethodByName(env, NULL, peer,
                                                     "preferredSize",
                                                     "()Ljava/awt/Dimension;").l;
            DASSERT(!safe_ExceptionOccurred(env));

            if (dimension != NULL && width == 0) {
                width = env->GetIntField(dimension, AwtDimension::widthID);
            }
	    c->CreateHWnd(env, L"", style, exStyle,
			  x, y, width, height,
			  awtParent->GetHWnd(),
			  reinterpret_cast<HMENU>(static_cast<INT_PTR>(myId)),
			  ::GetSysColor(COLOR_WINDOWTEXT),
			  ::GetSysColor(COLOR_WINDOW),
			  peer);

	    /* suppress inheriting parent's color. */
	    c->m_backgroundColorSet = TRUE;
            c->UpdateBackground(env, target);

            /* Bug 4255631 Solaris: Size returned by Choice.getSize() does not match
             * actual size
             * Fix: Set the Choice to its actual size in the component.
             */
            ::GetClientRect(c->GetHWnd(), &rc);
            env->SetIntField(target, AwtComponent::widthID,  (jint) rc.right);
            env->SetIntField(target, AwtComponent::heightID, (jint) rc.bottom);

            env->DeleteLocalRef(dimension);
	}
    } catch (...) {
        env->DeleteLocalRef(target);
	throw;
    }

done:
    env->DeleteLocalRef(target);

    return c;
}