void AwtScrollPane::_SetSpans(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetSpansStruct *sss = (SetSpansStruct *)param;
    jobject self = sss->scrollpane;
    jint parentWidth = sss->parentWidth;
    jint parentHeight = sss->parentHeight;
    jint childWidth = sss->childWidth;
    jint childHeight = sss->childHeight;

    AwtScrollPane *s = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    s = (AwtScrollPane *)pData;
    if (::IsWindow(s->GetHWnd()))
    {
        DTRACE_PRINTLN5("%x: WScrollPanePeer.setSpans(%d, %d, %d, %d)", self,
            parentWidth, parentHeight, childWidth, childHeight);
        s->RecalcSizes(parentWidth, parentHeight, childWidth, childHeight);
        s->VerifyState();
    }
ret:
   env->DeleteGlobalRef(self);

   delete sss;
}
jint AwtScrollPane::_GetOffset(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    GetOffsetStruct *gos = (GetOffsetStruct *)param;
    jobject self = gos->scrollpane;
    jint orient = gos->orient;

    jint result = 0;
    AwtScrollPane *s = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    s = (AwtScrollPane *)pData;
    if (::IsWindow(s->GetHWnd()))
    {
        DTRACE_PRINTLN2("%x: WScrollPanePeer.getOffset(%d)", self, orient);
        s->VerifyState();
        int nBar = (orient == java_awt_Adjustable_HORIZONTAL) ? SB_HORZ : SB_VERT;
        result = s->GetScrollPos(nBar);
    }
ret:
   env->DeleteGlobalRef(self);

   delete gos;

   return result;
}
void AwtScrollPane::_SetScrollPos(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetScrollPosStruct *spss = (SetScrollPosStruct *)param;
    jobject self = spss->scrollpane;
    jint x = spss->x;
    jint y = spss->y;

    AwtScrollPane *s = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    s = (AwtScrollPane *)pData;
    if (::IsWindow(s->GetHWnd()))
    {
        DTRACE_PRINTLN3("%x: WScrollPanePeer.setScrollPosition(%d, %d)", self, x, y);
        SCROLLINFO si;
        ZeroMemory(&si, sizeof(si));
        si.fMask = SIF_POS;
        si.cbSize = sizeof(si);
        // set x
        si.nPos = x;
        ::SetScrollInfo(s->GetHWnd(), SB_HORZ, &si, TRUE);
        // set y
        si.nPos = y;
        ::SetScrollInfo(s->GetHWnd(), SB_VERT, &si, TRUE);
    }
ret:
   env->DeleteGlobalRef(self);

   delete spss;
}
/*
 * Class:     sun_awt_windows_WScrollPanePeer
 * Method:    setInsets
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_setInsets(JNIEnv *env, jobject self)
{
    TRY

    DTRACE_PRINTLN1("%x: WScrollPanePeer.setInsets()", self);

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtScrollPane* pane = (AwtScrollPane *)pData;
    pane->SetInsets(env);
    pane->VerifyState();

    CATCH_BAD_ALLOC;
}
/*
 * Class:     sun_awt_windows_WScrollPanePeer
 * Method:    setScrollPosition
 * Signature: (II)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_setScrollPosition(JNIEnv *env, 
						       jobject self,
						       jint x, jint y)
{
    TRY;

    DTRACE_PRINTLN3("%x: WScrollPanePeer.setScrollPosition(%d, %d)", self, x, y);

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtScrollPane* pane = (AwtScrollPane *)pData;
    pane->SetScrollPos(SB_HORZ, x);
    pane->SetScrollPos(SB_VERT, y);
    CATCH_BAD_ALLOC;
}
/*
 * Class:     sun_awt_windows_WScrollPanePeer
 * Method:    getOffset
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL 
Java_sun_awt_windows_WScrollPanePeer_getOffset(JNIEnv *env, jobject self,
					       jint orient)
{
    TRY;

    DTRACE_PRINTLN2("%x: WScrollPanePeer.getOffset(%d)", self, orient);

    PDATA pData;
    JNI_CHECK_PEER_RETURN_NULL(self);
    AwtScrollPane* pane = (AwtScrollPane *)pData;
    pane->VerifyState();
    int nBar = (orient == java_awt_Adjustable_HORIZONTAL) ? SB_HORZ : SB_VERT;
    return pane->GetScrollPos(nBar);

    CATCH_BAD_ALLOC_RET(0);
}
/*
 * Class:     sun_awt_windows_WScrollPanePeer
 * Method:    setSpans
 * Signature: (IIII)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_setSpans(JNIEnv *env, jobject self,
					      jint parentWidth,
					      jint parentHeight, 
					      jint childWidth,
					      jint childHeight)
{
    TRY;

    DTRACE_PRINTLN5("%x: WScrollPanePeer.setSpans(%d, %d, %d, %d)", self, 
               parentWidth, parentHeight, childWidth, childHeight);
    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);
    AwtScrollPane* pane = (AwtScrollPane *)pData;
    pane->RecalcSizes(parentWidth, parentHeight, childWidth, childHeight);
    pane->VerifyState();

    CATCH_BAD_ALLOC;
}
void AwtScrollPane::_SetInsets(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    AwtScrollPane *s = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    s = (AwtScrollPane *)pData;
    if (::IsWindow(s->GetHWnd()))
    {
        DTRACE_PRINTLN1("%x: WScrollPanePeer.setInsets()", self);
        s->SetInsets(env);
        s->VerifyState();
    }
ret:
   env->DeleteGlobalRef(self);
}
/* Create a new AwtScrollPane object and window.   */
AwtScrollPane* AwtScrollPane::Create(jobject self, jobject parent)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    jobject target = NULL;
    AwtScrollPane* c = NULL;

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

        PDATA pData;
        AwtComponent* awtParent;
        JNI_CHECK_PEER_GOTO(parent, done);

        awtParent = (AwtComponent*)pData;
        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);

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

        c = new AwtScrollPane();

        {
            DWORD style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
            jint scrollbarDisplayPolicy =
                env->GetIntField(target, scrollbarDisplayPolicyID);

            if (scrollbarDisplayPolicy
                    == java_awt_ScrollPane_SCROLLBARS_ALWAYS) {
                style |= WS_HSCROLL | WS_VSCROLL;
            }
            DWORD exStyle = WS_EX_CLIENTEDGE;

            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(),
                          reinterpret_cast<HMENU>(static_cast<INT_PTR>(
                awtParent->CreateControlID())),
                          ::GetSysColor(COLOR_WINDOWTEXT),
                          ::GetSysColor(COLOR_WINDOW),
                          self);
        }
    } catch (...) {
        env->DeleteLocalRef(target);
        throw;
    }

done:
    env->DeleteLocalRef(target);
    return c;
}