comparison dwt/widgets/List.d @ 213:36f5cb12e1a2

Update to SWT 3.4M7
author Frank Benoit <benoit@tionex.de>
date Sat, 17 May 2008 17:34:28 +0200
parents ab60f3309436
children a8fed3e56433
comparison
equal deleted inserted replaced
212:ab60f3309436 213:36f5cb12e1a2
200 addListener (DWT.DefaultSelection,typedListener); 200 addListener (DWT.DefaultSelection,typedListener);
201 } 201 }
202 202
203 override int callWindowProc (HWND hwnd, int msg, int wParam, int lParam) { 203 override int callWindowProc (HWND hwnd, int msg, int wParam, int lParam) {
204 if (handle is null) return 0; 204 if (handle is null) return 0;
205 return OS.CallWindowProc (ListProc, hwnd, msg, wParam, lParam); 205 bool redraw = false;
206 switch (msg) {
207 case OS.WM_HSCROLL:
208 case OS.WM_VSCROLL: {
209 redraw = findImageControl () !is null && drawCount is 0 && OS.IsWindowVisible (handle);
210 if (redraw) OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0);
211 break;
212 }
213 }
214 int /*long*/ code = OS.CallWindowProc (ListProc, hwnd, msg, wParam, lParam);
215 switch (msg) {
216 case OS.WM_HSCROLL:
217 case OS.WM_VSCROLL: {
218 if (redraw) {
219 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0);
220 OS.InvalidateRect (handle, null, true);
221 }
222 break;
223 }
224 }
225 return code;
206 } 226 }
207 227
208 static int checkStyle (int style) { 228 static int checkStyle (int style) {
209 return checkBits (style, DWT.SINGLE, DWT.MULTI, 0, 0, 0, 0); 229 return checkBits (style, DWT.SINGLE, DWT.MULTI, 0, 0, 0, 0);
210 } 230 }
1201 checkWidget (); 1221 checkWidget ();
1202 if (items is null) error (DWT.ERROR_NULL_ARGUMENT); 1222 if (items is null) error (DWT.ERROR_NULL_ARGUMENT);
1203 for (int i=0; i<items.length; i++) { 1223 for (int i=0; i<items.length; i++) {
1204 if (items [i] is null) error (DWT.ERROR_INVALID_ARGUMENT); 1224 if (items [i] is null) error (DWT.ERROR_INVALID_ARGUMENT);
1205 } 1225 }
1206 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); 1226 int /*long*/ oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC);
1207 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) ListProc); 1227 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR) ListProc);
1208 bool redraw = drawCount is 0 && OS.IsWindowVisible (handle); 1228 bool redraw = drawCount is 0 && OS.IsWindowVisible (handle);
1209 if (redraw) { 1229 if (redraw) {
1210 OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); 1230 OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0);
1211 } 1231 }
1212 RECT rect; 1232 RECT rect;
1253 * behavior. 1273 * behavior.
1254 */ 1274 */
1255 // int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE; 1275 // int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE;
1256 // OS.RedrawWindow (handle, null, 0, flags); 1276 // OS.RedrawWindow (handle, null, 0, flags);
1257 } 1277 }
1258 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); 1278 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc);
1259 if (index < items.length) error (DWT.ERROR_ITEM_NOT_ADDED); 1279 if (index < items.length) error (DWT.ERROR_ITEM_NOT_ADDED);
1260 } 1280 }
1261 1281
1262 void setScrollWidth () { 1282 void setScrollWidth () {
1263 int newWidth = 0; 1283 int newWidth = 0;
1530 1550
1531 override int windowProc () { 1551 override int windowProc () {
1532 return cast(int) ListProc; 1552 return cast(int) ListProc;
1533 } 1553 }
1534 1554
1535 override LRESULT WM_SIZE (int wParam, int lParam) { 1555 override LRESULT WM_CHAR (int wParam, int lParam) {
1556 LRESULT result = super.WM_CHAR (wParam, lParam);
1557 if (result !is null) return result;
1558 /*
1559 * Feature in Windows. The Windows list box does not implement
1560 * the control key interface for multi-select list boxes, making
1561 * it inaccessible from the keyboard. The fix is to implement
1562 * the key processing.
1563 */
1564 if (OS.GetKeyState (OS.VK_CONTROL) < 0 && OS.GetKeyState (OS.VK_SHIFT) >= 0) {
1565 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
1566 if ((bits & OS.LBS_EXTENDEDSEL) !is 0) {
1567 switch (wParam) {
1568 case OS.VK_SPACE: {
1569 int index = OS.SendMessage (handle, OS.LB_GETCARETINDEX, 0, 0);
1570 int code = OS.SendMessage (handle, OS.LB_GETSEL, index, 0);
1571 if (code is OS.LB_ERR) break;
1572 OS.SendMessage (handle, OS.LB_SETSEL, code !is 0 ? 0 : 1, index);
1573 OS.SendMessage (handle, OS.LB_SETANCHORINDEX, index, 0);
1574 postEvent (DWT.Selection);
1575 return LRESULT.ZERO;
1576 }
1577 }
1578 }
1579 }
1580 return result;
1581 }
1582
1583 override LRESULT WM_KEYDOWN (int /*long*/ wParam, int /*long*/ lParam) {
1584 LRESULT result = super.WM_KEYDOWN (wParam, lParam);
1585 if (result !is null) return result;
1586 /*
1587 * Feature in Windows. The Windows list box does not implement
1588 * the control key interface for multi-select list boxes, making
1589 * it inaccessible from the keyboard. The fix is to implement
1590 * the key processing.
1591 */
1592 if (OS.GetKeyState (OS.VK_CONTROL) < 0 && OS.GetKeyState (OS.VK_SHIFT) >= 0) {
1593 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
1594 if ((bits & OS.LBS_EXTENDEDSEL) !is 0) {
1595 int location = -1;
1596 switch (wParam) {
1597 case OS.VK_SPACE: {
1598 /*
1599 * Ensure that the window proc does not process VK_SPACE
1600 * so that it can be handled in WM_CHAR. This allows the
1601 * application to cancel an operation that is normally
1602 * performed in WM_KEYDOWN from WM_CHAR.
1603 */
1604 return LRESULT.ZERO;
1605 }
1606 case OS.VK_UP:
1607 case OS.VK_DOWN: {
1608 int index = OS.SendMessage (handle, OS.LB_GETCARETINDEX, 0, 0);
1609 location = Math.max (0, index + ((wParam) is OS.VK_UP ? -1 : 1));
1610 break;
1611 }
1612 case OS.VK_PRIOR: {
1613 int index = OS.SendMessage (handle, OS.LB_GETCARETINDEX, 0, 0);
1614 int topIndex = OS.SendMessage (handle, OS.LB_GETTOPINDEX, 0, 0);
1615 if (index !is topIndex) {
1616 location = topIndex;
1617 } else {
1618 forceResize ();
1619 RECT rect;
1620 OS.GetClientRect (handle, &rect);
1621 int itemHeight = OS.SendMessage (handle, OS.LB_GETITEMHEIGHT, 0, 0);
1622 int pageSize = Math.max (2, (rect.bottom / itemHeight));
1623 location = Math.max (0, topIndex - (pageSize - 1));
1624 }
1625 break;
1626 }
1627 case OS.VK_NEXT: {
1628 int index = OS.SendMessage (handle, OS.LB_GETCARETINDEX, 0, 0);
1629 int topIndex = OS.SendMessage (handle, OS.LB_GETTOPINDEX, 0, 0);
1630 forceResize ();
1631 RECT rect;
1632 OS.GetClientRect (handle, &rect);
1633 int itemHeight = OS.SendMessage (handle, OS.LB_GETITEMHEIGHT, 0, 0);
1634 int pageSize = Math.max (2, (rect.bottom / itemHeight));
1635 int bottomIndex = topIndex + pageSize - 1;
1636 if (index !is bottomIndex) {
1637 location = bottomIndex;
1638 } else {
1639 location = bottomIndex + pageSize - 1;
1640 }
1641 int count = OS.SendMessage (handle, OS.LB_GETCOUNT, 0, 0);
1642 if (count !is OS.LB_ERR) location = Math.min (count - 1, location);
1643 break;
1644 }
1645 case OS.VK_HOME: {
1646 location = 0;
1647 break;
1648 }
1649 case OS.VK_END: {
1650 int count = OS.SendMessage (handle, OS.LB_GETCOUNT, 0, 0);
1651 if (count is OS.LB_ERR) break;
1652 location = count - 1;
1653 break;
1654 }
1655 }
1656 if (location !is -1) {
1657 OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
1658 OS.SendMessage (handle, OS.LB_SETCARETINDEX, location, 0);
1659 return LRESULT.ZERO;
1660 }
1661 }
1662 }
1663
1664 /*
1665 * Feature in Windows. When the user changes focus using
1666 * the keyboard, the focus indicator does not draw. The
1667 * fix is to update the UI state for the control whenever
1668 * the focus indicator changes as a result of something
1669 * the user types.
1670 */
1671 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
1672 if ((uiState & OS.UISF_HIDEFOCUS) !is 0) {
1673 int oldIndex = OS.SendMessage (handle, OS.LB_GETCARETINDEX, 0, 0);
1674 int /*long*/ code = callWindowProc (handle, OS.WM_KEYDOWN, wParam, lParam);
1675 int newIndex = OS.SendMessage (handle, OS.LB_GETCARETINDEX, 0, 0);
1676 if (oldIndex !is newIndex) {
1677 OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0);
1678 /*
1679 * Bug in Windows. When the WM_CHANGEUISTATE is used
1680 * to update the UI state for a list that has been
1681 * selected using Shift+Arrow, the focus indicator
1682 * has pixel corruption. The fix is to redraw the
1683 * focus item.
1684 */
1685 RECT itemRect;
1686 OS.SendMessage (handle, OS.LB_GETITEMRECT, newIndex, &itemRect);
1687 OS.InvalidateRect (handle, &itemRect, true);
1688 }
1689 return new LRESULT (code);
1690 }
1691 return result;
1692 }
1693
1694 override LRESULT WM_SIZE (int /*long*/ wParam, int /*long*/ lParam) {
1536 /* 1695 /*
1537 * Bug in Windows. If the top index is changed while the 1696 * Bug in Windows. If the top index is changed while the
1538 * list is being resized, Windows does not redraw properly 1697 * list is being resized, Windows does not redraw properly
1539 * when their is white space at the bottom of the control. 1698 * when their is white space at the bottom of the control.
1540 * The fix is to detect when the top index has changed and 1699 * The fix is to detect when the top index has changed and
1559 } 1718 }
1560 return result; 1719 return result;
1561 } 1720 }
1562 1721
1563 override LRESULT wmCommandChild (int wParam, int lParam) { 1722 override LRESULT wmCommandChild (int wParam, int lParam) {
1564 int code = wParam >> 16; 1723 int code = OS.HIWORD (wParam);
1565 switch (code) { 1724 switch (code) {
1566 case OS.LBN_SELCHANGE: 1725 case OS.LBN_SELCHANGE:
1567 postEvent (DWT.Selection); 1726 postEvent (DWT.Selection);
1568 break; 1727 break;
1569 case OS.LBN_DBLCLK: 1728 case OS.LBN_DBLCLK: