wine/dlls/comctl32/toolbar.c
1999-03-12 17:42:50 +00:00

2963 lines
70 KiB
C

/*
* Toolbar control
*
* Copyright 1998 Eric Kohl
*
* TODO:
* - A little bug in TOOLBAR_DrawMasked()
* - Button wrapping (under construction).
* - Messages.
* - Notifications.
* - Fix TB_SETROWS.
* - Tooltip support (almost complete).
* - Unicode suppport.
* - Internal COMMCTL32 bitmaps.
* - Fix TOOLBAR_SetButtonInfo32A.
* - Fix TOOLBAR_Customize. (Customize dialog.)
*
* Testing:
* - Run tests using Waite Group Windows95 API Bible Volume 2.
* The second cdrom contains executables addstr.exe, btncount.exe,
* btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
* enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
* indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
* setparnt.exe, setrows.exe, toolwnd.exe.
* - Microsofts controlspy examples.
*/
#include <string.h>
#include "commctrl.h"
#include "sysmetrics.h"
#include "cache.h"
#include "toolbar.h"
#include "win.h"
#include "debug.h"
/* #define __NEW_WRAP_CODE__ */
#define SEPARATOR_WIDTH 8
#define SEPARATOR_HEIGHT 5
#define TOP_BORDER 2
#define BOTTOM_BORDER 2
#define TOOLBAR_GetInfoPtr(wndPtr) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
static void
TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
{
INT x = (lpRect->left + lpRect->right) / 2 - 1;
INT yBottom = lpRect->bottom - 3;
INT yTop = lpRect->top + 1;
SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
MoveToEx (hdc, x, yBottom, NULL);
LineTo (hdc, x, yTop);
x++;
SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
MoveToEx (hdc, x, yBottom, NULL);
LineTo (hdc, x, yTop);
}
static void
TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
HDC hdc, INT nState)
{
RECT rcText = btnPtr->rect;
HFONT hOldFont;
INT nOldBkMode;
COLORREF clrOld;
/* draw text */
if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
InflateRect (&rcText, -3, -3);
rcText.top += infoPtr->nBitmapHeight;
if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
OffsetRect (&rcText, 1, 1);
hOldFont = SelectObject (hdc, infoPtr->hFont);
nOldBkMode = SetBkMode (hdc, TRANSPARENT);
if (!(nState & TBSTATE_ENABLED)) {
clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
OffsetRect (&rcText, 1, 1);
DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
&rcText, infoPtr->dwDTFlags);
SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
OffsetRect (&rcText, -1, -1);
DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
&rcText, infoPtr->dwDTFlags);
}
else if (nState & TBSTATE_INDETERMINATE) {
clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
&rcText, infoPtr->dwDTFlags);
}
else {
clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
&rcText, infoPtr->dwDTFlags);
}
SetTextColor (hdc, clrOld);
SelectObject (hdc, hOldFont);
if (nOldBkMode != TRANSPARENT)
SetBkMode (hdc, nOldBkMode);
}
}
static void
TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
{
HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
INT cx = lpRect->right - lpRect->left;
INT cy = lpRect->bottom - lpRect->top;
PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
SelectObject (hdc, hbr);
}
static void
TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
HDC hdc, INT x, INT y)
{
/* FIXME: this function is a hack since it uses image list
internals directly */
HDC hdcImageList = CreateCompatibleDC (0);
HDC hdcMask = CreateCompatibleDC (0);
HIMAGELIST himl = infoPtr->himlStd;
HBITMAP hbmMask;
/* create new bitmap */
hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
SelectObject (hdcMask, hbmMask);
/* copy the mask bitmap */
SelectObject (hdcImageList, himl->hbmMask);
SetBkColor (hdcImageList, RGB(255, 255, 255));
SetTextColor (hdcImageList, RGB(0, 0, 0));
BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
#if 0
/* add white mask from image */
SelectObject (hdcImageList, himl->hbmImage);
SetBkColor (hdcImageList, RGB(0, 0, 0));
BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
#endif
/* draw the new mask */
SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
hdcMask, 0, 0, 0xB8074A);
SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
BitBlt (hdc, x, y, himl->cx, himl->cy,
hdcMask, 0, 0, 0xB8074A);
DeleteObject (hbmMask);
DeleteDC (hdcMask);
DeleteDC (hdcImageList);
}
static void
TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
RECT rc;
if (btnPtr->fsState & TBSTATE_HIDDEN)
return;
rc = btnPtr->rect;
if (btnPtr->fsStyle & TBSTYLE_SEP) {
if ((dwStyle & TBSTYLE_FLAT) && (btnPtr->idCommand == 0))
TOOLBAR_DrawFlatSeparator (&btnPtr->rect, hdc);
return;
}
/* disabled */
if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
DrawEdge (hdc, &rc, EDGE_RAISED,
BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
if (dwStyle & TBSTYLE_FLAT) {
/* if (infoPtr->himlDis) */
ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
rc.left+1, rc.top+1, ILD_NORMAL);
/* else */
/* TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1); */
}
else
TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
return;
}
/* pressed TBSTYLE_BUTTON */
if (btnPtr->fsState & TBSTATE_PRESSED) {
DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
rc.left+2, rc.top+2, ILD_NORMAL);
TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
return;
}
/* checked TBSTYLE_CHECK*/
if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
(btnPtr->fsState & TBSTATE_CHECKED)) {
if (dwStyle & TBSTYLE_FLAT)
DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
BF_RECT | BF_MIDDLE | BF_ADJUST);
else
DrawEdge (hdc, &rc, EDGE_SUNKEN,
BF_RECT | BF_MIDDLE | BF_ADJUST);
TOOLBAR_DrawPattern (hdc, &rc);
if (dwStyle & TBSTYLE_FLAT)
ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
rc.left+2, rc.top+2, ILD_NORMAL);
else
ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
rc.left+2, rc.top+2, ILD_NORMAL);
TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
return;
}
/* indeterminate */
if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
DrawEdge (hdc, &rc, EDGE_RAISED,
BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
TOOLBAR_DrawPattern (hdc, &rc);
TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
return;
}
/* normal state */
DrawEdge (hdc, &rc, EDGE_RAISED,
BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
if (dwStyle & TBSTYLE_FLAT)
ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
rc.left+1, rc.top+1, ILD_NORMAL);
else
ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
rc.left+1, rc.top+1, ILD_NORMAL);
TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
}
static void
TOOLBAR_Refresh (HWND hwnd, HDC hdc)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
INT i;
/* draw buttons */
btnPtr = infoPtr->buttons;
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
}
static void
TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
INT i;
HDC hdc;
HFONT hOldFont;
SIZE sz;
lpSize->cx = 0;
lpSize->cy = 0;
hdc = GetDC (0);
hOldFont = SelectObject (hdc, infoPtr->hFont);
btnPtr = infoPtr->buttons;
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
(btnPtr->iString > -1) &&
(btnPtr->iString < infoPtr->nNumStrings)) {
LPWSTR lpText = infoPtr->strings[btnPtr->iString];
GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), &sz);
if (sz.cx > lpSize->cx)
lpSize->cx = sz.cx;
if (sz.cy > lpSize->cy)
lpSize->cy = sz.cy;
}
}
SelectObject (hdc, hOldFont);
ReleaseDC (0, hdc);
TRACE (toolbar, "string size %d x %d!\n", lpSize->cx, lpSize->cy);
}
static void
TOOLBAR_CalcToolbar (HWND hwnd)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
TBUTTON_INFO *btnPtr;
INT i, nRows;
INT x, y, cx, cy;
BOOL bWrap;
SIZE sizeString;
/* --- new --- */
#ifdef __NEW_WRAP_CODE__
INT nGrpCount = 0;
INT grpX,j;
TBUTTON_INFO *grpPtr;
#endif
/* --- end new --- */
TOOLBAR_CalcStrings (hwnd, &sizeString);
if (sizeString.cy > 0)
infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
if (sizeString.cx > infoPtr->nBitmapWidth)
infoPtr->nButtonWidth = sizeString.cx + 6;
else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
x = infoPtr->nIndent;
y = TOP_BORDER;
cx = infoPtr->nButtonWidth;
cy = infoPtr->nButtonHeight;
nRows = 0;
/* calculate the size of each button according to it's style */
/* TOOLBAR_CalcButtons (hwnd); */
infoPtr->rcBound.top = y;
infoPtr->rcBound.left = x;
infoPtr->rcBound.bottom = y + cy;
infoPtr->rcBound.right = x;
btnPtr = infoPtr->buttons;
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
bWrap = FALSE;
if (btnPtr->fsState & TBSTATE_HIDDEN) {
SetRectEmpty (&btnPtr->rect);
continue;
}
#ifdef __NEW_WRAP_CODE__
/*#if 0 */
if (btnPtr->fsStyle & TBSTYLE_SEP) {
/* UNDOCUMENTED: If a separator has a non zero bitmap index, */
/* it is the actual width of the separator. This is used for */
/* custom controls in toolbars. */
if ((dwStyle & TBSTYLE_WRAPABLE) &&
(btnPtr->fsState & TBSTATE_WRAP)) {
x = 0;
y += cy;
cx = infoPtr->nWidth;
cy = ((btnPtr->iBitmap > 0) ?
btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
/* nRows++; */
/* bWrap = TRUE; */
}
else
cx = (btnPtr->iBitmap > 0) ?
btnPtr->iBitmap : SEPARATOR_WIDTH;
}
else {
/* this must be a button */
cx = infoPtr->nButtonWidth;
}
/*#endif */
/* --- begin test --- */
if ((i >= nGrpCount) && (btnPtr->fsStyle & TBSTYLE_GROUP)) {
for (j = i, grpX = x, nGrpCount = 0; j < infoPtr->nNumButtons; j++) {
grpPtr = &infoPtr->buttons[j];
if (grpPtr->fsState & TBSTATE_HIDDEN)
continue;
grpX += cx;
if ((grpPtr->fsStyle & TBSTYLE_SEP) ||
!(grpPtr->fsStyle & TBSTYLE_GROUP) ||
(grpX > infoPtr->nWidth)) {
nGrpCount = j;
break;
}
else if (grpX + x > infoPtr->nWidth) {
bWrap = TRUE;
nGrpCount = j;
break;
}
}
}
bWrap = ((bWrap || (x + cx > infoPtr->nWidth)) &&
(dwStyle & TBSTYLE_WRAPABLE));
if (bWrap) {
nRows++;
y += cy;
x = infoPtr->nIndent;
bWrap = FALSE;
}
SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
btnPtr->nRow = nRows;
x += cx;
if (btnPtr->fsState & TBSTATE_WRAP) {
nRows++;
y += (cy + SEPARATOR_HEIGHT);
x = infoPtr->nIndent;
}
infoPtr->nRows = nRows + 1;
/* --- end test --- */
#else
if (btnPtr->fsStyle & TBSTYLE_SEP) {
/* UNDOCUMENTED: If a separator has a non zero bitmap index, */
/* it is the actual width of the separator. This is used for */
/* custom controls in toolbars. */
if ((dwStyle & TBSTYLE_WRAPABLE) &&
(btnPtr->fsState & TBSTATE_WRAP)) {
x = 0;
y += cy;
cx = infoPtr->nWidth;
cy = ((btnPtr->iBitmap > 0) ?
btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
nRows++;
bWrap = TRUE;
}
else
cx = (btnPtr->iBitmap > 0) ?
btnPtr->iBitmap : SEPARATOR_WIDTH;
}
else {
/* this must be a button */
cx = infoPtr->nButtonWidth;
}
btnPtr->rect.left = x;
btnPtr->rect.top = y;
btnPtr->rect.right = x + cx;
btnPtr->rect.bottom = y + cy;
if (infoPtr->rcBound.left > x)
infoPtr->rcBound.left = x;
if (infoPtr->rcBound.right < x + cx)
infoPtr->rcBound.right = x + cx;
if (infoPtr->rcBound.bottom < y + cy)
infoPtr->rcBound.bottom = y + cy;
if (infoPtr->hwndToolTip) {
TTTOOLINFOA ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof(TTTOOLINFOA);
ti.hwnd = hwnd;
ti.uId = btnPtr->idCommand;
ti.rect = btnPtr->rect;
SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
0, (LPARAM)&ti);
}
if (bWrap) {
x = 0;
y += cy;
if (i < infoPtr->nNumButtons)
nRows++;
}
else
x += cx;
#endif
}
infoPtr->nHeight = y + cy + BOTTOM_BORDER;
TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
}
static INT
TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
INT i;
btnPtr = infoPtr->buttons;
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
if (btnPtr->fsState & TBSTATE_HIDDEN)
continue;
if (btnPtr->fsStyle & TBSTYLE_SEP) {
if (PtInRect (&btnPtr->rect, *lpPt)) {
TRACE (toolbar, " ON SEPARATOR %d!\n", i);
return -i;
}
}
else {
if (PtInRect (&btnPtr->rect, *lpPt)) {
TRACE (toolbar, " ON BUTTON %d!\n", i);
return i;
}
}
}
TRACE (toolbar, " NOWHERE!\n");
return -1;
}
static INT
TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
{
TBUTTON_INFO *btnPtr;
INT i;
btnPtr = infoPtr->buttons;
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
if (btnPtr->idCommand == idCommand) {
TRACE (toolbar, "command=%d index=%d\n", idCommand, i);
return i;
}
}
TRACE (toolbar, "no index found for command=%d\n", idCommand);
return -1;
}
static INT
TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
{
TBUTTON_INFO *btnPtr;
INT nRunIndex;
if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
return -1;
/* check index button */
btnPtr = &infoPtr->buttons[nIndex];
if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
if (btnPtr->fsState & TBSTATE_CHECKED)
return nIndex;
}
/* check previous buttons */
nRunIndex = nIndex - 1;
while (nRunIndex >= 0) {
btnPtr = &infoPtr->buttons[nRunIndex];
if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
if (btnPtr->fsState & TBSTATE_CHECKED)
return nRunIndex;
}
else
break;
nRunIndex--;
}
/* check next buttons */
nRunIndex = nIndex + 1;
while (nRunIndex < infoPtr->nNumButtons) {
btnPtr = &infoPtr->buttons[nRunIndex];
if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
if (btnPtr->fsState & TBSTATE_CHECKED)
return nRunIndex;
}
else
break;
nRunIndex++;
}
return -1;
}
static VOID
TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
MSG msg;
msg.hwnd = hwndMsg;
msg.message = uMsg;
msg.wParam = wParam;
msg.lParam = lParam;
msg.time = GetMessageTime ();
msg.pt.x = LOWORD(GetMessagePos ());
msg.pt.y = HIWORD(GetMessagePos ());
SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
}
static LRESULT
TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
INT nIndex = 0;
if ((!lpAddBmp) || ((INT)wParam <= 0))
return -1;
TRACE (toolbar, "adding %d bitmaps!\n", wParam);
if (!(infoPtr->himlDef)) {
/* create new default image list */
TRACE (toolbar, "creating default image list!\n");
infoPtr->himlStd =
ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
ILC_COLOR | ILC_MASK, (INT)wParam, 2);
}
#if 0
if (!(infoPtr->himlDis)) {
/* create new disabled image list */
TRACE (toolbar, "creating disabled image list!\n");
infoPtr->himlDis =
ImageList_Create (infoPtr->nBitmapWidth,
infoPtr->nBitmapHeight, ILC_COLOR | ILC_MASK,
(INT)wParam, 2);
}
#endif
/* Add bitmaps to the default image list */
if (lpAddBmp->hInst == (HINSTANCE)0) {
nIndex =
ImageList_AddMasked (infoPtr->himlStd, (HBITMAP)lpAddBmp->nID,
CLR_DEFAULT);
}
else if (lpAddBmp->hInst == HINST_COMMCTRL) {
/* add internal bitmaps */
FIXME (toolbar, "internal bitmaps not supported!\n");
/* Hack to "add" some reserved images within the image list
to get the right image indices */
nIndex = ImageList_GetImageCount (infoPtr->himlStd);
ImageList_SetImageCount (infoPtr->himlStd, nIndex + (INT)wParam);
}
else {
HBITMAP hBmp =
LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
nIndex = ImageList_AddMasked (infoPtr->himlStd, hBmp, CLR_DEFAULT);
DeleteObject (hBmp);
}
infoPtr->nNumBitmaps += (INT)wParam;
return nIndex;
}
static LRESULT
TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
INT nOldButtons, nNewButtons, nAddButtons, nCount;
HDC hdc;
TRACE (toolbar, "adding %d buttons!\n", wParam);
nAddButtons = (UINT)wParam;
nOldButtons = infoPtr->nNumButtons;
nNewButtons = nOldButtons + nAddButtons;
if (infoPtr->nNumButtons == 0) {
infoPtr->buttons =
COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
}
else {
TBUTTON_INFO *oldButtons = infoPtr->buttons;
infoPtr->buttons =
COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
memcpy (&infoPtr->buttons[0], &oldButtons[0],
nOldButtons * sizeof(TBUTTON_INFO));
COMCTL32_Free (oldButtons);
}
infoPtr->nNumButtons = nNewButtons;
/* insert new button data */
for (nCount = 0; nCount < nAddButtons; nCount++) {
TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
btnPtr->iBitmap = lpTbb[nCount].iBitmap;
btnPtr->idCommand = lpTbb[nCount].idCommand;
btnPtr->fsState = lpTbb[nCount].fsState;
btnPtr->fsStyle = lpTbb[nCount].fsStyle;
btnPtr->dwData = lpTbb[nCount].dwData;
btnPtr->iString = lpTbb[nCount].iString;
if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
TTTOOLINFOA ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof (TTTOOLINFOA);
ti.hwnd = hwnd;
ti.uId = btnPtr->idCommand;
ti.hinst = 0;
ti.lpszText = LPSTR_TEXTCALLBACKA;
SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
0, (LPARAM)&ti);
}
}
TOOLBAR_CalcToolbar (hwnd);
hdc = GetDC (hwnd);
TOOLBAR_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
/* << TOOLBAR_AddButtons32W >> */
static LRESULT
TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
if ((wParam) && (HIWORD(lParam) == 0)) {
char szString[256];
INT len;
TRACE (toolbar, "adding string from resource!\n");
len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
szString, 256);
TRACE (toolbar, "len=%d \"%s\"\n", len, szString);
nIndex = infoPtr->nNumStrings;
if (infoPtr->nNumStrings == 0) {
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR));
}
else {
LPWSTR *oldStrings = infoPtr->strings;
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
memcpy (&infoPtr->strings[0], &oldStrings[0],
sizeof(LPWSTR) * infoPtr->nNumStrings);
COMCTL32_Free (oldStrings);
}
infoPtr->strings[infoPtr->nNumStrings] =
COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
infoPtr->nNumStrings++;
}
else {
LPSTR p = (LPSTR)lParam;
INT len;
if (p == NULL)
return -1;
TRACE (toolbar, "adding string(s) from array!\n");
nIndex = infoPtr->nNumStrings;
while (*p) {
len = lstrlenA (p);
TRACE (toolbar, "len=%d \"%s\"\n", len, p);
if (infoPtr->nNumStrings == 0) {
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR));
}
else {
LPWSTR *oldStrings = infoPtr->strings;
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
memcpy (&infoPtr->strings[0], &oldStrings[0],
sizeof(LPWSTR) * infoPtr->nNumStrings);
COMCTL32_Free (oldStrings);
}
infoPtr->strings[infoPtr->nNumStrings] =
COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
infoPtr->nNumStrings++;
p += (len+1);
}
}
return nIndex;
}
static LRESULT
TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
if ((wParam) && (HIWORD(lParam) == 0)) {
WCHAR szString[256];
INT len;
TRACE (toolbar, "adding string from resource!\n");
len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
szString, 256);
TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(szString));
nIndex = infoPtr->nNumStrings;
if (infoPtr->nNumStrings == 0) {
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR));
}
else {
LPWSTR *oldStrings = infoPtr->strings;
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
memcpy (&infoPtr->strings[0], &oldStrings[0],
sizeof(LPWSTR) * infoPtr->nNumStrings);
COMCTL32_Free (oldStrings);
}
infoPtr->strings[infoPtr->nNumStrings] =
COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
infoPtr->nNumStrings++;
}
else {
LPWSTR p = (LPWSTR)lParam;
INT len;
if (p == NULL)
return -1;
TRACE (toolbar, "adding string(s) from array!\n");
nIndex = infoPtr->nNumStrings;
while (*p) {
len = lstrlenW (p);
TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(p));
if (infoPtr->nNumStrings == 0) {
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR));
}
else {
LPWSTR *oldStrings = infoPtr->strings;
infoPtr->strings =
COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
memcpy (&infoPtr->strings[0], &oldStrings[0],
sizeof(LPWSTR) * infoPtr->nNumStrings);
COMCTL32_Free (oldStrings);
}
infoPtr->strings[infoPtr->nNumStrings] =
COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
infoPtr->nNumStrings++;
p += (len+1);
}
}
return nIndex;
}
static LRESULT
TOOLBAR_AutoSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
RECT parent_rect;
HWND parent;
/* INT32 x, y; */
INT cx, cy;
UINT uPosFlags = 0;
TRACE (toolbar, "resize forced!\n");
parent = GetParent (hwnd);
GetClientRect(parent, &parent_rect);
if (dwStyle & CCS_NORESIZE) {
uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
cx = 0;
cy = 0;
}
else {
infoPtr->nWidth = parent_rect.right - parent_rect.left;
TOOLBAR_CalcToolbar (hwnd);
cy = infoPtr->nHeight;
cx = infoPtr->nWidth;
}
if (dwStyle & CCS_NOPARENTALIGN)
uPosFlags |= SWP_NOMOVE;
if (!(dwStyle & CCS_NODIVIDER))
cy += sysMetrics[SM_CYEDGE];
infoPtr->bAutoSize = TRUE;
SetWindowPos (hwnd, HWND_TOP, parent_rect.left, parent_rect.top,
cx, cy, uPosFlags);
return 0;
}
static LRESULT
TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
return infoPtr->nNumButtons;
}
static LRESULT
TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr == NULL) {
ERR (toolbar, "(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
ERR (toolbar, "infoPtr == NULL!\n");
return 0;
}
infoPtr->dwStructSize = (DWORD)wParam;
return 0;
}
static LRESULT
TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
HDC hdc;
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
btnPtr->iBitmap = LOWORD(lParam);
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
static LRESULT
TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
HDC hdc;
INT nIndex;
INT nOldIndex = -1;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
return FALSE;
if (LOWORD(lParam) == FALSE)
btnPtr->fsState &= ~TBSTATE_CHECKED;
else {
if (btnPtr->fsStyle & TBSTYLE_GROUP) {
nOldIndex =
TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
if (nOldIndex == nIndex)
return 0;
if (nOldIndex != -1)
infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
}
btnPtr->fsState |= TBSTATE_CHECKED;
}
hdc = GetDC (hwnd);
if (nOldIndex != -1)
TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
/* FIXME: Send a WM_NOTIFY?? */
return TRUE;
}
static LRESULT
TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
}
static LRESULT
TOOLBAR_Customize (HWND hwnd)
{
FIXME (toolbar, "customization not implemented!\n");
return 0;
}
static LRESULT
TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex = (INT)wParam;
if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
return FALSE;
if ((infoPtr->hwndToolTip) &&
!(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
TTTOOLINFOA ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof (TTTOOLINFOA);
ti.hwnd = hwnd;
ti.uId = infoPtr->buttons[nIndex].idCommand;
SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
}
if (infoPtr->nNumButtons == 1) {
TRACE (toolbar, " simple delete!\n");
COMCTL32_Free (infoPtr->buttons);
infoPtr->buttons = NULL;
infoPtr->nNumButtons = 0;
}
else {
TBUTTON_INFO *oldButtons = infoPtr->buttons;
TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex);
infoPtr->nNumButtons--;
infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
if (nIndex > 0) {
memcpy (&infoPtr->buttons[0], &oldButtons[0],
nIndex * sizeof(TBUTTON_INFO));
}
if (nIndex < infoPtr->nNumButtons) {
memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
(infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
}
COMCTL32_Free (oldButtons);
}
TOOLBAR_CalcToolbar (hwnd);
InvalidateRect (hwnd, NULL, TRUE);
UpdateWindow (hwnd);
return TRUE;
}
static LRESULT
TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
HDC hdc;
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
if (LOWORD(lParam) == FALSE)
btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
else
btnPtr->fsState |= TBSTATE_ENABLED;
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
/* << TOOLBAR_GetAnchorHighlight >> */
static LRESULT
TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return -1;
return infoPtr->buttons[nIndex].iBitmap;
}
static __inline__ LRESULT
TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
}
static LRESULT
TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
INT nIndex = (INT)wParam;
TBUTTON_INFO *btnPtr;
if (infoPtr == NULL)
return FALSE;
if (lpTbb == NULL)
return FALSE;
if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
lpTbb->iBitmap = btnPtr->iBitmap;
lpTbb->idCommand = btnPtr->idCommand;
lpTbb->fsState = btnPtr->fsState;
lpTbb->fsStyle = btnPtr->fsStyle;
lpTbb->dwData = btnPtr->dwData;
lpTbb->iString = btnPtr->iString;
return TRUE;
}
static LRESULT
TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
TBUTTON_INFO *btnPtr;
INT nIndex;
if (infoPtr == NULL)
return -1;
if (lpTbInfo == NULL)
return -1;
if (lpTbInfo->cbSize < sizeof(LPTBBUTTONINFOA))
return -1;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return -1;
btnPtr = &infoPtr->buttons[nIndex];
if (lpTbInfo->dwMask & TBIF_COMMAND)
lpTbInfo->idCommand = btnPtr->idCommand;
if (lpTbInfo->dwMask & TBIF_IMAGE)
lpTbInfo->iImage = btnPtr->iBitmap;
if (lpTbInfo->dwMask & TBIF_LPARAM)
lpTbInfo->lParam = btnPtr->dwData;
if (lpTbInfo->dwMask & TBIF_SIZE)
lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
if (lpTbInfo->dwMask & TBIF_STATE)
lpTbInfo->fsState = btnPtr->fsState;
if (lpTbInfo->dwMask & TBIF_STYLE)
lpTbInfo->fsStyle = btnPtr->fsStyle;
if (lpTbInfo->dwMask & TBIF_TEXT) {
if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
lstrcpynA (lpTbInfo->pszText,
(LPSTR)infoPtr->strings[btnPtr->iString],
lpTbInfo->cchText);
}
return nIndex;
}
/* << TOOLBAR_GetButtonInfo32W >> */
static LRESULT
TOOLBAR_GetButtonSize (HWND hwnd)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
return MAKELONG((WORD)infoPtr->nButtonWidth,
(WORD)infoPtr->nButtonHeight);
}
static LRESULT
TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex, nStringIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return -1;
nStringIndex = infoPtr->buttons[nIndex].iString;
TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
return -1;
if (lParam == 0) return -1;
lstrcpyA ((LPSTR)lParam, (LPSTR)infoPtr->strings[nStringIndex]);
return lstrlenA ((LPSTR)infoPtr->strings[nStringIndex]);
}
/* << TOOLBAR_GetButtonText32W >> */
/* << TOOLBAR_GetColorScheme >> */
static LRESULT
TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
return (LRESULT)infoPtr->himlDis;
else
return 0;
}
__inline__ static LRESULT
TOOLBAR_GetExtendedStyle (HWND hwnd)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
return infoPtr->dwExStyle;
}
static LRESULT
TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
return (LRESULT)infoPtr->himlHot;
else
return 0;
}
/* << TOOLBAR_GetHotItem >> */
static LRESULT
TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
return (LRESULT)infoPtr->himlDef;
else
return 0;
}
/* << TOOLBAR_GetInsertMark >> */
/* << TOOLBAR_GetInsertMarkColor >> */
static LRESULT
TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
LPRECT lpRect;
INT nIndex;
if (infoPtr == NULL)
return FALSE;
nIndex = (INT)wParam;
btnPtr = &infoPtr->buttons[nIndex];
if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
return FALSE;
lpRect = (LPRECT)lParam;
if (lpRect == NULL)
return FALSE;
if (btnPtr->fsState & TBSTATE_HIDDEN)
return FALSE;
lpRect->left = btnPtr->rect.left;
lpRect->right = btnPtr->rect.right;
lpRect->bottom = btnPtr->rect.bottom;
lpRect->top = btnPtr->rect.top;
return TRUE;
}
static LRESULT
TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPSIZE lpSize = (LPSIZE)lParam;
if (lpSize == NULL)
return FALSE;
lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
TRACE (toolbar, "maximum size %d x %d\n",
infoPtr->rcBound.right - infoPtr->rcBound.left,
infoPtr->rcBound.bottom - infoPtr->rcBound.top);
return TRUE;
}
/* << TOOLBAR_GetObject >> */
/* << TOOLBAR_GetPadding >> */
static LRESULT
TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
LPRECT lpRect;
INT nIndex;
if (infoPtr == NULL)
return FALSE;
nIndex = (INT)wParam;
btnPtr = &infoPtr->buttons[nIndex];
if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
return FALSE;
lpRect = (LPRECT)lParam;
if (lpRect == NULL)
return FALSE;
lpRect->left = btnPtr->rect.left;
lpRect->right = btnPtr->rect.right;
lpRect->bottom = btnPtr->rect.bottom;
lpRect->top = btnPtr->rect.top;
return TRUE;
}
static LRESULT
TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
return infoPtr->nRows;
else
return 1;
}
static LRESULT
TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return -1;
return infoPtr->buttons[nIndex].fsState;
}
static LRESULT
TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return -1;
return infoPtr->buttons[nIndex].fsStyle;
}
static LRESULT
TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr == NULL)
return 0;
return infoPtr->nMaxTextRows;
}
static LRESULT
TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr == NULL)
return 0;
return infoPtr->hwndToolTip;
}
static LRESULT
TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TRACE (toolbar, "%s hwnd=0x%x stub!\n",
infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
return infoPtr->bUnicode;
}
static LRESULT
TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
if (LOWORD(lParam) == FALSE)
btnPtr->fsState &= ~TBSTATE_HIDDEN;
else
btnPtr->fsState |= TBSTATE_HIDDEN;
TOOLBAR_CalcToolbar (hwnd);
InvalidateRect (hwnd, NULL, TRUE);
UpdateWindow (hwnd);
return TRUE;
}
__inline__ static LRESULT
TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
}
static LRESULT
TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
HDC hdc;
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
if (LOWORD(lParam) == FALSE)
btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
else
btnPtr->fsState |= TBSTATE_INDETERMINATE;
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
static LRESULT
TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
INT nIndex = (INT)wParam;
TBUTTON_INFO *oldButtons;
HDC hdc;
if (lpTbb == NULL)
return FALSE;
if (nIndex < 0)
return FALSE;
TRACE (toolbar, "inserting button index=%d\n", nIndex);
if (nIndex > infoPtr->nNumButtons) {
nIndex = infoPtr->nNumButtons;
TRACE (toolbar, "adjust index=%d\n", nIndex);
}
oldButtons = infoPtr->buttons;
infoPtr->nNumButtons++;
infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
/* pre insert copy */
if (nIndex > 0) {
memcpy (&infoPtr->buttons[0], &oldButtons[0],
nIndex * sizeof(TBUTTON_INFO));
}
/* insert new button */
infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
infoPtr->buttons[nIndex].iString = lpTbb->iString;
if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
TTTOOLINFOA ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof (TTTOOLINFOA);
ti.hwnd = hwnd;
ti.uId = lpTbb->idCommand;
ti.hinst = 0;
ti.lpszText = LPSTR_TEXTCALLBACKA;
SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
0, (LPARAM)&ti);
}
/* post insert copy */
if (nIndex < infoPtr->nNumButtons - 1) {
memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
(infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
}
COMCTL32_Free (oldButtons);
TOOLBAR_CalcToolbar (hwnd);
hdc = GetDC (hwnd);
TOOLBAR_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
/* << TOOLBAR_InsertButton32W >> */
/* << TOOLBAR_InsertMarkHitTest >> */
static LRESULT
TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
}
static LRESULT
TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
}
static LRESULT
TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
}
static LRESULT
TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
}
static LRESULT
TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
}
static LRESULT
TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
}
/* << TOOLBAR_LoadImages >> */
/* << TOOLBAR_MapAccelerator >> */
/* << TOOLBAR_MarkButton >> */
/* << TOOLBAR_MoveButton >> */
static LRESULT
TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
HDC hdc;
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
if (LOWORD(lParam) == FALSE)
btnPtr->fsState &= ~TBSTATE_PRESSED;
else
btnPtr->fsState |= TBSTATE_PRESSED;
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
/* << TOOLBAR_ReplaceBitmap >> */
static LRESULT
TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
#if 0
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
if (lpSave == NULL) return 0;
if ((BOOL)wParam) {
/* save toolbar information */
FIXME (toolbar, "save to \"%s\" \"%s\"\n",
lpSave->pszSubKey, lpSave->pszValueName);
}
else {
/* restore toolbar information */
FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
lpSave->pszSubKey, lpSave->pszValueName);
}
#endif
return 0;
}
/* << TOOLBAR_SaveRestore32W >> */
/* << TOOLBAR_SetAnchorHighlight >> */
static LRESULT
TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
return FALSE;
infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
return TRUE;
}
static LRESULT
TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
TBUTTON_INFO *btnPtr;
INT nIndex;
if (lptbbi == NULL)
return FALSE;
if (lptbbi->cbSize < sizeof(LPTBBUTTONINFOA))
return FALSE;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
if (lptbbi->dwMask & TBIF_COMMAND)
btnPtr->idCommand = lptbbi->idCommand;
if (lptbbi->dwMask & TBIF_IMAGE)
btnPtr->iBitmap = lptbbi->iImage;
if (lptbbi->dwMask & TBIF_LPARAM)
btnPtr->dwData = lptbbi->lParam;
/* if (lptbbi->dwMask & TBIF_SIZE) */
/* btnPtr->cx = lptbbi->cx; */
if (lptbbi->dwMask & TBIF_STATE)
btnPtr->fsState = lptbbi->fsState;
if (lptbbi->dwMask & TBIF_STYLE)
btnPtr->fsStyle = lptbbi->fsStyle;
if (lptbbi->dwMask & TBIF_TEXT) {
if ((btnPtr->iString >= 0) ||
(btnPtr->iString < infoPtr->nNumStrings)) {
#if 0
CHAR **lpString = &infoPtr->strings[btnPtr->iString];
INT len = lstrlenA (lptbbi->pszText);
*lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
#endif
/* this is the ultimate sollution */
/* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
}
}
return TRUE;
}
/* << TOOLBAR_SetButtonInfo32W >> */
static LRESULT
TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
return FALSE;
infoPtr->nButtonWidth = (INT)LOWORD(lParam);
infoPtr->nButtonHeight = (INT)HIWORD(lParam);
return TRUE;
}
static LRESULT
TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr == NULL)
return FALSE;
infoPtr->cxMin = (INT)LOWORD(lParam);
infoPtr->cxMax = (INT)HIWORD(lParam);
return TRUE;
}
static LRESULT
TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex = (INT)wParam;
if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
return FALSE;
infoPtr->buttons[nIndex].idCommand = (INT)lParam;
if (infoPtr->hwndToolTip) {
FIXME (toolbar, "change tool tip!\n");
}
return TRUE;
}
/* << TOOLBAR_SetColorScheme >> */
static LRESULT
TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
HIMAGELIST himlTemp;
if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
return 0;
himlTemp = infoPtr->himlDis;
infoPtr->himlDis = (HIMAGELIST)lParam;
/* FIXME: redraw ? */
return (LRESULT)himlTemp;
}
static LRESULT
TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
DWORD dwTemp;
dwTemp = infoPtr->dwDTFlags;
infoPtr->dwDTFlags =
(infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
return (LRESULT)dwTemp;
}
static LRESULT
TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
DWORD dwTemp;
dwTemp = infoPtr->dwExStyle;
infoPtr->dwExStyle = (DWORD)lParam;
return (LRESULT)dwTemp;
}
static LRESULT
TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
HIMAGELIST himlTemp;
if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
return 0;
himlTemp = infoPtr->himlHot;
infoPtr->himlHot = (HIMAGELIST)lParam;
/* FIXME: redraw ? */
return (LRESULT)himlTemp;
}
/* << TOOLBAR_SetHotItem >> */
static LRESULT
TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
HIMAGELIST himlTemp;
if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
return 0;
himlTemp = infoPtr->himlDef;
infoPtr->himlDef = (HIMAGELIST)lParam;
/* FIXME: redraw ? */
return (LRESULT)himlTemp;
}
static LRESULT
TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
HDC hdc;
infoPtr->nIndent = (INT)wParam;
TOOLBAR_CalcToolbar (hwnd);
hdc = GetDC (hwnd);
TOOLBAR_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
/* << TOOLBAR_SetInsertMark >> */
static LRESULT
TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
infoPtr->clrInsertMark = (COLORREF)lParam;
/* FIXME : redraw ??*/
return 0;
}
static LRESULT
TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr == NULL)
return FALSE;
infoPtr->nMaxTextRows = (INT)wParam;
return TRUE;
}
/* << TOOLBAR_SetPadding >> */
static LRESULT
TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
HWND hwndOldNotify;
if (infoPtr == NULL)
return 0;
hwndOldNotify = infoPtr->hwndNotify;
infoPtr->hwndNotify = (HWND)wParam;
return hwndOldNotify;
}
static LRESULT
TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPRECT lprc = (LPRECT)lParam;
HDC hdc;
if (LOWORD(wParam) > 1) {
FIXME (toolbar, "multiple rows not supported!\n");
}
/* recalculate toolbar */
TOOLBAR_CalcToolbar (hwnd);
/* return bounding rectangle */
if (lprc) {
lprc->left = infoPtr->rcBound.left;
lprc->right = infoPtr->rcBound.right;
lprc->top = infoPtr->rcBound.top;
lprc->bottom = infoPtr->rcBound.bottom;
}
/* repaint toolbar */
hdc = GetDC (hwnd);
TOOLBAR_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
return 0;
}
static LRESULT
TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
HDC hdc;
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
btnPtr->fsState = LOWORD(lParam);
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
return TRUE;
}
static LRESULT
TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
HDC hdc;
INT nIndex;
nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
if (nIndex == -1)
return FALSE;
btnPtr = &infoPtr->buttons[nIndex];
btnPtr->fsStyle = LOWORD(lParam);
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
if (infoPtr->hwndToolTip) {
FIXME (toolbar, "change tool tip!\n");
}
return TRUE;
}
__inline__ static LRESULT
TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr == NULL)
return 0;
infoPtr->hwndToolTip = (HWND)wParam;
return 0;
}
static LRESULT
TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
BOOL bTemp;
TRACE (toolbar, "%s hwnd=0x%04x stub!\n",
((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
bTemp = infoPtr->bUnicode;
infoPtr->bUnicode = (BOOL)wParam;
return bTemp;
}
static LRESULT
TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
LOGFONTA logFont;
/* initialize info structure */
infoPtr->nButtonHeight = 22;
infoPtr->nButtonWidth = 23;
infoPtr->nBitmapHeight = 15;
infoPtr->nBitmapWidth = 16;
infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
infoPtr->nRows = 1;
infoPtr->nMaxTextRows = 1;
infoPtr->cxMin = -1;
infoPtr->cxMax = -1;
infoPtr->bCaptured = FALSE;
infoPtr->bUnicode = IsWindowUnicode (hwnd);
infoPtr->nButtonDown = -1;
infoPtr->nOldHit = -1;
infoPtr->hwndNotify = GetParent (hwnd);
infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
infoPtr->nHotItem = -1;
infoPtr->dwDTFlags = DT_CENTER;
SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
infoPtr->hFont = CreateFontIndirectA (&logFont);
if (dwStyle & TBSTYLE_TOOLTIPS) {
/* Create tooltip control */
infoPtr->hwndToolTip =
CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hwnd, 0, 0, 0);
/* Send NM_TOOLTIPSCREATED notification */
if (infoPtr->hwndToolTip) {
NMTOOLTIPSCREATED nmttc;
nmttc.hdr.hwndFrom = hwnd;
nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
nmttc.hdr.code = NM_TOOLTIPSCREATED;
nmttc.hwndToolTips = infoPtr->hwndToolTip;
SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
}
}
return 0;
}
static LRESULT
TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
/* delete tooltip control */
if (infoPtr->hwndToolTip)
DestroyWindow (infoPtr->hwndToolTip);
/* delete button data */
if (infoPtr->buttons)
COMCTL32_Free (infoPtr->buttons);
/* delete strings */
if (infoPtr->strings) {
INT i;
for (i = 0; i < infoPtr->nNumStrings; i++)
if (infoPtr->strings[i])
COMCTL32_Free (infoPtr->strings[i]);
COMCTL32_Free (infoPtr->strings);
}
/* destroy default image list */
if (infoPtr->himlDef)
ImageList_Destroy (infoPtr->himlDef);
/* destroy disabled image list */
if (infoPtr->himlDis)
ImageList_Destroy (infoPtr->himlDis);
/* destroy hot image list */
if (infoPtr->himlHot)
ImageList_Destroy (infoPtr->himlHot);
/* delete default font */
if (infoPtr->hFont)
DeleteObject (infoPtr->hFont);
/* free toolbar info data */
COMCTL32_Free (infoPtr);
return 0;
}
static LRESULT
TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr->bTransparent)
return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
}
static LRESULT
TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
POINT pt;
INT nHit;
HDC hdc;
pt.x = (INT)LOWORD(lParam);
pt.y = (INT)HIWORD(lParam);
nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
if (nHit >= 0) {
btnPtr = &infoPtr->buttons[nHit];
if (!(btnPtr->fsState & TBSTATE_ENABLED))
return 0;
SetCapture (hwnd);
infoPtr->bCaptured = TRUE;
infoPtr->nButtonDown = nHit;
btnPtr->fsState |= TBSTATE_PRESSED;
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
}
else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
TOOLBAR_Customize (hwnd);
return 0;
}
static LRESULT
TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
POINT pt;
INT nHit;
HDC hdc;
if (infoPtr->hwndToolTip)
TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
WM_LBUTTONDOWN, wParam, lParam);
pt.x = (INT)LOWORD(lParam);
pt.y = (INT)HIWORD(lParam);
nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
if (nHit >= 0) {
btnPtr = &infoPtr->buttons[nHit];
if (!(btnPtr->fsState & TBSTATE_ENABLED))
return 0;
SetCapture (hwnd);
infoPtr->bCaptured = TRUE;
infoPtr->nButtonDown = nHit;
infoPtr->nOldHit = nHit;
btnPtr->fsState |= TBSTATE_PRESSED;
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
}
return 0;
}
static LRESULT
TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
POINT pt;
INT nHit;
INT nOldIndex = -1;
HDC hdc;
BOOL bSendMessage = TRUE;
if (infoPtr->hwndToolTip)
TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
WM_LBUTTONUP, wParam, lParam);
pt.x = (INT)LOWORD(lParam);
pt.y = (INT)HIWORD(lParam);
nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
infoPtr->bCaptured = FALSE;
ReleaseCapture ();
btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
btnPtr->fsState &= ~TBSTATE_PRESSED;
if (nHit == infoPtr->nButtonDown) {
if (btnPtr->fsStyle & TBSTYLE_CHECK) {
if (btnPtr->fsStyle & TBSTYLE_GROUP) {
nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
infoPtr->nButtonDown);
if (nOldIndex == infoPtr->nButtonDown)
bSendMessage = FALSE;
if ((nOldIndex != infoPtr->nButtonDown) &&
(nOldIndex != -1))
infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
btnPtr->fsState |= TBSTATE_CHECKED;
}
else {
if (btnPtr->fsState & TBSTATE_CHECKED)
btnPtr->fsState &= ~TBSTATE_CHECKED;
else
btnPtr->fsState |= TBSTATE_CHECKED;
}
}
}
else
bSendMessage = FALSE;
hdc = GetDC (hwnd);
if (nOldIndex != -1)
TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
if (bSendMessage)
SendMessageA (infoPtr->hwndNotify, WM_COMMAND,
MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
infoPtr->nButtonDown = -1;
infoPtr->nOldHit = -1;
}
return 0;
}
static LRESULT
TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TBUTTON_INFO *btnPtr;
POINT pt;
INT nHit;
HDC hdc;
if (infoPtr->hwndToolTip)
TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
WM_MOUSEMOVE, wParam, lParam);
pt.x = (INT)LOWORD(lParam);
pt.y = (INT)HIWORD(lParam);
nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
if (infoPtr->bCaptured) {
if (infoPtr->nOldHit != nHit) {
btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
if (infoPtr->nOldHit == infoPtr->nButtonDown) {
btnPtr->fsState &= ~TBSTATE_PRESSED;
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
}
else if (nHit == infoPtr->nButtonDown) {
btnPtr->fsState |= TBSTATE_PRESSED;
hdc = GetDC (hwnd);
TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
ReleaseDC (hwnd, hdc);
}
}
infoPtr->nOldHit = nHit;
}
return 0;
}
__inline__ static LRESULT
TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/* if (wndPtr->dwStyle & CCS_NODIVIDER) */
return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
/* else */
/* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
}
__inline__ static LRESULT
TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
((LPRECT)lParam)->top += sysMetrics[SM_CYEDGE];
return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
}
static LRESULT
TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr;
/* allocate memory for info structure */
infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
/* paranoid!! */
infoPtr->dwStructSize = sizeof(TBBUTTON);
/* fix instance handle, if the toolbar was created by CreateToolbarEx() */
if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
}
return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
}
static LRESULT
TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
RECT rcWindow;
HDC hdc;
if (dwStyle & WS_MINIMIZE)
return 0; /* Nothing to do */
DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
return 0;
if (!(dwStyle & CCS_NODIVIDER))
{
GetWindowRect (hwnd, &rcWindow);
OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
}
ReleaseDC( hwnd, hdc );
return 0;
}
__inline__ static LRESULT
TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPNMHDR lpnmh = (LPNMHDR)lParam;
TRACE (toolbar, "passing WM_NOTIFY!\n");
if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
#if 0
if (lpnmh->code == TTN_GETDISPINFOA) {
LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
FIXME (toolbar, "retrieving ASCII string\n");
}
else if (lpnmh->code == TTN_GETDISPINFOW) {
LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
FIXME (toolbar, "retrieving UNICODE string\n");
}
#endif
}
return 0;
}
static LRESULT
TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
TOOLBAR_Refresh (hwnd, hdc);
if (!wParam)
EndPaint (hwnd, &ps);
return 0;
}
static LRESULT
TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
RECT parent_rect;
HWND parent;
/* INT32 x, y; */
INT cx, cy;
INT flags;
UINT uPosFlags = 0;
/* Resize deadlock check */
if (infoPtr->bAutoSize) {
infoPtr->bAutoSize = FALSE;
return 0;
}
flags = (INT) wParam;
/* FIXME for flags =
* SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
*/
TRACE (toolbar, "sizing toolbar!\n");
if (flags == SIZE_RESTORED) {
/* width and height don't apply */
parent = GetParent (hwnd);
GetClientRect(parent, &parent_rect);
if (dwStyle & CCS_NORESIZE) {
uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
/* FIXME */
/* infoPtr->nWidth = parent_rect.right - parent_rect.left; */
cy = infoPtr->nHeight;
cx = infoPtr->nWidth;
TOOLBAR_CalcToolbar (hwnd);
infoPtr->nWidth = cx;
infoPtr->nHeight = cy;
}
else {
infoPtr->nWidth = parent_rect.right - parent_rect.left;
TOOLBAR_CalcToolbar (hwnd);
cy = infoPtr->nHeight;
cx = infoPtr->nWidth;
}
if (dwStyle & CCS_NOPARENTALIGN) {
uPosFlags |= SWP_NOMOVE;
cy = infoPtr->nHeight;
cx = infoPtr->nWidth;
}
if (!(dwStyle & CCS_NODIVIDER))
cy += sysMetrics[SM_CYEDGE];
SetWindowPos (hwnd, 0, parent_rect.left, parent_rect.top,
cx, cy, uPosFlags | SWP_NOZORDER);
}
return 0;
}
static LRESULT
TOOLBAR_StyleChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
TOOLBAR_AutoSize (hwnd, wParam, lParam);
hdc = GetDC (hwnd);
TOOLBAR_Refresh (hwnd, hdc);
ReleaseDC (hwnd, hdc);
return 0;
}
LRESULT WINAPI
ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case TB_ADDBITMAP:
return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
case TB_ADDBUTTONSA:
return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
/* case TB_ADDBUTTONS32W: */
case TB_ADDSTRINGA:
return TOOLBAR_AddStringA (hwnd, wParam, lParam);
case TB_ADDSTRINGW:
return TOOLBAR_AddStringW (hwnd, wParam, lParam);
case TB_AUTOSIZE:
return TOOLBAR_AutoSize (hwnd, wParam, lParam);
case TB_BUTTONCOUNT:
return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
case TB_BUTTONSTRUCTSIZE:
return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
case TB_CHANGEBITMAP:
return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
case TB_CHECKBUTTON:
return TOOLBAR_CheckButton (hwnd, wParam, lParam);
case TB_COMMANDTOINDEX:
return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
case TB_CUSTOMIZE:
return TOOLBAR_Customize (hwnd);
case TB_DELETEBUTTON:
return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
case TB_ENABLEBUTTON:
return TOOLBAR_EnableButton (hwnd, wParam, lParam);
/* case TB_GETANCHORHIGHLIGHT: */ /* 4.71 */
case TB_GETBITMAP:
return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
case TB_GETBITMAPFLAGS:
return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
case TB_GETBUTTON:
return TOOLBAR_GetButton (hwnd, wParam, lParam);
case TB_GETBUTTONINFOA:
return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
/* case TB_GETBUTTONINFO32W: */ /* 4.71 */
case TB_GETBUTTONSIZE:
return TOOLBAR_GetButtonSize (hwnd);
case TB_GETBUTTONTEXTA:
return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
/* case TB_GETBUTTONTEXT32W: */
/* case TB_GETCOLORSCHEME: */ /* 4.71 */
case TB_GETDISABLEDIMAGELIST:
return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
case TB_GETEXTENDEDSTYLE:
return TOOLBAR_GetExtendedStyle (hwnd);
case TB_GETHOTIMAGELIST:
return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
/* case TB_GETHOTITEM: */ /* 4.71 */
case TB_GETIMAGELIST:
return TOOLBAR_GetImageList (hwnd, wParam, lParam);
/* case TB_GETINSERTMARK: */ /* 4.71 */
/* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
case TB_GETITEMRECT:
return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
case TB_GETMAXSIZE:
return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
/* case TB_GETOBJECT: */ /* 4.71 */
/* case TB_GETPADDING: */ /* 4.71 */
case TB_GETRECT:
return TOOLBAR_GetRect (hwnd, wParam, lParam);
case TB_GETROWS:
return TOOLBAR_GetRows (hwnd, wParam, lParam);
case TB_GETSTATE:
return TOOLBAR_GetState (hwnd, wParam, lParam);
case TB_GETSTYLE:
return TOOLBAR_GetStyle (hwnd, wParam, lParam);
case TB_GETTEXTROWS:
return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
case TB_GETTOOLTIPS:
return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
case TB_GETUNICODEFORMAT:
return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
case TB_HIDEBUTTON:
return TOOLBAR_HideButton (hwnd, wParam, lParam);
case TB_HITTEST:
return TOOLBAR_HitTest (hwnd, wParam, lParam);
case TB_INDETERMINATE:
return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
case TB_INSERTBUTTONA:
return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
/* case TB_INSERTBUTTON32W: */
/* case TB_INSERTMARKHITTEST: */ /* 4.71 */
case TB_ISBUTTONCHECKED:
return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
case TB_ISBUTTONENABLED:
return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
case TB_ISBUTTONHIDDEN:
return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
case TB_ISBUTTONHIGHLIGHTED:
return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
case TB_ISBUTTONINDETERMINATE:
return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
case TB_ISBUTTONPRESSED:
return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
/* case TB_LOADIMAGES: */ /* 4.70 */
/* case TB_MAPACCELERATOR32A: */ /* 4.71 */
/* case TB_MAPACCELERATOR32W: */ /* 4.71 */
/* case TB_MARKBUTTON: */ /* 4.71 */
/* case TB_MOVEBUTTON: */ /* 4.71 */
case TB_PRESSBUTTON:
return TOOLBAR_PressButton (hwnd, wParam, lParam);
/* case TB_REPLACEBITMAP: */
case TB_SAVERESTOREA:
return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
/* case TB_SAVERESTORE32W: */
/* case TB_SETANCHORHIGHLIGHT: */ /* 4.71 */
case TB_SETBITMAPSIZE:
return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
case TB_SETBUTTONINFOA:
return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
/* case TB_SETBUTTONINFO32W: */ /* 4.71 */
case TB_SETBUTTONSIZE:
return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
case TB_SETBUTTONWIDTH:
return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
case TB_SETCMDID:
return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
/* case TB_SETCOLORSCHEME: */ /* 4.71 */
case TB_SETDISABLEDIMAGELIST:
return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
case TB_SETDRAWTEXTFLAGS:
return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
case TB_SETEXTENDEDSTYLE:
return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
case TB_SETHOTIMAGELIST:
return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
/* case TB_SETHOTITEM: */ /* 4.71 */
case TB_SETIMAGELIST:
return TOOLBAR_SetImageList (hwnd, wParam, lParam);
case TB_SETINDENT:
return TOOLBAR_SetIndent (hwnd, wParam, lParam);
/* case TB_SETINSERTMARK: */ /* 4.71 */
case TB_SETINSERTMARKCOLOR:
return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
case TB_SETMAXTEXTROWS:
return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
/* case TB_SETPADDING: */ /* 4.71 */
case TB_SETPARENT:
return TOOLBAR_SetParent (hwnd, wParam, lParam);
case TB_SETROWS:
return TOOLBAR_SetRows (hwnd, wParam, lParam);
case TB_SETSTATE:
return TOOLBAR_SetState (hwnd, wParam, lParam);
case TB_SETSTYLE:
return TOOLBAR_SetStyle (hwnd, wParam, lParam);
case TB_SETTOOLTIPS:
return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
case TB_SETUNICODEFORMAT:
return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
/* case WM_CHAR: */
case WM_CREATE:
return TOOLBAR_Create (hwnd, wParam, lParam);
case WM_DESTROY:
return TOOLBAR_Destroy (hwnd, wParam, lParam);
case WM_ERASEBKGND:
return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
/* case WM_GETFONT: */
/* case WM_KEYDOWN: */
/* case WM_KILLFOCUS: */
case WM_LBUTTONDBLCLK:
return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
case WM_LBUTTONDOWN:
return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
case WM_LBUTTONUP:
return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
case WM_MOUSEMOVE:
return TOOLBAR_MouseMove (hwnd, wParam, lParam);
case WM_NCACTIVATE:
return TOOLBAR_NCActivate (hwnd, wParam, lParam);
case WM_NCCALCSIZE:
return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
case WM_NCCREATE:
return TOOLBAR_NCCreate (hwnd, wParam, lParam);
case WM_NCPAINT:
return TOOLBAR_NCPaint (hwnd, wParam, lParam);
case WM_NOTIFY:
return TOOLBAR_Notify (hwnd, wParam, lParam);
/* case WM_NOTIFYFORMAT: */
case WM_PAINT:
return TOOLBAR_Paint (hwnd, wParam);
case WM_SIZE:
return TOOLBAR_Size (hwnd, wParam, lParam);
case WM_STYLECHANGED:
return TOOLBAR_StyleChanged (hwnd, wParam, lParam);
/* case WM_SYSCOLORCHANGE: */
/* case WM_WININICHANGE: */
case WM_CHARTOITEM:
case WM_COMMAND:
case WM_DRAWITEM:
case WM_MEASUREITEM:
case WM_VKEYTOITEM:
return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
default:
if (uMsg >= WM_USER)
ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
uMsg, wParam, lParam);
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
}
return 0;
}
VOID
TOOLBAR_Register (VOID)
{
WNDCLASSA wndClass;
if (GlobalFindAtomA (TOOLBARCLASSNAMEA)) return;
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wndClass.lpszClassName = TOOLBARCLASSNAMEA;
RegisterClassA (&wndClass);
}
VOID
TOOLBAR_Unregister (VOID)
{
if (GlobalFindAtomA (TOOLBARCLASSNAMEA))
UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);
}