1 11 package org.eclipse.swt.widgets; 12 13 14 import org.eclipse.swt.*; 15 import org.eclipse.swt.internal.win32.*; 16 import org.eclipse.swt.graphics.*; 17 import org.eclipse.swt.events.*; 18 19 39 public class Spinner extends Composite { 40 int hwndText, hwndUpDown; 41 boolean ignoreModify; 42 int pageIncrement, digits; 43 static final int EditProc; 44 static final TCHAR EditClass = new TCHAR (0, "EDIT", true); 45 static final int UpDownProc; 46 static final TCHAR UpDownClass = new TCHAR (0, OS.UPDOWN_CLASS, true); 47 static { 48 WNDCLASS lpWndClass = new WNDCLASS (); 49 OS.GetClassInfo (0, EditClass, lpWndClass); 50 EditProc = lpWndClass.lpfnWndProc; 51 OS.GetClassInfo (0, UpDownClass, lpWndClass); 52 UpDownProc = lpWndClass.lpfnWndProc; 53 } 54 55 84 public Spinner (Composite parent, int style) { 85 super (parent, checkStyle (style)); 86 } 87 88 int callWindowProc (int hwnd, int msg, int wParam, int lParam) { 89 if (handle == 0) return 0; 90 if (hwnd == hwndText) { 91 return OS.CallWindowProc (EditProc, hwnd, msg, wParam, lParam); 92 } 93 if (hwnd == hwndUpDown) { 94 return OS.CallWindowProc (UpDownProc, hwnd, msg, wParam, lParam); 95 } 96 return OS.DefWindowProc (handle, msg, wParam, lParam); 97 } 98 99 static int checkStyle (int style) { 100 107 return style & ~(SWT.H_SCROLL | SWT.V_SCROLL); 108 } 109 110 boolean checkHandle (int hwnd) { 111 return hwnd == handle || hwnd == hwndText || hwnd == hwndUpDown; 112 } 113 114 protected void checkSubclass () { 115 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); 116 } 117 118 void createHandle () { 119 super.createHandle (); 120 state &= ~(CANVAS | THEME_BACKGROUND); 121 int hInstance = OS.GetModuleHandle (null); 122 int textExStyle = (style & SWT.BORDER) != 0 ? OS.WS_EX_CLIENTEDGE : 0; 123 int textStyle = OS.WS_CHILD | OS.WS_VISIBLE | OS.ES_AUTOHSCROLL | OS.WS_CLIPSIBLINGS; 124 if ((style & SWT.READ_ONLY) != 0) textStyle |= OS.ES_READONLY; 125 if (OS.WIN32_VERSION >= OS.VERSION (4, 10)) { 126 if ((style & SWT.RIGHT_TO_LEFT) != 0) textExStyle |= OS.WS_EX_LAYOUTRTL; 127 } 128 hwndText = OS.CreateWindowEx ( 129 textExStyle, 130 EditClass, 131 null, 132 textStyle, 133 0, 0, 0, 0, 134 handle, 135 0, 136 hInstance, 137 null); 138 if (hwndText == 0) error (SWT.ERROR_NO_HANDLES); 139 OS.SetWindowLong (hwndText, OS.GWL_ID, hwndText); 140 int upDownStyle = OS.WS_CHILD | OS.WS_VISIBLE | OS.UDS_AUTOBUDDY; 141 if ((style & SWT.WRAP) != 0) upDownStyle |= OS.UDS_WRAP; 142 if ((style & SWT.BORDER) != 0) { 143 if ((style & SWT.RIGHT_TO_LEFT) != 0) { 144 upDownStyle |= OS.UDS_ALIGNLEFT; 145 } else { 146 upDownStyle |= OS.UDS_ALIGNRIGHT; 147 } 148 } 149 hwndUpDown = OS.CreateWindowEx ( 150 0, 151 UpDownClass, 152 null, 153 upDownStyle, 154 0, 0, 0, 0, 155 handle, 156 0, 157 hInstance, 158 null); 159 if (hwndUpDown == 0) error (SWT.ERROR_NO_HANDLES); 160 int flags = OS.SWP_NOSIZE | OS.SWP_NOMOVE | OS.SWP_NOACTIVATE; 161 SetWindowPos (hwndText, hwndUpDown, 0, 0, 0, 0, flags); 162 OS.SetWindowLong (hwndUpDown, OS.GWL_ID, hwndUpDown); 163 if (OS.IsDBLocale) { 164 int hIMC = OS.ImmGetContext (handle); 165 OS.ImmAssociateContext (hwndText, hIMC); 166 OS.ImmAssociateContext (hwndUpDown, hIMC); 167 OS.ImmReleaseContext (handle, hIMC); 168 } 169 OS.SendMessage (hwndUpDown, OS.UDM_SETRANGE32, 0, 100); 170 OS.SendMessage (hwndUpDown, OS.IsWinCE ? OS.UDM_SETPOS : OS.UDM_SETPOS32, 0, 0); 171 pageIncrement = 10; 172 digits = 0; 173 TCHAR buffer = new TCHAR (getCodePage (), "0", true); 174 OS.SetWindowText (hwndText, buffer); 175 } 176 177 196 public void addModifyListener (ModifyListener listener) { 197 checkWidget (); 198 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 199 TypedListener typedListener = new TypedListener (listener); 200 addListener (SWT.Modify, typedListener); 201 } 202 203 227 public void addSelectionListener(SelectionListener listener) { 228 checkWidget (); 229 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 230 TypedListener typedListener = new TypedListener (listener); 231 addListener (SWT.Selection,typedListener); 232 addListener (SWT.DefaultSelection,typedListener); 233 } 234 235 254 void addVerifyListener (VerifyListener listener) { 255 checkWidget(); 256 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 257 TypedListener typedListener = new TypedListener (listener); 258 addListener (SWT.Verify, typedListener); 259 } 260 261 int borderHandle () { 262 return hwndText; 263 } 264 265 public Point computeSize (int wHint, int hHint, boolean changed) { 266 checkWidget (); 267 int width = 0, height = 0; 268 if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) { 269 int newFont, oldFont = 0; 270 int hDC = OS.GetDC (hwndText); 271 newFont = OS.SendMessage (hwndText, OS.WM_GETFONT, 0, 0); 272 if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont); 273 TEXTMETRIC tm = OS.IsUnicode ? (TEXTMETRIC) new TEXTMETRICW () : new TEXTMETRICA (); 274 OS.GetTextMetrics (hDC, tm); 275 height = tm.tmHeight; 276 RECT rect = new RECT (); 277 int [] max = new int [1]; 278 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, null, max); 279 String string = String.valueOf (max [0]); 280 if (digits > 0) { 281 StringBuffer buffer = new StringBuffer (); 282 buffer.append (string); 283 buffer.append (getDecimalSeparator ()); 284 int count = digits - string.length (); 285 while (count >= 0) { 286 buffer.append ("0"); 287 count--; 288 } 289 string = buffer.toString (); 290 } 291 TCHAR buffer = new TCHAR (getCodePage (), string, false); 292 int flags = OS.DT_CALCRECT | OS.DT_EDITCONTROL | OS.DT_NOPREFIX; 293 OS.DrawText (hDC, buffer, buffer.length (), rect, flags); 294 width = rect.right - rect.left; 295 if (newFont != 0) OS.SelectObject (hDC, oldFont); 296 OS.ReleaseDC (hwndText, hDC); 297 } 298 if (width == 0) width = DEFAULT_WIDTH; 299 if (height == 0) height = DEFAULT_HEIGHT; 300 if (wHint != SWT.DEFAULT) width = wHint; 301 if (hHint != SWT.DEFAULT) height = hHint; 302 Rectangle trim = computeTrim (0, 0, width, height); 303 if (hHint == SWT.DEFAULT) { 304 int upDownHeight = OS.GetSystemMetrics (OS.SM_CYVSCROLL) + 2 * getBorderWidth (); 305 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { 306 upDownHeight += (style & SWT.BORDER) != 0 ? 1 : 3; 307 } 308 trim.height = Math.max (trim.height, upDownHeight); 309 } 310 return new Point (trim.width, trim.height); 311 } 312 313 public Rectangle computeTrim (int x, int y, int width, int height) { 314 checkWidget (); 315 316 317 RECT rect = new RECT (); 318 OS.SetRect (rect, x, y, x + width, y + height); 319 int bits0 = OS.GetWindowLong (hwndText, OS.GWL_STYLE); 320 int bits1 = OS.GetWindowLong (hwndText, OS.GWL_EXSTYLE); 321 OS.AdjustWindowRectEx (rect, bits0, false, bits1); 322 width = rect.right - rect.left; 323 height = rect.bottom - rect.top; 324 325 331 int margins = OS.SendMessage (hwndText, OS.EM_GETMARGINS, 0, 0); 332 x -= margins & 0xFFFF; 333 width += (margins & 0xFFFF) + ((margins >> 16) & 0xFFFF); 334 if ((style & SWT.BORDER) != 0) { 335 x -= 1; 336 y -= 1; 337 width += 2; 338 height += 2; 339 } 340 width += OS.GetSystemMetrics (OS.SM_CXVSCROLL); 341 return new Rectangle (x, y, width, height); 342 } 343 344 355 public void copy () { 356 checkWidget (); 357 OS.SendMessage (hwndText, OS.WM_COPY, 0, 0); 358 } 359 360 372 public void cut () { 373 checkWidget (); 374 if ((style & SWT.READ_ONLY) != 0) return; 375 OS.SendMessage (hwndText, OS.WM_CUT, 0, 0); 376 } 377 378 int defaultBackground () { 379 return OS.GetSysColor (OS.COLOR_WINDOW); 380 } 381 382 void enableWidget (boolean enabled) { 383 super.enableWidget (enabled); 384 OS.EnableWindow (hwndText, enabled); 385 OS.EnableWindow (hwndUpDown, enabled); 386 } 387 388 void deregister () { 389 super.deregister (); 390 display.removeControl (hwndText); 391 display.removeControl (hwndUpDown); 392 } 393 394 boolean hasFocus () { 395 int hwndFocus = OS.GetFocus (); 396 if (hwndFocus == handle) return true; 397 if (hwndFocus == hwndText) return true; 398 if (hwndFocus == hwndUpDown) return true; 399 return false; 400 } 401 402 412 public int getDigits () { 413 checkWidget (); 414 return digits; 415 } 416 417 String getDecimalSeparator () { 418 TCHAR tchar = new TCHAR (getCodePage (), 4); 419 int size = OS.GetLocaleInfo (OS.LOCALE_USER_DEFAULT, OS.LOCALE_SDECIMAL, tchar, 4); 420 return size != 0 ? tchar.toString (0, size - 1) : "."; 421 } 422 423 434 public int getIncrement () { 435 checkWidget (); 436 UDACCEL udaccel = new UDACCEL (); 437 OS.SendMessage (hwndUpDown, OS.UDM_GETACCEL, 1, udaccel); 438 return udaccel.nInc; 439 } 440 441 451 public int getMaximum () { 452 checkWidget (); 453 int [] max = new int [1]; 454 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, null, max); 455 return max [0]; 456 } 457 458 468 public int getMinimum () { 469 checkWidget (); 470 int [] min = new int [1]; 471 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, min, null); 472 return min [0]; 473 } 474 475 486 public int getPageIncrement () { 487 checkWidget (); 488 return pageIncrement; 489 } 490 491 501 public int getSelection () { 502 checkWidget (); 503 if (OS.IsWinCE) { 504 return OS.SendMessage (hwndUpDown, OS.UDM_GETPOS, 0, 0) & 0xFFFF; 505 } else { 506 return OS.SendMessage (hwndUpDown, OS.UDM_GETPOS32, 0, 0); 507 } 508 } 509 510 int getSelectionText () { 511 int length = OS.GetWindowTextLength (hwndText); 512 TCHAR buffer = new TCHAR (getCodePage (), length + 1); 513 OS.GetWindowText (hwndText, buffer, length + 1); 514 String string = buffer.toString (0, length); 515 try { 516 int value; 517 if (digits > 0) { 518 String decimalSeparator = getDecimalSeparator (); 519 int index = string.indexOf (decimalSeparator); 520 if (index != -1) { 521 String wholePart = string.substring (0, index); 522 String decimalPart = string.substring (index + 1); 523 if (decimalPart.length () > digits) { 524 decimalPart = decimalPart.substring (0, digits); 525 } else { 526 int i = digits - decimalPart.length (); 527 for (int j = 0; j < i; j++) { 528 decimalPart = decimalPart + "0"; 529 } 530 } 531 int wholeValue = Integer.parseInt (wholePart); 532 int decimalValue = Integer.parseInt (decimalPart); 533 for (int i = 0; i < digits; i++) wholeValue *= 10; 534 value = wholeValue + decimalValue; 535 } else { 536 value = Integer.parseInt (string); 537 } 538 } else { 539 value = Integer.parseInt (string); 540 } 541 int [] max = new int [1], min = new int [1]; 542 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, min, max); 543 if (min [0] <= value && value <= max [0]) return value; 544 } catch (NumberFormatException e) { 545 } 546 return -1; 547 } 548 549 int mbcsToWcsPos (int mbcsPos) { 550 if (mbcsPos <= 0) return 0; 551 if (OS.IsUnicode) return mbcsPos; 552 int mbcsSize = OS.GetWindowTextLengthA (hwndText); 553 if (mbcsSize == 0) return 0; 554 if (mbcsPos >= mbcsSize) return mbcsSize; 555 byte [] buffer = new byte [mbcsSize + 1]; 556 OS.GetWindowTextA (hwndText, buffer, mbcsSize + 1); 557 return OS.MultiByteToWideChar (getCodePage (), OS.MB_PRECOMPOSED, buffer, mbcsPos, null, 0); 558 } 559 560 572 public void paste () { 573 checkWidget (); 574 if ((style & SWT.READ_ONLY) != 0) return; 575 OS.SendMessage (hwndText, OS.WM_PASTE, 0, 0); 576 } 577 578 void register () { 579 super.register (); 580 display.addControl (hwndText, this); 581 display.addControl (hwndUpDown, this); 582 } 583 584 void releaseHandle () { 585 super.releaseHandle (); 586 hwndText = hwndUpDown = 0; 587 } 588 589 606 public void removeModifyListener (ModifyListener listener) { 607 checkWidget (); 608 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 609 if (eventTable == null) return; 610 eventTable.unhook (SWT.Modify, listener); 611 } 612 613 630 public void removeSelectionListener(SelectionListener listener) { 631 checkWidget (); 632 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 633 if (eventTable == null) return; 634 eventTable.unhook (SWT.Selection, listener); 635 eventTable.unhook (SWT.DefaultSelection,listener); 636 } 637 638 655 void removeVerifyListener (VerifyListener listener) { 656 checkWidget (); 657 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 658 if (eventTable == null) return; 659 eventTable.unhook (SWT.Verify, listener); 660 } 661 662 boolean sendKeyEvent (int type, int msg, int wParam, int lParam, Event event) { 663 if (!super.sendKeyEvent (type, msg, wParam, lParam, event)) { 664 return false; 665 } 666 if ((style & SWT.READ_ONLY) != 0) return true; 667 if (type != SWT.KeyDown) return true; 668 if (msg != OS.WM_CHAR && msg != OS.WM_KEYDOWN && msg != OS.WM_IME_CHAR) { 669 return true; 670 } 671 if (event.character == 0) return true; 672 char key = event.character; 674 int stateMask = event.stateMask; 675 676 681 switch (msg) { 682 case OS.WM_CHAR: 683 if (key != 0x08 && key != 0x7F && key != '\r' && key != '\t' && key != '\n') break; 684 case OS.WM_KEYDOWN: 686 if ((stateMask & (SWT.ALT | SWT.SHIFT | SWT.CONTROL)) != 0) return false; 687 break; 688 } 689 690 693 if (OS.GetKeyState (OS.VK_LBUTTON) < 0) { 694 return true; 695 } 696 697 698 String oldText = ""; 699 int [] start = new int [1], end = new int [1]; 700 OS.SendMessage (hwndText, OS.EM_GETSEL, start, end); 701 switch (key) { 702 case 0x08: 703 if (start [0] == end [0]) { 704 if (start [0] == 0) return true; 705 start [0] = start [0] - 1; 706 if (!OS.IsUnicode && OS.IsDBLocale) { 707 int [] newStart = new int [1], newEnd = new int [1]; 708 OS.SendMessage (hwndText, OS.EM_SETSEL, start [0], end [0]); 709 OS.SendMessage (hwndText, OS.EM_GETSEL, newStart, newEnd); 710 if (start [0] != newStart [0]) start [0] = start [0] - 1; 711 } 712 start [0] = Math.max (start [0], 0); 713 } 714 break; 715 case 0x7F: 716 if (start [0] == end [0]) { 717 int length = OS.GetWindowTextLength (hwndText); 718 if (start [0] == length) return true; 719 end [0] = end [0] + 1; 720 if (!OS.IsUnicode && OS.IsDBLocale) { 721 int [] newStart = new int [1], newEnd = new int [1]; 722 OS.SendMessage (hwndText, OS.EM_SETSEL, start [0], end [0]); 723 OS.SendMessage (hwndText, OS.EM_GETSEL, newStart, newEnd); 724 if (end [0] != newEnd [0]) end [0] = end [0] + 1; 725 } 726 end [0] = Math.min (end [0], length); 727 } 728 break; 729 case '\r': 730 return true; 731 default: 732 if (key != '\t' && key < 0x20) return true; 733 oldText = new String (new char [] {key}); 734 break; 735 } 736 String newText = verifyText (oldText, start [0], end [0], event); 737 if (newText == null) return false; 738 if (newText == oldText) return true; 739 TCHAR buffer = new TCHAR (getCodePage (), newText, true); 740 OS.SendMessage (hwndText, OS.EM_SETSEL, start [0], end [0]); 741 OS.SendMessage (hwndText, OS.EM_REPLACESEL, 0, buffer); 742 return false; 743 } 744 745 void setBackgroundImage (int hBitmap) { 746 super.setBackgroundImage (hBitmap); 747 OS.InvalidateRect (hwndText, null, true); 748 } 749 750 void setBackgroundPixel (int pixel) { 751 super.setBackgroundPixel (pixel); 752 OS.InvalidateRect (hwndText, null, true); 753 } 754 755 775 public void setDigits (int value) { 776 checkWidget (); 777 if (value < 0) error (SWT.ERROR_INVALID_ARGUMENT); 778 if (value == this.digits) return; 779 this.digits = value; 780 int pos; 781 if (OS.IsWinCE) { 782 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS, 0, 0) & 0xFFFF; 783 } else { 784 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS32, 0, 0); 785 } 786 setSelection (pos, false, true, false); 787 } 788 789 void setForegroundPixel (int pixel) { 790 super.setForegroundPixel (pixel); 791 OS.InvalidateRect (hwndText, null, true); 792 } 793 794 806 public void setIncrement (int value) { 807 checkWidget (); 808 if (value < 1) return; 809 int hHeap = OS.GetProcessHeap (); 810 int count = OS.SendMessage (hwndUpDown, OS.UDM_GETACCEL, 0, (UDACCEL)null); 811 int udaccels = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, UDACCEL.sizeof * count); 812 OS.SendMessage (hwndUpDown, OS.UDM_GETACCEL, count, udaccels); 813 int first = -1; 814 UDACCEL udaccel = new UDACCEL (); 815 for (int i = 0; i < count; i++) { 816 int offset = udaccels + (i * UDACCEL.sizeof); 817 OS.MoveMemory (udaccel, offset, UDACCEL.sizeof); 818 if (first == -1) first = udaccel.nInc; 819 udaccel.nInc = udaccel.nInc * value / first; 820 OS.MoveMemory (offset, udaccel, UDACCEL.sizeof); 821 } 822 OS.SendMessage (hwndUpDown, OS.UDM_SETACCEL, count, udaccels); 823 OS.HeapFree (hHeap, 0, udaccels); 824 } 825 826 839 public void setMaximum (int value) { 840 checkWidget (); 841 if (value < 0) return; 842 int [] min = new int [1]; 843 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, min, null); 844 if (value <= min [0]) return; 845 int pos; 846 if (OS.IsWinCE) { 847 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS, 0, 0) & 0xFFFF; 848 } else { 849 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS32, 0, 0); 850 } 851 OS.SendMessage (hwndUpDown , OS.UDM_SETRANGE32, min [0], value); 852 if (pos > value) setSelection (value, true, true, false); 853 } 854 855 868 public void setMinimum (int value) { 869 checkWidget (); 870 if (value < 0) return; 871 int [] max = new int [1]; 872 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, null, max); 873 if (value >= max [0]) return; 874 int pos; 875 if (OS.IsWinCE) { 876 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS, 0, 0) & 0xFFFF; 877 } else { 878 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS32, 0, 0); 879 } 880 OS.SendMessage (hwndUpDown , OS.UDM_SETRANGE32, value, max [0]); 881 if (pos < value) setSelection (value, true, true, false); 882 } 883 884 896 public void setPageIncrement (int value) { 897 checkWidget (); 898 if (value < 1) return; 899 pageIncrement = value; 900 } 901 902 915 public void setSelection (int value) { 916 checkWidget (); 917 int [] max = new int [1], min = new int [1]; 918 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, min, max); 919 value = Math.min (Math.max (min [0], value), max [0]); 920 setSelection (value, true, true, false); 921 } 922 923 void setSelection (int value, boolean setPos, boolean setText, boolean notify) { 924 if (setPos) { 925 OS.SendMessage (hwndUpDown , OS.IsWinCE ? OS.UDM_SETPOS : OS.UDM_SETPOS32, 0, value); 926 } 927 if (setText) { 928 String string = String.valueOf (value); 929 if (digits > 0) { 930 String decimalSeparator = getDecimalSeparator (); 931 int index = string.length () - digits; 932 StringBuffer buffer = new StringBuffer (); 933 if (index > 0) { 934 buffer.append (string.substring (0, index)); 935 buffer.append (decimalSeparator); 936 buffer.append (string.substring (index)); 937 } else { 938 buffer.append ("0"); 939 buffer.append (decimalSeparator); 940 while (index++ < 0) buffer.append ("0"); 941 buffer.append (string); 942 } 943 string = buffer.toString (); 944 } 945 if (hooks (SWT.Verify) || filters (SWT.Verify)) { 946 int length = OS.GetWindowTextLength (hwndText); 947 string = verifyText (string, 0, length, null); 948 if (string == null) return; 949 } 950 TCHAR buffer = new TCHAR (getCodePage (), string, true); 951 OS.SetWindowText (hwndText, buffer); 952 } 953 if (notify) postEvent (SWT.Selection); 954 } 955 956 void setToolTipText (Shell shell, String string) { 957 shell.setToolTipText (hwndText, string); 958 shell.setToolTipText (hwndUpDown, string); 959 } 960 961 984 public void setValues (int selection, int minimum, int maximum, int digits, int increment, int pageIncrement) { 985 checkWidget (); 986 if (minimum < 0) return; 987 if (maximum <= minimum) return; 988 if (digits < 0) return; 989 if (increment < 1) return; 990 if (pageIncrement < 1) return; 991 selection = Math.min (Math.max (minimum, selection), maximum); 992 setIncrement (increment); 993 this.pageIncrement = pageIncrement; 994 this.digits = digits; 995 OS.SendMessage (hwndUpDown , OS.UDM_SETRANGE32, minimum, maximum); 996 setSelection (selection, true, true, false); 997 } 998 999 void subclass () { 1000 super.subclass (); 1001 int newProc = display.windowProc; 1002 OS.SetWindowLong (hwndText, OS.GWL_WNDPROC, newProc); 1003 OS.SetWindowLong (hwndUpDown, OS.GWL_WNDPROC, newProc); 1004} 1005 1006void unsubclass () { 1007 super.unsubclass (); 1008 OS.SetWindowLong (hwndText, OS.GWL_WNDPROC, EditProc); 1009 OS.SetWindowLong (hwndUpDown, OS.GWL_WNDPROC, UpDownProc); 1010} 1011 1012String verifyText (String string, int start, int end, Event keyEvent) { 1013 Event event = new Event (); 1014 event.text = string; 1015 event.start = start; 1016 event.end = end; 1017 if (keyEvent != null) { 1018 event.character = keyEvent.character; 1019 event.keyCode = keyEvent.keyCode; 1020 event.stateMask = keyEvent.stateMask; 1021 } 1022 int index = 0; 1023 if (digits > 0) { 1024 String decimalSeparator = getDecimalSeparator (); 1025 index = string.indexOf (decimalSeparator); 1026 if (index != -1) { 1027 string = string.substring (0, index) + string.substring (index + 1); 1028 } 1029 index = 0; 1030 } 1031 while (index < string.length ()) { 1032 if (!Character.isDigit (string.charAt (index))) break; 1033 index++; 1034 } 1035 event.doit = index == string.length (); 1036 if (!OS.IsUnicode && OS.IsDBLocale) { 1037 event.start = mbcsToWcsPos (start); 1038 event.end = mbcsToWcsPos (end); 1039 } 1040 sendEvent (SWT.Verify, event); 1041 if (!event.doit || isDisposed ()) return null; 1042 return event.text; 1043} 1044 1045int widgetExtStyle () { 1046 return super.widgetExtStyle () & ~OS.WS_EX_CLIENTEDGE; 1047} 1048 1049int windowProc (int hwnd, int msg, int wParam, int lParam) { 1050 if (hwnd == hwndText || hwnd == hwndUpDown) { 1051 LRESULT result = null; 1052 switch (msg) { 1053 1054 case OS.WM_CHAR: result = wmChar (hwnd, wParam, lParam); break; 1055 case OS.WM_IME_CHAR: result = wmIMEChar (hwnd, wParam, lParam); break; 1056 case OS.WM_KEYDOWN: result = wmKeyDown (hwnd, wParam, lParam); break; 1057 case OS.WM_KEYUP: result = wmKeyUp (hwnd, wParam, lParam); break; 1058 case OS.WM_SYSCHAR: result = wmSysChar (hwnd, wParam, lParam); break; 1059 case OS.WM_SYSKEYDOWN: result = wmSysKeyDown (hwnd, wParam, lParam); break; 1060 case OS.WM_SYSKEYUP: result = wmSysKeyUp (hwnd, wParam, lParam); break; 1061 1062 1063 case OS.WM_CAPTURECHANGED: result = wmCaptureChanged (hwnd, wParam, lParam); break; 1064 case OS.WM_LBUTTONDBLCLK: result = wmLButtonDblClk (hwnd, wParam, lParam); break; 1065 case OS.WM_LBUTTONDOWN: result = wmLButtonDown (hwnd, wParam, lParam); break; 1066 case OS.WM_LBUTTONUP: result = wmLButtonUp (hwnd, wParam, lParam); break; 1067 case OS.WM_MBUTTONDBLCLK: result = wmMButtonDblClk (hwnd, wParam, lParam); break; 1068 case OS.WM_MBUTTONDOWN: result = wmMButtonDown (hwnd, wParam, lParam); break; 1069 case OS.WM_MBUTTONUP: result = wmMButtonUp (hwnd, wParam, lParam); break; 1070 case OS.WM_MOUSEHOVER: result = wmMouseHover (hwnd, wParam, lParam); break; 1071 case OS.WM_MOUSELEAVE: result = wmMouseLeave (hwnd, wParam, lParam); break; 1072 case OS.WM_MOUSEMOVE: result = wmMouseMove (hwnd, wParam, lParam); break; 1073 case OS.WM_RBUTTONDBLCLK: result = wmRButtonDblClk (hwnd, wParam, lParam); break; 1075 case OS.WM_RBUTTONDOWN: result = wmRButtonDown (hwnd, wParam, lParam); break; 1076 case OS.WM_RBUTTONUP: result = wmRButtonUp (hwnd, wParam, lParam); break; 1077 case OS.WM_XBUTTONDBLCLK: result = wmXButtonDblClk (hwnd, wParam, lParam); break; 1078 case OS.WM_XBUTTONDOWN: result = wmXButtonDown (hwnd, wParam, lParam); break; 1079 case OS.WM_XBUTTONUP: result = wmXButtonUp (hwnd, wParam, lParam); break; 1080 1081 1082 case OS.WM_SETFOCUS: result = wmSetFocus (hwnd, wParam, lParam); break; 1083 case OS.WM_KILLFOCUS: result = wmKillFocus (hwnd, wParam, lParam); break; 1084 1085 1086 case OS.WM_PAINT: result = wmPaint (hwnd, wParam, lParam); break; 1087 case OS.WM_PRINT: result = wmPrint (hwnd, wParam, lParam); break; 1088 1089 1090 case OS.WM_CONTEXTMENU: result = wmContextMenu (hwnd, wParam, lParam); break; 1091 1092 1093 case OS.WM_CLEAR: 1094 case OS.WM_CUT: 1095 case OS.WM_PASTE: 1096 case OS.WM_UNDO: 1097 case OS.EM_UNDO: 1098 if (hwnd == hwndText) { 1099 result = wmClipboard (hwnd, msg, wParam, lParam); 1100 } 1101 break; 1102 } 1103 if (result != null) return result.value; 1104 return callWindowProc (hwnd, msg, wParam, lParam); 1105 } 1106 return super.windowProc (hwnd, msg, wParam, lParam); 1107} 1108 1109LRESULT WM_ERASEBKGND (int wParam, int lParam) { 1110 super.WM_ERASEBKGND (wParam, lParam); 1111 drawBackground (wParam); 1112 return LRESULT.ONE; 1113} 1114 1115LRESULT WM_KILLFOCUS (int wParam, int lParam) { 1116 return null; 1117} 1118 1119LRESULT WM_SETFOCUS (int wParam, int lParam) { 1120 OS.SetFocus (hwndText); 1121 return null; 1122} 1123 1124LRESULT WM_SETFONT (int wParam, int lParam) { 1125 LRESULT result = super.WM_SETFONT (wParam, lParam); 1126 if (result != null) return result; 1127 OS.SendMessage (hwndText, OS.WM_SETFONT, wParam, lParam); 1128 return result; 1129} 1130 1131LRESULT WM_SIZE (int wParam, int lParam) { 1132 LRESULT result = super.WM_SIZE (wParam, lParam); 1133 if (isDisposed ()) return result; 1134 int width = lParam & 0xFFFF, height = lParam >> 16; 1135 int upDownWidth = OS.GetSystemMetrics (OS.SM_CXVSCROLL); 1136 int textWidth = width - upDownWidth; 1137 int border = OS.GetSystemMetrics (OS.SM_CXEDGE); 1138 int flags = OS.SWP_NOZORDER | OS.SWP_DRAWFRAME | OS.SWP_NOACTIVATE; 1139 SetWindowPos (hwndText, 0, 0, 0, textWidth + border, height, flags); 1140 SetWindowPos (hwndUpDown, 0, textWidth, 0, upDownWidth, height, flags); 1141 return result; 1142} 1143 1144LRESULT wmChar (int hwnd, int wParam, int lParam) { 1145 LRESULT result = super.wmChar (hwnd, wParam, lParam); 1146 if (result != null) return result; 1147 1154 switch (wParam) { 1155 case SWT.CR: 1156 postEvent (SWT.DefaultSelection); 1157 case SWT.TAB: 1159 case SWT.ESC: return LRESULT.ZERO; 1160 } 1161 return result; 1162} 1163 1164LRESULT wmClipboard (int hwndText, int msg, int wParam, int lParam) { 1165 if ((style & SWT.READ_ONLY) != 0) return null; 1166 boolean call = false; 1168 int [] start = new int [1], end = new int [1]; 1169 String newText = null; 1170 switch (msg) { 1171 case OS.WM_CLEAR: 1172 case OS.WM_CUT: 1173 OS.SendMessage (hwndText, OS.EM_GETSEL, start, end); 1174 if (start [0] != end [0]) { 1175 newText = ""; 1176 call = true; 1177 } 1178 break; 1179 case OS.WM_PASTE: 1180 OS.SendMessage (hwndText, OS.EM_GETSEL, start, end); 1181 newText = getClipboardText (); 1182 break; 1183 case OS.EM_UNDO: 1184 case OS.WM_UNDO: 1185 if (OS.SendMessage (hwndText, OS.EM_CANUNDO, 0, 0) != 0) { 1186 ignoreModify = true; 1187 OS.SendMessage (hwndText, OS.EM_GETSEL, start, end); 1188 OS.CallWindowProc (EditProc, hwndText, msg, wParam, lParam); 1189 int length = OS.GetWindowTextLength (hwndText); 1190 int [] newStart = new int [1], newEnd = new int [1]; 1191 OS.SendMessage (hwndText, OS.EM_GETSEL, newStart, newEnd); 1192 if (length != 0 && newStart [0] != newEnd [0]) { 1193 TCHAR buffer = new TCHAR (getCodePage (), length + 1); 1194 OS.GetWindowText (hwndText, buffer, length + 1); 1195 newText = buffer.toString (newStart [0], newEnd [0] - newStart [0]); 1196 } else { 1197 newText = ""; 1198 } 1199 OS.CallWindowProc (EditProc, hwndText, msg, wParam, lParam); 1200 ignoreModify = false; 1201 } 1202 break; 1203 } 1204 if (newText != null) { 1205 String oldText = newText; 1206 newText = verifyText (newText, start [0], end [0], null); 1207 if (newText == null) return LRESULT.ZERO; 1208 if (!newText.equals (oldText)) { 1209 if (call) { 1210 OS.CallWindowProc (EditProc, hwndText, msg, wParam, lParam); 1211 } 1212 TCHAR buffer = new TCHAR (getCodePage (), newText, true); 1213 if (msg == OS.WM_SETTEXT) { 1214 int hHeap = OS.GetProcessHeap (); 1215 int byteCount = buffer.length () * TCHAR.sizeof; 1216 int pszText = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount); 1217 OS.MoveMemory (pszText, buffer, byteCount); 1218 int code = OS.CallWindowProc (EditProc, hwndText, msg, wParam, pszText); 1219 OS.HeapFree (hHeap, 0, pszText); 1220 return new LRESULT (code); 1221 } else { 1222 OS.SendMessage (hwndText, OS.EM_REPLACESEL, 0, buffer); 1223 return LRESULT.ZERO; 1224 } 1225 } 1226 } 1227 return null; 1228} 1229 1230LRESULT wmCommandChild (int wParam, int lParam) { 1231 int code = wParam >> 16; 1232 switch (code) { 1233 case OS.EN_CHANGE: 1234 if (ignoreModify) break; 1235 int value = getSelectionText (); 1236 if (value != -1) { 1237 int pos; 1238 if (OS.IsWinCE) { 1239 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS, 0, 0) & 0xFFFF; 1240 } else { 1241 pos = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS32, 0, 0); 1242 } 1243 if (pos != value) setSelection (value, true, false, true); 1244 } 1245 sendEvent (SWT.Modify); 1246 if (isDisposed ()) return LRESULT.ZERO; 1247 break; 1248 } 1249 return super.wmCommandChild (wParam, lParam); 1250} 1251 1252LRESULT wmKeyDown (int hwnd, int wParam, int lParam) { 1253 LRESULT result = super.wmKeyDown (hwnd, wParam, lParam); 1254 if (result != null) return result; 1255 1256 1257 UDACCEL udaccel = new UDACCEL (); 1258 OS.SendMessage (hwndUpDown, OS.UDM_GETACCEL, 1, udaccel); 1259 int delta = 0; 1260 switch (wParam) { 1261 case OS.VK_UP: delta = udaccel.nInc; break; 1262 case OS.VK_DOWN: delta = -udaccel.nInc; break; 1263 case OS.VK_PRIOR: delta = pageIncrement; break; 1264 case OS.VK_NEXT: delta = -pageIncrement; break; 1265 } 1266 if (delta != 0) { 1267 int value = getSelectionText (); 1268 if (value != -1) { 1269 if (OS.IsWinCE) { 1270 value = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS, 0, 0) & 0xFFFF; 1271 } else { 1272 value = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS32, 0, 0); 1273 } 1274 } 1275 int newValue = value + delta; 1276 int [] max = new int [1], min = new int [1]; 1277 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, min, max); 1278 if ((style & SWT.WRAP) != 0) { 1279 if (newValue < min [0]) newValue = max [0]; 1280 if (newValue > max [0]) newValue = min [0]; 1281 } 1282 newValue = Math.min (Math.max (min [0], newValue), max [0]); 1283 if (value != newValue) setSelection (newValue, true, true, true); 1284 } 1285 1286 1287 switch (wParam) { 1288 case OS.VK_UP: 1289 case OS.VK_DOWN: 1290 return LRESULT.ZERO; 1291 } 1292 return result; 1293} 1294 1295LRESULT wmKillFocus (int hwnd, int wParam, int lParam) { 1296 int value = getSelectionText (); 1297 if (value == -1) { 1298 if (OS.IsWinCE) { 1299 value = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS, 0, 0) & 0xFFFF; 1300 } else { 1301 value = OS.SendMessage (hwndUpDown, OS.UDM_GETPOS32, 0, 0); 1302 } 1303 setSelection (value, false, true, false); 1304 } 1305 return super.wmKillFocus (hwnd, wParam, lParam); 1306} 1307 1308LRESULT wmNotifyChild (NMHDR hdr, int wParam, int lParam) { 1309 switch (hdr.code) { 1310 case OS.UDN_DELTAPOS: 1311 NMUPDOWN lpnmud = new NMUPDOWN (); 1312 OS.MoveMemory (lpnmud, lParam, NMUPDOWN.sizeof); 1313 int value = lpnmud.iPos + lpnmud.iDelta; 1314 int [] max = new int [1], min = new int [1]; 1315 OS.SendMessage (hwndUpDown , OS.UDM_GETRANGE32, min, max); 1316 if ((style & SWT.WRAP) != 0) { 1317 if (value < min [0]) value = max [0]; 1318 if (value > max [0]) value = min [0]; 1319 } 1320 1328 value = Math.min (Math.max (min [0], value), max [0]); 1329 if (value != lpnmud.iPos) { 1330 setSelection (value, true, true, true); 1331 } 1332 return LRESULT.ONE; 1333 } 1334 return super.wmNotifyChild (hdr, wParam, lParam); 1335} 1336 1337LRESULT wmScrollChild (int wParam, int lParam) { 1338 int code = wParam & 0xFFFF; 1339 switch (code) { 1340 case OS.SB_THUMBPOSITION: 1341 postEvent (SWT.Selection); 1342 break; 1343 } 1344 return super.wmScrollChild (wParam, lParam); 1345} 1346 1347} 1348 | Popular Tags |