Mercurial > projects > dwt-win
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: |