1 /*
2 * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include "awt_Toolkit.h"
27 #include "awt_Scrollbar.h"
28 #include "awt_Canvas.h"
29 #include "awt_Window.h"
30
31 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
32 */
33
34 /***********************************************************************/
35 // struct for _SetValues() method
36 struct SetValuesStruct {
37 jobject scrollbar;
38 jint value;
39 jint visible;
40 jint min, max;
41 };
42 // struct for _SetLineIncrement()/_SetPageIncrement() methods
43 struct SetIncrementStruct {
44 jobject scrollbar;
45 jint increment;
46 };
47 /************************************************************************
48 * AwtScrollbar fields
49 */
50
51 jfieldID AwtScrollbar::lineIncrementID;
52 jfieldID AwtScrollbar::pageIncrementID;
53 jfieldID AwtScrollbar::orientationID;
54
55 BOOL AwtScrollbar::ms_isInsideMouseFilter = FALSE;
56 int AwtScrollbar::ms_instanceCounter = 0;
57 HHOOK AwtScrollbar::ms_hMouseFilter;
58
59 /************************************************************************
60 * AwtScrollbar methods
61 */
62
AwtScrollbar()63 AwtScrollbar::AwtScrollbar() {
64 m_orientation = SB_HORZ;
65 m_lineIncr = 0;
66 m_pageIncr = 0;
67 m_prevCallback = NULL;
68 m_prevCallbackPos = 0;
69 ms_instanceCounter++;
70
71 /*
72 * Fix for 4515085.
73 * Use the hook to process WM_LBUTTONUP message.
74 */
75 if (AwtScrollbar::ms_instanceCounter == 1) {
76 AwtScrollbar::ms_hMouseFilter =
77 ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC)AwtScrollbar::MouseFilter,
78 0, AwtToolkit::MainThread());
79 }
80 }
81
~AwtScrollbar()82 AwtScrollbar::~AwtScrollbar()
83 {
84 }
85
Dispose()86 void AwtScrollbar::Dispose()
87 {
88 if (--ms_instanceCounter == 0) {
89 ::UnhookWindowsHookEx(ms_hMouseFilter);
90 }
91 AwtComponent::Dispose();
92 }
93
94 LPCTSTR
GetClassName()95 AwtScrollbar::GetClassName() {
96 return TEXT("SCROLLBAR"); /* System provided scrollbar class */
97 }
98
99 /* Create a new AwtScrollbar object and window. */
100 AwtScrollbar *
Create(jobject peer,jobject parent)101 AwtScrollbar::Create(jobject peer, jobject parent)
102 {
103 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
104
105 jobject target = NULL;
106 AwtScrollbar* c = NULL;
107
108 try {
109 if (env->EnsureLocalCapacity(1) < 0) {
110 return NULL;
111 }
112
113 PDATA pData;
114 AwtCanvas* awtParent;
115
116 JNI_CHECK_PEER_GOTO(parent, done);
117 awtParent = (AwtCanvas*)pData;
118
119 target = env->GetObjectField(peer, AwtObject::targetID);
120 JNI_CHECK_NULL_GOTO(target, "null target", done);
121
122 c = new AwtScrollbar();
123
124 {
125 jint orientation =
126 env->GetIntField(target, AwtScrollbar::orientationID);
127 c->m_orientation = (orientation == java_awt_Scrollbar_VERTICAL) ?
128 SB_VERT : SB_HORZ;
129 c->m_lineIncr =
130 env->GetIntField(target, AwtScrollbar::lineIncrementID);
131 c->m_pageIncr =
132 env->GetIntField(target, AwtScrollbar::pageIncrementID);
133
134 DWORD style = WS_CHILD | WS_CLIPSIBLINGS |
135 c->m_orientation;/* Note: SB_ and SBS_ are the same here */
136
137 jint x = env->GetIntField(target, AwtComponent::xID);
138 jint y = env->GetIntField(target, AwtComponent::yID);
139 jint width = env->GetIntField(target, AwtComponent::widthID);
140 jint height = env->GetIntField(target, AwtComponent::heightID);
141
142 c->CreateHWnd(env, L"", style, 0,
143 x, y, width, height,
144 awtParent->GetHWnd(),
145 reinterpret_cast<HMENU>(static_cast<INT_PTR>(
146 awtParent->CreateControlID())),
147 ::GetSysColor(COLOR_SCROLLBAR),
148 ::GetSysColor(COLOR_SCROLLBAR),
149 peer);
150 c->m_backgroundColorSet = TRUE;
151 /* suppress inheriting parent's color. */
152 c->UpdateBackground(env, target);
153 }
154 } catch (...) {
155 env->DeleteLocalRef(target);
156 throw;
157 }
158
159 done:
160 env->DeleteLocalRef(target);
161 return c;
162 }
163
164 LRESULT CALLBACK
MouseFilter(int nCode,WPARAM wParam,LPARAM lParam)165 AwtScrollbar::MouseFilter(int nCode, WPARAM wParam, LPARAM lParam)
166 {
167 if (((UINT)wParam == WM_LBUTTONUP || (UINT)wParam == WM_MOUSEMOVE) &&
168 ms_isInsideMouseFilter != TRUE &&
169 nCode >= 0)
170 {
171 HWND hwnd = ((PMOUSEHOOKSTRUCT)lParam)->hwnd;
172 AwtComponent *comp = AwtComponent::GetComponent(hwnd);
173
174 if (comp != NULL && comp->IsScrollbar()) {
175 MSG msg;
176 LPMSG lpMsg = (LPMSG)&msg;
177 UINT msgID = (UINT)wParam;
178
179 ms_isInsideMouseFilter = TRUE;
180
181 // Peek the message to get wParam containing the message's flags.
182 // <::PeekMessage> will call this hook again. To prevent recursive
183 // processing the <ms_isInsideMouseFilter> flag is used.
184 // Calling <::PeekMessage> is not so good desision but is the only one
185 // found to get those flags (used further in Java event creation).
186 // WARNING! If you are about to add new hook of WM_MOUSE type make
187 // it ready for recursive call, otherwise modify this one.
188 if (::PeekMessage(lpMsg, hwnd, msgID, msgID, PM_NOREMOVE)) {
189 comp->WindowProc(msgID, lpMsg->wParam, lpMsg->lParam);
190 }
191
192 ms_isInsideMouseFilter = FALSE;
193 }
194 }
195 return ::CallNextHookEx(AwtScrollbar::ms_hMouseFilter, nCode, wParam, lParam);
196 }
197
198
199 LRESULT
WindowProc(UINT message,WPARAM wParam,LPARAM lParam)200 AwtScrollbar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
201 {
202 // Delegate real work to super
203 LRESULT retValue = AwtComponent::WindowProc(message, wParam, lParam);
204
205 // After-hooks for workarounds
206 switch (message) {
207
208 // Work around a windows bug described in KB article Q73839.
209 // Need to update focus indicator on scrollbar if thumb
210 // proportion or thumb position was changed.
211
212 case WM_SIZE:
213 case SBM_SETSCROLLINFO:
214 case SBM_SETRANGE:
215 case SBM_SETRANGEREDRAW:
216 if (AwtComponent::sm_focusOwner == GetHWnd()) {
217 UpdateFocusIndicator();
218 }
219 break;
220 }
221
222 return retValue;
223 }
224
225 MsgRouting
WmNcHitTest(UINT x,UINT y,LRESULT & retVal)226 AwtScrollbar::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
227 {
228 if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) {
229 retVal = HTCLIENT;
230 return mrConsume;
231 }
232 return AwtComponent::WmNcHitTest(x, y, retVal);
233 }
234
235 // Fix for a race condition when the WM_LBUTTONUP is picked by the AWT
236 // message loop before(!) the windows internal message loop for the
237 // scrollbar is started in response to WM_LBUTTONDOWN. See KB article
238 // Q102552.
239 //
240 // Note that WM_LBUTTONUP is processed by the windows internal message
241 // loop. May be we can synthesize a MOUSE_RELEASED event but that
242 // seems kludgey, so we'd better left this as is for now.
243
244 MsgRouting
WmMouseDown(UINT flags,int x,int y,int button)245 AwtScrollbar::WmMouseDown(UINT flags, int x, int y, int button)
246 {
247 // We pass the WM_LBUTTONDOWN up to Java, but we process it
248 // immediately as well to avoid the race. Later when this press
249 // event returns to us wrapped into a WM_AWT_HANDLE_EVENT we
250 // ignore it in the HandleEvent below. This means that we can not
251 // consume the mouse press in the Java world.
252
253 MsgRouting usualRoute = AwtComponent::WmMouseDown(flags, x, y, button);
254
255 if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) {
256 return mrConsume;
257 }
258
259 if (button == LEFT_BUTTON)
260 return mrDoDefault; // Force immediate processing to avoid the race.
261 else
262 return usualRoute;
263 }
264
265 MsgRouting
HandleEvent(MSG * msg,BOOL synthetic)266 AwtScrollbar::HandleEvent(MSG *msg, BOOL synthetic)
267 {
268 // SCROLLBAR control doesn't cause activation on mouse/key events,
269 // so we can safely (for synthetic focus) pass them to the system proc.
270
271 if (IsFocusingMouseMessage(msg)) {
272 // Left button press was already routed to default window
273 // procedure in the WmMouseDown above. Propagating synthetic
274 // press seems like a bad idea as internal message loop
275 // doesn't know how to unwrap synthetic release.
276 delete msg;
277 return mrConsume;
278 }
279 return AwtComponent::HandleEvent(msg, synthetic);
280 }
281
282 // Work around a windows bug descrbed in KB article Q73839. Reset
283 // focus on scrollbars to update focus indicator. The article advises
284 // to disable/enable the scrollbar.
285 void
UpdateFocusIndicator()286 AwtScrollbar::UpdateFocusIndicator()
287 {
288 if (IsFocusable()) {
289 // todo: doesn't work
290 SendMessage((WPARAM)ESB_DISABLE_BOTH);
291 SendMessage((WPARAM)ESB_ENABLE_BOTH);
292 }
293 }
294
295 // In a windows app one would call SetScrollInfo from WM_[HV]SCROLL
296 // handler directly. Since we call SetScrollInfo from Java world
297 // after scroll handler is over next WM_[HV]SCROLL event can be
298 // delivered before SetScrollInfo was called in response to the
299 // previous one and thus we would fire exactly the same event which
300 // will only contribute to the growth of the backlog of scroll events.
301
302 const char * const AwtScrollbar::SbNlineDown = "lineDown";
303 const char * const AwtScrollbar::SbNlineUp = "lineUp";
304 const char * const AwtScrollbar::SbNpageDown = "pageDown";
305 const char * const AwtScrollbar::SbNpageUp = "pageUp";
306 const char * const AwtScrollbar::SbNdrag = "drag";
307 const char * const AwtScrollbar::SbNdragEnd = "dragEnd";
308 const char * const AwtScrollbar::SbNwarp = "warp";
309
310 inline void
DoScrollCallbackCoalesce(const char * methodName,int newPos)311 AwtScrollbar::DoScrollCallbackCoalesce(const char* methodName, int newPos)
312 {
313 if (methodName == m_prevCallback && newPos == m_prevCallbackPos) {
314 DTRACE_PRINTLN2("AwtScrollbar: ignoring duplicate callback %s(%d)",
315 methodName, newPos);
316 }
317 else {
318 DoCallback(methodName, "(I)V", newPos);
319 m_prevCallback = methodName;
320 m_prevCallbackPos = newPos;
321 }
322 }
323
324
325 MsgRouting
WmVScroll(UINT scrollCode,UINT pos,HWND hScrollbar)326 AwtScrollbar::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollbar)
327 {
328 int minVal, maxVal; // scrollbar range
329 int minPos, maxPos; // thumb positions (max depends on visible amount)
330 int curPos, newPos;
331
332 // For drags we have old (static) and new (dynamic) thumb positions
333 int dragP = (scrollCode == SB_THUMBTRACK
334 || scrollCode == SB_THUMBPOSITION);
335 int thumbPos;
336
337 SCROLLINFO si;
338 si.cbSize = sizeof si;
339 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
340
341 // From, _Win32 Programming_, by Rector and Newcommer, p. 185:
342 // "In some of the older documentation on Win32 scroll bars,
343 // including that published by Microsoft, you may read that
344 // you *cannot* obtain the scroll position while in a handler.
345 // The SIF_TRACKPOS flag was added after this documentation
346 // was published. Beware of this older documentation; it may
347 // have other obsolete features."
348 if (dragP) {
349 si.fMask |= SIF_TRACKPOS;
350 }
351
352 VERIFY(::GetScrollInfo(GetHWnd(), SB_CTL, &si));
353 curPos = si.nPos;
354 minPos = minVal = si.nMin;
355
356 // Upper bound of the range. Note that adding 1 here is safe
357 // and won't cause a wrap, since we have substracted 1 in the
358 // SetValues above.
359 maxVal = si.nMax + 1;
360
361 // Meaningful maximum position is maximum - visible.
362 maxPos = maxVal - si.nPage;
363
364 // XXX: Documentation for SBM_SETRANGE says that scrollbar
365 // range is limited by MAXLONG, which is 2**31, but when a
366 // scroll range is greater than that, thumbPos is reported
367 // incorrectly due to integer arithmetic wrap(s).
368 thumbPos = dragP ? si.nTrackPos : curPos;
369
370 // NB: Beware arithmetic wrap when calculating newPos
371 switch (scrollCode) {
372
373 case SB_LINEUP:
374 if ((__int64)curPos - m_lineIncr > minPos)
375 newPos = curPos - m_lineIncr;
376 else
377 newPos = minPos;
378 if (newPos != curPos)
379 DoScrollCallbackCoalesce(SbNlineUp, newPos);
380 break;
381
382 case SB_LINEDOWN:
383 if ((__int64)curPos + m_lineIncr < maxPos)
384 newPos = curPos + m_lineIncr;
385 else
386 newPos = maxPos;
387 if (newPos != curPos)
388 DoScrollCallbackCoalesce(SbNlineDown, newPos);
389 break;
390
391 case SB_PAGEUP:
392 if ((__int64)curPos - m_pageIncr > minPos)
393 newPos = curPos - m_pageIncr;
394 else
395 newPos = minPos;
396 if (newPos != curPos)
397 DoScrollCallbackCoalesce(SbNpageUp, newPos);
398 break;
399
400 case SB_PAGEDOWN:
401 if ((__int64)curPos + m_pageIncr < maxPos)
402 newPos = curPos + m_pageIncr;
403 else
404 newPos = maxPos;
405 if (newPos != curPos)
406 DoScrollCallbackCoalesce(SbNpageDown, newPos);
407 break;
408
409 case SB_TOP:
410 if (minPos != curPos)
411 DoScrollCallbackCoalesce(SbNwarp, minPos);
412 break;
413
414 case SB_BOTTOM:
415 if (maxPos != curPos)
416 DoScrollCallbackCoalesce(SbNwarp, maxPos);
417 break;
418
419 case SB_THUMBTRACK:
420 if (thumbPos != curPos)
421 DoScrollCallbackCoalesce(SbNdrag, thumbPos);
422 break;
423
424 case SB_THUMBPOSITION:
425 DoScrollCallbackCoalesce(SbNdragEnd, thumbPos);
426 break;
427
428 case SB_ENDSCROLL:
429 // reset book-keeping info
430 m_prevCallback = NULL;
431 break;
432 }
433 return mrDoDefault;
434 }
435
436 MsgRouting
WmHScroll(UINT scrollCode,UINT pos,HWND hScrollbar)437 AwtScrollbar::WmHScroll(UINT scrollCode, UINT pos, HWND hScrollbar)
438 {
439 return WmVScroll(scrollCode, pos, hScrollbar);
440 }
441
_SetValues(void * param)442 void AwtScrollbar::_SetValues(void *param)
443 {
444 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
445
446 SetValuesStruct *svs = (SetValuesStruct *)param;
447 jobject self = svs->scrollbar;
448
449 SCROLLINFO si;
450 si.cbSize = sizeof si;
451 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
452 si.nMin = svs->min;
453 si.nMax = svs->max - 1;
454 si.nPage = svs->visible;
455 si.nPos = svs->value;
456
457 AwtScrollbar *sb = NULL;
458
459 PDATA pData;
460 JNI_CHECK_PEER_GOTO(self, ret);
461 sb = (AwtScrollbar *)pData;
462 if (::IsWindow(sb->GetHWnd()))
463 {
464 BOOL update_p = ::IsWindowEnabled(sb->GetHWnd()); // don't redraw if disabled
465 DTRACE_PRINTLN5("AwtScrollbar::SetValues(val = %d, vis = %d,"//(ctd.)
466 " min = %d, max = %d)%s",
467 svs->value, svs->visible, svs->min, svs->max,
468 update_p ? "" : " - NOT redrawing");
469 ::SetScrollInfo(sb->GetHWnd(), SB_CTL, &si, update_p);
470 }
471 ret:
472 env->DeleteGlobalRef(self);
473
474 delete svs;
475 }
476
_SetLineIncrement(void * param)477 void AwtScrollbar::_SetLineIncrement(void *param)
478 {
479 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
480
481 SetIncrementStruct *sis = (SetIncrementStruct *)param;
482 jobject self = sis->scrollbar;
483 jint increment = sis->increment;
484
485 AwtScrollbar *sb = NULL;
486
487 PDATA pData;
488 JNI_CHECK_PEER_GOTO(self, ret);
489 sb = (AwtScrollbar *)pData;
490 if (::IsWindow(sb->GetHWnd()))
491 {
492 sb->SetLineIncrement(increment);
493 }
494 ret:
495 env->DeleteGlobalRef(self);
496
497 delete sis;
498 }
499
_SetPageIncrement(void * param)500 void AwtScrollbar::_SetPageIncrement(void *param)
501 {
502 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
503
504 SetIncrementStruct *sis = (SetIncrementStruct *)param;
505 jobject self = sis->scrollbar;
506 jint increment = sis->increment;
507
508 AwtScrollbar *sb = NULL;
509
510 PDATA pData;
511 JNI_CHECK_PEER_GOTO(self, ret);
512 sb = (AwtScrollbar *)pData;
513 if (::IsWindow(sb->GetHWnd()))
514 {
515 sb->SetPageIncrement(increment);
516 }
517 ret:
518 env->DeleteGlobalRef(self);
519
520 delete sis;
521 }
522
523 /************************************************************************
524 * Scrollbar native methods
525 */
526
527 extern "C" {
528
529 /*
530 * Class: java_awt_Scrollbar
531 * Method: initIDs
532 * Signature: ()V
533 */
534 JNIEXPORT void JNICALL
Java_java_awt_Scrollbar_initIDs(JNIEnv * env,jclass cls)535 Java_java_awt_Scrollbar_initIDs(JNIEnv *env, jclass cls)
536 {
537 TRY;
538
539 AwtScrollbar::lineIncrementID = env->GetFieldID(cls, "lineIncrement", "I");
540 DASSERT(AwtScrollbar::lineIncrementID != NULL);
541 CHECK_NULL(AwtScrollbar::lineIncrementID);
542
543 AwtScrollbar::pageIncrementID = env->GetFieldID(cls, "pageIncrement", "I");
544 DASSERT(AwtScrollbar::pageIncrementID != NULL);
545 CHECK_NULL(AwtScrollbar::pageIncrementID);
546
547 AwtScrollbar::orientationID = env->GetFieldID(cls, "orientation", "I");
548 DASSERT(AwtScrollbar::orientationID != NULL);
549
550 CATCH_BAD_ALLOC;
551 }
552
553 } /* extern "C" */
554
555
556 /************************************************************************
557 * WScrollbarPeer native methods
558 */
559
560 extern "C" {
561
562 /*
563 * Class: sun_awt_windows_WScrollbarPeer
564 * Method: setValues
565 * Signature: (IIII)V
566 */
567 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_setValues(JNIEnv * env,jobject self,jint value,jint visible,jint minimum,jint maximum)568 Java_sun_awt_windows_WScrollbarPeer_setValues(JNIEnv *env, jobject self,
569 jint value, jint visible,
570 jint minimum, jint maximum)
571 {
572 TRY;
573
574 SetValuesStruct *svs = new SetValuesStruct;
575 svs->scrollbar = env->NewGlobalRef(self);
576 svs->value = value;
577 svs->visible = visible;
578 svs->min = minimum;
579 svs->max = maximum;
580
581 AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetValues, svs);
582 // global ref and svs are deleted in _SetValues
583
584 CATCH_BAD_ALLOC;
585 }
586
587 /*
588 * Class: sun_awt_windows_WScrollbarPeer
589 * Method: setLineIncrement
590 * Signature: (I)V
591 */
592 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_setLineIncrement(JNIEnv * env,jobject self,jint increment)593 Java_sun_awt_windows_WScrollbarPeer_setLineIncrement(JNIEnv *env, jobject self,
594 jint increment)
595 {
596 TRY;
597
598 SetIncrementStruct *sis = new SetIncrementStruct;
599 sis->scrollbar = env->NewGlobalRef(self);
600 sis->increment = increment;
601
602 AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetLineIncrement, sis);
603 // global ref and svs are deleted in _SetValues
604
605 CATCH_BAD_ALLOC;
606 }
607
608 /*
609 * Class: sun_awt_windows_WScrollbarPeer
610 * Method: setPageIncrement
611 * Signature: (I)V
612 */
613 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_setPageIncrement(JNIEnv * env,jobject self,jint increment)614 Java_sun_awt_windows_WScrollbarPeer_setPageIncrement(JNIEnv *env, jobject self,
615 jint increment)
616 {
617 TRY;
618
619 SetIncrementStruct *sis = new SetIncrementStruct;
620 sis->scrollbar = env->NewGlobalRef(self);
621 sis->increment = increment;
622
623 AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetPageIncrement, sis);
624 // global ref and svs are deleted in _SetValues
625
626 CATCH_BAD_ALLOC;
627 }
628
629 /*
630 * Class: sun_awt_windows_WScrollbarPeer
631 * Method: create
632 * Signature: (Lsun/awt/windows/WComponentPeer;)V
633 */
634 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollbarPeer_create(JNIEnv * env,jobject self,jobject parent)635 Java_sun_awt_windows_WScrollbarPeer_create(JNIEnv *env, jobject self,
636 jobject parent)
637 {
638 TRY;
639
640 AwtToolkit::CreateComponent(self, parent,
641 (AwtToolkit::ComponentFactory)
642 AwtScrollbar::Create);
643
644 CATCH_BAD_ALLOC;
645 }
646
647 /*
648 * Class: sun_awt_windows_WScrollbarPeer
649 * Method: getScrollbarSize
650 * Signature: (I)I
651 */
652 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WScrollbarPeer_getScrollbarSize(JNIEnv * env,jclass clazz,jint orientation)653 Java_sun_awt_windows_WScrollbarPeer_getScrollbarSize(JNIEnv *env, jclass clazz, jint orientation)
654 {
655 if (orientation == java_awt_Scrollbar_VERTICAL) {
656 return ::GetSystemMetrics(SM_CXVSCROLL);
657 } else {
658 return ::GetSystemMetrics(SM_CYHSCROLL);
659 }
660 }
661
662 } /* extern "C" */
663