- Add support for navigating a toolbar with the arrow keys.

- Fix WrapToolbar in the case of no parent window.
- Use the newly added NMTBINITCUSTOMIZE for sending the
  TBN_INITCUSTOMIZE so that it is safe on 64-bit platforms.
This commit is contained in:
Robert Shearman 2005-09-14 19:16:03 +00:00 committed by Alexandre Julliard
parent 3fa5678ea9
commit 2c6ab0dba5
2 changed files with 129 additions and 12 deletions

View File

@ -41,7 +41,6 @@
* - WM_WININICHANGE * - WM_WININICHANGE
* - Notifications: * - Notifications:
* - NM_CHAR * - NM_CHAR
* - NM_KEYDOWN
* - TBN_GETOBJECT * - TBN_GETOBJECT
* - TBN_SAVE * - TBN_SAVE
* - Button wrapping (under construction). * - Button wrapping (under construction).
@ -1278,12 +1277,21 @@ TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
btnPtr = infoPtr->buttons; btnPtr = infoPtr->buttons;
x = infoPtr->nIndent; x = infoPtr->nIndent;
/* this can get the parents width, to know how far we can extend if (GetParent(hwnd))
* this toolbar. We cannot use its height, as there may be multiple {
* toolbars in a rebar control /* this can get the parents width, to know how far we can extend
*/ * this toolbar. We cannot use its height, as there may be multiple
GetClientRect( GetParent(hwnd), &rc ); * toolbars in a rebar control
infoPtr->nWidth = rc.right - rc.left; */
GetClientRect( GetParent(hwnd), &rc );
infoPtr->nWidth = rc.right - rc.left;
}
else
{
GetWindowRect( hwnd, &rc );
infoPtr->nWidth = rc.right - rc.left;
}
bButtonWrap = FALSE; bButtonWrap = FALSE;
TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n", TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n",
@ -2193,6 +2201,7 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
WCHAR Buffer[256]; WCHAR Buffer[256];
int i = 0; int i = 0;
int index; int index;
NMTBINITCUSTOMIZE nmtbic;
infoPtr = custInfo->tbInfo; infoPtr = custInfo->tbInfo;
@ -2202,10 +2211,9 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (!TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_QUERYINSERT)) if (!TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_QUERYINSERT))
return FALSE; return FALSE;
/* UNDOCUMENTED: dialog hwnd immediately follows NMHDR */ nmtbic.hwndDialog = hwnd;
memcpy(&nmtb.iItem, &hwnd, sizeof(hwnd));
/* Send TBN_INITCUSTOMIZE notification */ /* Send TBN_INITCUSTOMIZE notification */
if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_INITCUSTOMIZE) == if (TOOLBAR_SendNotify (&nmtbic.hdr, infoPtr, TBN_INITCUSTOMIZE) ==
TBNRF_HIDEHELP) TBNRF_HIDEHELP)
{ {
TRACE("TBNRF_HIDEHELP requested\n"); TRACE("TBNRF_HIDEHELP requested\n");
@ -5783,6 +5791,77 @@ TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
} }
static void
TOOLBAR_SetRelativeHotItem(TOOLBAR_INFO *infoPtr, INT iDirection, DWORD dwReason)
{
INT i;
INT nNewHotItem = infoPtr->nHotItem;
for (i = 0; i < infoPtr->nNumButtons; i++)
{
/* did we wrap? */
if ((nNewHotItem + iDirection < 0) ||
(nNewHotItem + iDirection >= infoPtr->nNumButtons))
{
NMTBWRAPHOTITEM nmtbwhi;
nmtbwhi.idNew = infoPtr->buttons[nNewHotItem].idCommand;
nmtbwhi.iDirection = iDirection;
nmtbwhi.dwReason = dwReason;
if (TOOLBAR_SendNotify(&nmtbwhi.hdr, infoPtr, TBN_WRAPHOTITEM))
return;
}
nNewHotItem += iDirection;
nNewHotItem = (nNewHotItem + infoPtr->nNumButtons) % infoPtr->nNumButtons;
if ((infoPtr->buttons[nNewHotItem].fsState & TBSTATE_ENABLED) &&
!(infoPtr->buttons[nNewHotItem].fsStyle & BTNS_SEP))
{
TOOLBAR_SetHotItemEx(infoPtr, nNewHotItem, dwReason);
break;
}
}
}
static LRESULT
TOOLBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
NMKEY nmkey;
nmkey.nVKey = (UINT)wParam;
nmkey.uFlags = HIWORD(lParam);
if (TOOLBAR_SendNotify(&nmkey.hdr, infoPtr, NM_KEYDOWN))
return DefWindowProcW(hwnd, WM_KEYDOWN, wParam, lParam);
switch ((UINT)wParam)
{
case VK_LEFT:
case VK_UP:
TOOLBAR_SetRelativeHotItem(infoPtr, -1, HICF_ARROWKEYS);
break;
case VK_RIGHT:
case VK_DOWN:
TOOLBAR_SetRelativeHotItem(infoPtr, 1, HICF_ARROWKEYS);
break;
case VK_SPACE:
case VK_RETURN:
if ((infoPtr->nHotItem >= 0) &&
(infoPtr->buttons[infoPtr->nHotItem].fsState & TBSTATE_ENABLED))
{
SendMessageW (infoPtr->hwndNotify, WM_COMMAND,
MAKEWPARAM(infoPtr->buttons[infoPtr->nHotItem].idCommand, BN_CLICKED),
(LPARAM)hwnd);
}
break;
}
return 0;
}
static LRESULT static LRESULT
TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam) TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
{ {
@ -6080,7 +6159,7 @@ TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (btnPtr->fsState & TBSTATE_ENABLED) if (btnPtr->fsState & TBSTATE_ENABLED)
{ {
SendMessageW (infoPtr->hwndNotify, WM_COMMAND, SendMessageW (infoPtr->hwndNotify, WM_COMMAND,
MAKEWPARAM(infoPtr->buttons[nHit].idCommand, 0), (LPARAM)hwnd); MAKEWPARAM(infoPtr->buttons[nHit].idCommand, BN_CLICKED), (LPARAM)hwnd);
} }
} }
@ -6320,6 +6399,7 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
/* paranoid!! */ /* paranoid!! */
infoPtr->dwStructSize = sizeof(TBBUTTON); infoPtr->dwStructSize = sizeof(TBBUTTON);
infoPtr->nRows = 1; infoPtr->nRows = 1;
infoPtr->nWidth = 0;
/* fix instance handle, if the toolbar was created by CreateToolbarEx() */ /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
if (!GetWindowLongPtrW (hwnd, GWLP_HINSTANCE)) { if (!GetWindowLongPtrW (hwnd, GWLP_HINSTANCE)) {
@ -6639,6 +6719,21 @@ TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
} }
static LRESULT
TOOLBAR_SetFocus (HWND hwnd, WPARAM wParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TRACE("nHotItem = %d\n", infoPtr->nHotItem);
/* make first item hot */
if (infoPtr->nNumButtons > 0)
TOOLBAR_SetHotItemEx(infoPtr, 0, HICF_OTHER);
return 0;
}
static LRESULT static LRESULT
TOOLBAR_SetRedraw (HWND hwnd, WPARAM wParam, LPARAM lParam) TOOLBAR_SetRedraw (HWND hwnd, WPARAM wParam, LPARAM lParam)
/***************************************************** /*****************************************************
@ -7092,7 +7187,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_GETFONT: case WM_GETFONT:
return TOOLBAR_GetFont (hwnd, wParam, lParam); return TOOLBAR_GetFont (hwnd, wParam, lParam);
/* case WM_KEYDOWN: */ case WM_KEYDOWN:
return TOOLBAR_KeyDown (hwnd, wParam, lParam);
/* case WM_KILLFOCUS: */ /* case WM_KILLFOCUS: */
case WM_LBUTTONDBLCLK: case WM_LBUTTONDBLCLK:
@ -7140,6 +7237,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_PAINT: case WM_PAINT:
return TOOLBAR_Paint (hwnd, wParam); return TOOLBAR_Paint (hwnd, wParam);
case WM_SETFOCUS:
return TOOLBAR_SetFocus (hwnd, wParam);
case WM_SETREDRAW: case WM_SETREDRAW:
return TOOLBAR_SetRedraw (hwnd, wParam, lParam); return TOOLBAR_SetRedraw (hwnd, wParam, lParam);

View File

@ -1235,6 +1235,7 @@ static const WCHAR TOOLBARCLASSNAMEW[] = { 'T','o','o','l','b','a','r',
#define TBN_RESTORE (TBN_FIRST-21) #define TBN_RESTORE (TBN_FIRST-21)
#define TBN_SAVE (TBN_FIRST-22) #define TBN_SAVE (TBN_FIRST-22)
#define TBN_INITCUSTOMIZE (TBN_FIRST-23) #define TBN_INITCUSTOMIZE (TBN_FIRST-23)
#define TBN_WRAPHOTITEM (TBN_FIRST-24) /* this is undocumented and the name is a guess */
#define TBNRF_HIDEHELP 0x00000001 #define TBNRF_HIDEHELP 0x00000001
@ -1552,6 +1553,22 @@ typedef struct
INT cyButtonSpacing; INT cyButtonSpacing;
} TBMETRICS, *LPTBMETRICS; } TBMETRICS, *LPTBMETRICS;
/* these are undocumented and the names are guesses */
typedef struct
{
NMHDR hdr;
HWND hwndDialog;
} NMTBINITCUSTOMIZE;
typedef struct
{
NMHDR hdr;
INT idNew;
INT iDirection; /* left is -1, right is 1 */
DWORD dwReason; /* HICF_* */
} NMTBWRAPHOTITEM;
HWND WINAPI HWND WINAPI
CreateToolbar(HWND, DWORD, UINT, INT, HINSTANCE, CreateToolbar(HWND, DWORD, UINT, INT, HINSTANCE,
UINT, LPCTBBUTTON, INT); UINT, LPCTBBUTTON, INT);