mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-02 17:46:50 -05:00
3572 lines
No EOL
96 KiB
C++
3572 lines
No EOL
96 KiB
C++
#include "main.h"
|
|
#include "./toolbar.h"
|
|
#include "./graphics.h"
|
|
#include "./resource.h"
|
|
#include "./toolbarItem.h"
|
|
#include "./toolbarStatic.h"
|
|
#include "./toolbarButton.h"
|
|
#include "./toolbarRating.h"
|
|
#include "./toolbarProgress.h"
|
|
#include "./toolbarAddress.h"
|
|
#include "../winamp/wa_dlg.h"
|
|
#include "../Plugins/General/gen_ml/ml_ipc_0313.h"
|
|
#include "./ifc_imageloader.h"
|
|
#include "./ifc_skinhelper.h"
|
|
#include "./ifc_omservice.h"
|
|
#include "./ifc_omservicecommand.h"
|
|
#include "./menu.h"
|
|
#include "./ifc_wasabihelper.h"
|
|
|
|
#include "./browserUiCommon.h"
|
|
|
|
|
|
#include <windows.h>
|
|
#include <shlwapi.h>
|
|
#include <commctrl.h>
|
|
#include <strsafe.h>
|
|
#include <vector>
|
|
|
|
#define TOOLBAR_SPACE_LEFT 0
|
|
#define TOOLBAR_SPACE_TOP 4
|
|
#define TOOLBAR_SPACE_RIGHT 1
|
|
#define TOOLBAR_SPACE_BOTTOM 3
|
|
|
|
#define TOOLBAR_HIDDENHEIGHT 3
|
|
|
|
#define TOOLBAR_ICONSTATE_NORMAL 0
|
|
#define TOOLBAR_ICONSTATE_HIGHLIGHTED 1
|
|
#define TOOLBAR_ICONSTATE_PRESSED 2
|
|
#define TOOLBAR_ICONSTATE_DISABLED 3
|
|
#define TOOLBAR_ICONSTATE_COUNT 4
|
|
|
|
#define TBS_MENULOOP 0x00000001
|
|
#define TBS_HIDDEN 0x00000002
|
|
#define TBS_HIDETIMERSET 0x00000004
|
|
#define TBS_NOFOCUSRECT 0x00000008
|
|
|
|
#define ICON_NONE (-1)
|
|
#define ICON_CHEVRON (-2) // - resolved on the fly
|
|
#define ICON_SEPARATOR 0
|
|
#define ICON_CHEVRON_BOTTOM 1
|
|
#define ICON_CHEVRON_TOP 2
|
|
#define ICON_BACK 3
|
|
#define ICON_FORWARD 4
|
|
#define ICON_REFRESH 5
|
|
#define ICON_STOP 6
|
|
#define ICON_HOME 7
|
|
#define ICON_ERROR 8
|
|
#define ICON_LOCK 9
|
|
#define ICON_HISTORY 10
|
|
#define ICON_ADDRESSBAR 11
|
|
|
|
#define ICON_SEPARATOR_WIDTH 6
|
|
#define ICON_CHEVRON_WIDTH 13
|
|
#define ICON_HISTORY_WIDTH 9
|
|
#define ICON_ARROW_WIDTH 17
|
|
|
|
#define TOOLBRUSH_BACK 0
|
|
#define TOOLBRUSH_FRAME 1
|
|
#define TOOLBRUSH_ITEMBK 2
|
|
#define TOOLBRUSH_LAST TOOLBRUSH_ITEMBK
|
|
|
|
#define ID_CHEVRON_CLICKED 1
|
|
|
|
#define TOOLBAR_BKCOLOR WADLG_LISTHEADER_BGCOLOR
|
|
#define TOOLBAR_FGCOLOR WADLG_LISTHEADER_FONTCOLOR
|
|
|
|
#define EDIT_ALPHA 50
|
|
#define TEXT_ALPHA 127
|
|
#define HIGHLIGHT_ALPHA 160
|
|
#define TIMER_AUTOHIDE_ID 14
|
|
#define TIMER_AUTOHIDE_DELAY 300
|
|
|
|
#define AUTOHIDE_ANIMATETIME 200
|
|
|
|
typedef std::vector<ToolbarItem*> ItemList;
|
|
|
|
typedef struct __TOOLBAR
|
|
{
|
|
UINT ref;
|
|
UINT flags;
|
|
HBRUSH szBrushes[TOOLBRUSH_LAST + 1];
|
|
HIMAGELIST imageList;
|
|
HFONT textFont;
|
|
ItemList *items;
|
|
ToolbarItem *chevron;
|
|
ToolbarItem *pressed;
|
|
ToolbarItem *highlighted;
|
|
UINT resolveCache;
|
|
HFONT ownedFont;
|
|
HWND hTooltip;
|
|
COLORREF rgbBk;
|
|
COLORREF rgbFg;
|
|
COLORREF rgbText;
|
|
COLORREF rgbHilite;
|
|
COLORREF rgbFrame;
|
|
COLORREF rgbEdit;
|
|
COLORREF rgbEditBk;
|
|
size_t iFocused;
|
|
HWND hBrowser;
|
|
TOOLBARTEXTMETRIC textMetric;
|
|
} TOOLBAR;
|
|
|
|
typedef struct __TOOLBARMOUSEHOOK
|
|
{
|
|
HHOOK hHook;
|
|
HWND hwnd;
|
|
} TOOLBARMOUSEHOOK;
|
|
|
|
static size_t tlsIndex = TLS_OUT_OF_INDEXES;
|
|
|
|
typedef ToolbarItem *(CALLBACK *TOOLBARITEMFACTORY)(ToolbarItem::Template * /*itemTemplate*/);
|
|
|
|
typedef struct __TOOLBARITEMCLASS
|
|
{
|
|
LPCSTR name;
|
|
TOOLBARITEMFACTORY creator;
|
|
LPCWSTR text;
|
|
LPCWSTR description;
|
|
INT iconId;
|
|
INT commandId;
|
|
UINT style;
|
|
} TOOLBARITEMCLASS;
|
|
|
|
#define REGISTER_ITEM(__name, __creator, __textId, __descriptionId, __iconId, __commandId, __style)\
|
|
{ (__name), (__creator), MAKEINTRESOURCE(__textId),\
|
|
MAKEINTRESOURCE(__descriptionId), (__iconId), (__commandId), (__style) }
|
|
|
|
#define REGISTER_STATIC(__name, __textId, __descriptionId, __iconId, __style)\
|
|
REGISTER_ITEM(__name, ToolbarStatic::CreateInstance, __textId, __descriptionId, __iconId, 0, __style)
|
|
|
|
#define REGISTER_BUTTON(__name, __textId, __descriptionId, __iconId, __commandId, __style)\
|
|
REGISTER_ITEM(__name, ToolbarButton::CreateInstance, __textId, __descriptionId, __iconId, __commandId, __style)
|
|
|
|
#define REGISTER_RATING(__name, __textId, __descriptionId, __style)\
|
|
REGISTER_ITEM(__name, ToolbarRating::CreateInstance, __textId, __descriptionId, ICON_NONE, 0, __style)
|
|
|
|
#define REGISTER_PROGRESS(__name, __textId, __descriptionId, __style)\
|
|
REGISTER_ITEM(__name, ToolbarProgress::CreateInstance, __textId, __descriptionId, ICON_NONE, 0, __style)
|
|
|
|
#define REGISTER_ADDRESSBAR(__name, __style)\
|
|
REGISTER_ITEM(__name, ToolbarAddress::CreateInstance, NULL, NULL, ICON_NONE, 0, __style)
|
|
|
|
const static TOOLBARITEMCLASS szRegisteredToolItems[] =
|
|
{
|
|
REGISTER_STATIC(TOOLITEM_SEPARATOR, IDS_SEPARATOR, 0, ICON_SEPARATOR, ToolbarStatic::styleSeparator),
|
|
REGISTER_STATIC(TOOLITEM_SPACE, IDS_SPACE, 0, ICON_NONE, ToolbarStatic::styleSpacer),
|
|
REGISTER_STATIC(TOOLITEM_FLEXSPACE, IDS_FLEXSPACE, 0, ICON_NONE, ToolbarStatic::styleSpacer | ToolbarItem::styleFlexible),
|
|
REGISTER_RATING(TOOLITEM_USERRATING, IDS_RATED, NULL, ToolbarItem::styleWantKey),
|
|
REGISTER_PROGRESS(TOOLITEM_DOWNLOADPROGRESS, NULL, NULL, ToolbarItem::stateDisabled),
|
|
REGISTER_ADDRESSBAR(TOOLITEM_ADDRESSBAR, ToolbarItem::styleFlexible | ToolbarItem::styleWantKey | ToolbarItem::styleTabstop),
|
|
|
|
REGISTER_BUTTON(TOOLITEM_CHEVRON, IDS_MORE, IDS_MORE_DESCRIPTION, ICON_CHEVRON,
|
|
ID_CHEVRON_CLICKED, ToolbarItem::styleWantKey),
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_HOME, IDS_HOME, IDS_HOME_DESCRIPTION, ICON_HOME,
|
|
ID_NAVIGATION_HOME, ToolbarItem::styleWantKey),
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_BACK, IDS_BACK, IDS_BACK_DESCRIPTION, ICON_BACK,
|
|
ID_NAVIGATION_BACK, ToolbarItem::styleWantKey),
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_FORWARD, IDS_FORWARD, IDS_FORWARD_DESCRIPTION, ICON_FORWARD,
|
|
ID_NAVIGATION_FORWARD, ToolbarItem::styleWantKey),
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_STOP, IDS_STOP, IDS_STOP_DESCRIPTION, ICON_STOP,
|
|
ID_NAVIGATION_STOP, ToolbarItem::styleWantKey),
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_REFRESH, IDS_REFRESH, IDS_REFRESH_DESCRIPTION, ICON_REFRESH,
|
|
ID_NAVIGATION_REFRESH, ToolbarItem::styleWantKey),
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_HISTORY, IDS_HISTORY, IDS_HISTORY_DESCRIPTION, ICON_HISTORY,
|
|
ID_NAVIGATION_HISTORY, ToolbarItem::styleWantKey),
|
|
|
|
REGISTER_BUTTON(TOOLITEM_CMDLINK_INFO, IDS_SERVICE_GETINFO, IDS_SERVICE_GETINFO_DESCRIPTION, ICON_NONE,
|
|
ID_SERVICE_GETINFO, ToolbarItem::styleWantKey | ToolbarButton::styleCommandLink),
|
|
REGISTER_BUTTON(TOOLITEM_CMDLINK_REPORT, IDS_SERVICE_REPORT, IDS_SERVICE_REPORT_DESCRIPTION, ICON_NONE,
|
|
ID_SERVICE_REPORT, ToolbarItem::styleWantKey | ToolbarButton::styleCommandLink),
|
|
REGISTER_BUTTON(TOOLITEM_CMDLINK_UNSUBSCRIBE, IDS_SERVICE_UNSUBSCRIBE, IDS_SERVICE_UNSUBSCRIBE_DESCRIPTION, ICON_NONE,
|
|
ID_SERVICE_UNSUBSCRIBE, ToolbarItem::styleWantKey | ToolbarButton::styleCommandLink),
|
|
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_SECURECONNECTION, IDS_SECURE_CONNECTION, IDS_SECURE_CONNECTION, ICON_LOCK,
|
|
ID_BROWSER_SECURECONNECTION, ToolbarItem::styleWantKey),
|
|
|
|
REGISTER_BUTTON(TOOLITEM_BUTTON_SCRIPTERROR, IDS_SCRIPT_ERROR, IDS_SCRIPT_ERROR_DESCRIPTION, ICON_ERROR,
|
|
ID_BROWSER_SCRIPTERROR, ToolbarItem::styleWantKey),
|
|
|
|
|
|
|
|
};
|
|
|
|
#define GetToolbar(__hwnd) ((TOOLBAR*)(LONG_PTR)(LONGX86)GetWindowLongPtr((__hwnd), 0))
|
|
static LRESULT CALLBACK Toolbar_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
static LRESULT CALLBACK Toolbar_MouseHook(INT code, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
|
typedef struct __TOOLBARITEMINSERTREC
|
|
{
|
|
LPCSTR name;
|
|
UINT style;
|
|
} TOOLBARITEMINSERTREC;
|
|
|
|
BOOL Toolbar_RegisterClass(HINSTANCE hInstance)
|
|
{
|
|
WNDCLASS wc;
|
|
ATOM klassAtom;
|
|
ifc_wasabihelper *wasabi;
|
|
|
|
if (GetClassInfo(hInstance, NWC_ONLINEMEDIATOOLBAR, &wc))
|
|
return TRUE;
|
|
|
|
ZeroMemory(&wc, sizeof(WNDCLASS));
|
|
|
|
wc.hInstance = hInstance;
|
|
wc.lpszClassName = NWC_ONLINEMEDIATOOLBAR;
|
|
wc.lpfnWndProc = Toolbar_WindowProc;
|
|
wc.style = 0;
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = NULL;
|
|
wc.cbWndExtra = sizeof(TOOLBAR*);
|
|
|
|
klassAtom = RegisterClassW(&wc);
|
|
if (0 == klassAtom)
|
|
return FALSE;
|
|
|
|
if (SUCCEEDED(Plugin_GetWasabiHelper(&wasabi)))
|
|
{
|
|
api_application *application;
|
|
if (SUCCEEDED(wasabi->GetApplicationApi(&application)))
|
|
{
|
|
application->DirectMouseWheel_RegisterSkipClass(klassAtom);
|
|
application->Release();
|
|
}
|
|
wasabi->Release();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL Toolbar_ClearItems(TOOLBAR *toolbar)
|
|
{
|
|
if (NULL == toolbar) return FALSE;
|
|
if (NULL == toolbar->items) return TRUE;
|
|
|
|
size_t index = toolbar->items->size();
|
|
|
|
while(index--)
|
|
{
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL != item) item->Release();
|
|
}
|
|
toolbar->items->clear();
|
|
return TRUE;
|
|
|
|
}
|
|
static ULONG Toolbar_AddRef(TOOLBAR *toolbar)
|
|
{
|
|
if (NULL == toolbar) return 0;
|
|
return InterlockedIncrement((LONG*)&toolbar->ref);
|
|
}
|
|
|
|
static ULONG Toolbar_Release(TOOLBAR *toolbar)
|
|
{
|
|
if (0 == toolbar || 0 == toolbar->ref) return 0;
|
|
LONG r = InterlockedDecrement((LONG*)&toolbar->ref);
|
|
if (0 == r)
|
|
{
|
|
if (NULL != toolbar->hTooltip)
|
|
DestroyWindow(toolbar->hTooltip);
|
|
|
|
if (NULL != toolbar->chevron)
|
|
toolbar->chevron->Release();
|
|
|
|
if (NULL != toolbar->items)
|
|
{
|
|
Toolbar_ClearItems(toolbar);
|
|
delete(toolbar->items);
|
|
}
|
|
|
|
if (NULL != toolbar->imageList)
|
|
ImageList_Destroy(toolbar->imageList);
|
|
|
|
if (NULL != toolbar->ownedFont)
|
|
DeleteObject(toolbar->ownedFont);
|
|
|
|
|
|
free(toolbar);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
static const TOOLBARITEMCLASS *Toolbar_FindClass(LPCSTR pszName)
|
|
{
|
|
if (NULL == pszName) return NULL;
|
|
|
|
for (INT i =0; i < ARRAYSIZE(szRegisteredToolItems); i++)
|
|
{
|
|
if (CSTR_EQUAL == CompareStringA(CSTR_INVARIANT, NORM_IGNORECASE,
|
|
szRegisteredToolItems[i].name, -1, pszName, -1))
|
|
{
|
|
return &szRegisteredToolItems[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static ToolbarItem* Toolbar_CreateItem(LPCSTR pszName, UINT styleOverride)
|
|
{
|
|
const TOOLBARITEMCLASS *iClass = Toolbar_FindClass(pszName);
|
|
if (NULL == iClass || NULL == iClass->creator)
|
|
return NULL;
|
|
|
|
ToolbarItem::Template iTemplate;
|
|
ZeroMemory(&iTemplate, sizeof(ToolbarItem::Template));
|
|
|
|
iTemplate.name = iClass->name;
|
|
iTemplate.text = iClass->text;
|
|
iTemplate.description= iClass->description;
|
|
iTemplate.iconId = iClass->iconId;
|
|
iTemplate.commandId = iClass->commandId;
|
|
iTemplate.style = iClass->style | styleOverride;
|
|
return iClass->creator(&iTemplate);
|
|
}
|
|
|
|
static BOOL Toolbar_GetClientRect(HWND hwnd, RECT *prc)
|
|
{
|
|
if (!GetClientRect(hwnd, prc))
|
|
return FALSE;
|
|
prc->left += TOOLBAR_SPACE_LEFT;
|
|
prc->right -= TOOLBAR_SPACE_RIGHT;
|
|
|
|
if (0 != (TBS_BOTTOMDOCK & GetWindowLongPtr(hwnd, GWL_STYLE)))
|
|
{
|
|
prc->top += TOOLBAR_SPACE_TOP;
|
|
prc->bottom -= TOOLBAR_SPACE_BOTTOM;
|
|
}
|
|
else
|
|
{
|
|
prc->top += TOOLBAR_SPACE_BOTTOM;
|
|
prc->bottom -= TOOLBAR_SPACE_TOP;
|
|
}
|
|
return TRUE;
|
|
}
|
|
static void Toolbar_UpdateColorTable(HWND hwnd, ifc_skinhelper *skinHelper)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
if (NULL == skinHelper || FAILED(skinHelper->GetColor(TOOLBAR_BKCOLOR, &toolbar->rgbBk)))
|
|
toolbar->rgbBk = GetSysColor(COLOR_WINDOW);
|
|
|
|
if (NULL == skinHelper || FAILED(skinHelper->GetColor(TOOLBAR_FGCOLOR, &toolbar->rgbFg)))
|
|
toolbar->rgbFg = GetSysColor(COLOR_WINDOWTEXT);
|
|
|
|
COLORREF rgbItemBk;
|
|
if (NULL == skinHelper || FAILED(skinHelper->GetColor(WADLG_ITEMBG, &rgbItemBk)))
|
|
rgbItemBk = GetSysColor(COLOR_WINDOW);
|
|
|
|
COLORREF rgbItem;
|
|
if (NULL == skinHelper || FAILED(skinHelper->GetColor(WADLG_ITEMFG, &rgbItem)))
|
|
rgbItem = GetSysColor(COLOR_WINDOWTEXT);
|
|
|
|
if (NULL != skinHelper)
|
|
{
|
|
const INT szFrameColors[] =
|
|
{
|
|
WADLG_HILITE,
|
|
WADLG_LISTHEADER_FRAME_MIDDLECOLOR,
|
|
WADLG_LISTHEADER_FRAME_BOTTOMCOLOR,
|
|
WADLG_LISTHEADER_FRAME_TOPCOLOR,
|
|
};
|
|
|
|
for (INT i = 0; i < ARRAYSIZE(szFrameColors); i++)
|
|
{
|
|
if (SUCCEEDED(skinHelper->GetColor(szFrameColors[i], &toolbar->rgbFrame)))
|
|
toolbar->rgbFrame = GetSysColor(COLOR_GRAYTEXT);
|
|
|
|
INT distance = GetColorDistance(toolbar->rgbFrame, rgbItemBk);
|
|
if (distance < 0) distance = -distance;
|
|
if (distance >= 40) break;
|
|
}
|
|
}
|
|
else
|
|
toolbar->rgbFrame = GetSysColor(COLOR_GRAYTEXT);
|
|
|
|
toolbar->rgbEdit = BlendColors(toolbar->rgbBk, rgbItem, EDIT_ALPHA);
|
|
toolbar->rgbEditBk = BlendColors(toolbar->rgbBk, rgbItemBk, EDIT_ALPHA);
|
|
toolbar->rgbText = BlendColors(toolbar->rgbFg, toolbar->rgbBk, TEXT_ALPHA);
|
|
toolbar->rgbHilite = BlendColors(toolbar->rgbFg, toolbar->rgbBk, HIGHLIGHT_ALPHA);
|
|
|
|
}
|
|
static void Toolbar_UpdateTextMetrics(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
ZeroMemory(&toolbar->textMetric, sizeof(TOOLBARTEXTMETRIC));
|
|
|
|
RECT clientRect;
|
|
if (!Toolbar_GetClientRect(hwnd, &clientRect))
|
|
return;
|
|
|
|
INT iconCX, iconCY;
|
|
if (NULL == toolbar->imageList ||
|
|
FALSE == ImageList_GetIconSize(toolbar->imageList, &iconCX, &iconCY))
|
|
{
|
|
iconCX = 0;
|
|
iconCY = 0;
|
|
}
|
|
else
|
|
{
|
|
iconCY = iconCY / TOOLBAR_ICONSTATE_COUNT;
|
|
}
|
|
|
|
|
|
HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
|
if (NULL == hdc) return;
|
|
|
|
HFONT originalFont = (HFONT)SelectObject(hdc, toolbar->textFont);
|
|
|
|
TEXTMETRIC tm;
|
|
if (GetTextMetrics(hdc, &tm))
|
|
{
|
|
toolbar->textMetric.height = tm.tmHeight;
|
|
toolbar->textMetric.aveCharWidth = tm.tmAveCharWidth;
|
|
toolbar->textMetric.overhang = tm.tmOverhang;
|
|
|
|
INT clientHeight = clientRect.bottom - clientRect.top;
|
|
if (tm.tmHeight >= iconCY)
|
|
{
|
|
toolbar->textMetric.baseY = tm.tmAscent - tm.tmInternalLeading;
|
|
INT t = clientHeight - toolbar->textMetric.baseY;
|
|
toolbar->textMetric.origY = clientRect.top + t/2;
|
|
if (0 != t%2)
|
|
{
|
|
toolbar->textMetric.origY += 1;
|
|
toolbar->textMetric.baseY += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
toolbar->textMetric.baseY = (clientHeight - iconCY)/2;
|
|
if (tm.tmDescent > toolbar->textMetric.baseY)
|
|
toolbar->textMetric.baseY = tm.tmDescent;
|
|
//toolbar->textMetric.baseY += 8;
|
|
toolbar->textMetric.baseY = clientHeight - toolbar->textMetric.baseY;
|
|
toolbar->textMetric.origY = (clientRect.top + toolbar->textMetric.baseY + tm.tmDescent) - tm.tmHeight;
|
|
toolbar->textMetric.baseY -= toolbar->textMetric.origY;
|
|
}
|
|
}
|
|
|
|
SelectObject(hdc, originalFont);
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
static HIMAGELIST Toolbar_LoadImagelist(TOOLBAR *toolbar, HINSTANCE hInstance, LPCWSTR pszPath, INT iconWidth, INT iconStatesCount)
|
|
{
|
|
if (iconWidth <= 0 || iconStatesCount <= 0 || NULL == pszPath)
|
|
return NULL;
|
|
|
|
HBITMAP bitmap = NULL;
|
|
|
|
ifc_omimageloader *loader;
|
|
if (SUCCEEDED(Plugin_QueryImageLoader(hInstance, pszPath, FALSE, &loader)))
|
|
{
|
|
loader->LoadBitmap(&bitmap, NULL, NULL);
|
|
loader->Release();
|
|
}
|
|
|
|
DIBSECTION dib;
|
|
if (NULL == bitmap ||
|
|
sizeof(DIBSECTION) != GetObject(bitmap, sizeof(DIBSECTION), &dib))
|
|
{
|
|
if (NULL != bitmap) DeleteObject(bitmap);
|
|
return NULL;
|
|
}
|
|
|
|
if (dib.dsBm.bmHeight < 0) dib.dsBm.bmHeight = -dib.dsBm.bmHeight;
|
|
|
|
Image_Colorize((BYTE*)dib.dsBm.bmBits, dib.dsBm.bmWidth, dib.dsBm.bmHeight, dib.dsBm.bmBitsPixel,
|
|
ColorAdjustLuma(toolbar->rgbBk, -140, TRUE), toolbar->rgbFg, FALSE);
|
|
|
|
Image_BlendOnColorEx((BYTE*)dib.dsBm.bmBits, dib.dsBm.bmWidth, dib.dsBm.bmHeight,
|
|
0, 0, dib.dsBm.bmWidth, dib.dsBm.bmHeight, dib.dsBm.bmBitsPixel, FALSE, toolbar->rgbBk);
|
|
|
|
|
|
if (iconWidth > dib.dsBm.bmWidth) iconWidth = dib.dsBm.bmWidth;
|
|
|
|
INT iconHeight = dib.dsBm.bmHeight / iconStatesCount;
|
|
INT initial = dib.dsBm.bmWidth / iconWidth;
|
|
|
|
HIMAGELIST himl = ImageList_Create(iconWidth, iconHeight * iconStatesCount, ILC_COLOR24, initial, 1);
|
|
if (NULL != himl)
|
|
{
|
|
INT index = ImageList_Add(himl, bitmap, NULL);
|
|
if (-1 == index)
|
|
{
|
|
ImageList_Destroy(himl);
|
|
himl = NULL;
|
|
}
|
|
}
|
|
DeleteObject(bitmap);
|
|
return himl;
|
|
}
|
|
|
|
static LONG Toolbar_ShowChevron(HWND hwnd, const RECT *prcClient) // return client cx change
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && NULL != toolbar->chevron && toolbar->chevron->IsRectEmpty())
|
|
{
|
|
RECT chevronRect;
|
|
CopyRect(&chevronRect, prcClient);
|
|
if (toolbar->chevron->AdjustRect(hwnd, &chevronRect))
|
|
{
|
|
chevronRect.left = prcClient->right - (chevronRect.right - chevronRect.left);
|
|
chevronRect.right = prcClient->right;
|
|
if (toolbar->chevron->SetRect(&chevronRect))
|
|
return (chevronRect.left - prcClient->right);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static ToolbarItem *Toolbar_GetItem(TOOLBAR *toolbar, size_t index)
|
|
{
|
|
if (NULL == toolbar || NULL == toolbar->items)
|
|
return NULL;
|
|
|
|
size_t count = toolbar->items->size();
|
|
|
|
if (index < count)
|
|
return toolbar->items->at(index);
|
|
if (index == count)
|
|
return toolbar->chevron;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static BOOL Toolbar_IsItemAcceptFocus(ToolbarItem *item, BOOL fTabstopOnly)
|
|
{
|
|
if (NULL == item)
|
|
return FALSE;
|
|
|
|
UINT itemStyle = item->GetStyle();
|
|
if (0 != ((ToolbarItem::stateDisabled | ToolbarItem::stateHidden) & itemStyle))
|
|
return FALSE;
|
|
|
|
UINT mask = ToolbarItem::styleTabstop;
|
|
if (FALSE == fTabstopOnly) mask |= ToolbarItem::styleWantKey;
|
|
if (0 == (mask & itemStyle))
|
|
return FALSE;
|
|
|
|
return (FALSE == item->IsRectEmpty());
|
|
}
|
|
|
|
static void Toolbar_UpdateTabstop(HWND hwnd)
|
|
{
|
|
BOOL fEnable = FALSE;
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
|
|
if (0 != (TBS_TABSTOP & windowStyle))
|
|
{
|
|
fEnable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && NULL != toolbar->items)
|
|
{
|
|
size_t index = toolbar->items->size();
|
|
while(index--)
|
|
{
|
|
if (FALSE != Toolbar_IsItemAcceptFocus(toolbar->items->at(index), TRUE))
|
|
{
|
|
fEnable = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FALSE != fEnable)
|
|
{
|
|
if (0 == (WS_TABSTOP & windowStyle))
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | WS_TABSTOP);
|
|
}
|
|
else
|
|
{
|
|
if (0 != (WS_TABSTOP & windowStyle))
|
|
{
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_TABSTOP);
|
|
}
|
|
}
|
|
}
|
|
static INT Toolbar_InsertItemInternal(TOOLBAR *toolbar, ToolbarItem *item, INT insertBefore, HWND hwnd)
|
|
{
|
|
if (NULL == toolbar || NULL == toolbar->items || NULL == item)
|
|
return ITEM_ERR;
|
|
|
|
INT index = ITEM_ERR;
|
|
|
|
if (TBIP_FIRST == insertBefore)
|
|
{
|
|
toolbar->items->insert(toolbar->items->begin(), item);
|
|
index = 0;
|
|
}
|
|
else if (TBIP_LAST == insertBefore)
|
|
{
|
|
toolbar->items->push_back(item);
|
|
index = ((INT)toolbar->items->size() - 1);
|
|
}
|
|
else
|
|
{
|
|
if (insertBefore < 0) insertBefore = 0;
|
|
else if (insertBefore >= (INT)toolbar->items->size()) insertBefore = (INT)toolbar->items->size();
|
|
toolbar->items->insert(toolbar->items->begin() + insertBefore, item);
|
|
index = insertBefore;
|
|
}
|
|
|
|
if (ITEM_ERR != index)
|
|
{
|
|
item->AddRef();
|
|
item->UpdateSkin(hwnd);
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
static size_t Toolbar_GetFocusIndex(HWND hwnd, size_t focusIndex, INT searchDirection, BOOL fTabstopOnly)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->items || 0 == toolbar->items->size())
|
|
return ((size_t)-1);
|
|
|
|
|
|
ToolbarItem *item = Toolbar_GetItem(toolbar, focusIndex);
|
|
if (NULL != item && Toolbar_IsItemAcceptFocus(item, fTabstopOnly))
|
|
return focusIndex;
|
|
|
|
if (0 == searchDirection)
|
|
return ((size_t)-1);
|
|
|
|
if (searchDirection > 0)
|
|
{
|
|
size_t count = toolbar->items->size();
|
|
size_t i = focusIndex + 1;
|
|
for (; i < count; i++)
|
|
{
|
|
if (Toolbar_IsItemAcceptFocus(toolbar->items->at(i), fTabstopOnly))
|
|
return i;
|
|
}
|
|
if (i == count && Toolbar_IsItemAcceptFocus(toolbar->chevron, fTabstopOnly))
|
|
return i;
|
|
}
|
|
else
|
|
{
|
|
size_t count = toolbar->items->size();
|
|
if (focusIndex == count && Toolbar_IsItemAcceptFocus(toolbar->chevron, fTabstopOnly))
|
|
return count;
|
|
|
|
size_t i = focusIndex;
|
|
if (i <= count)
|
|
{
|
|
while(i--)
|
|
{
|
|
if (Toolbar_IsItemAcceptFocus(toolbar->items->at(i), fTabstopOnly))
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ((size_t)-1);
|
|
}
|
|
|
|
static void Toolbar_OffsetItems(ToolbarItem **itemList, INT count, INT offsetX, INT offsetY)
|
|
{
|
|
while(count-- > 0)
|
|
{
|
|
if (NULL != itemList[count])
|
|
itemList[count]->OffsetRect(offsetX, offsetY);
|
|
}
|
|
}
|
|
static void Toolbar_HideItems(ToolbarItem **itemList, INT count, INT *chevronItemCount)
|
|
{
|
|
INT chevronItems = 0;
|
|
while(count-- > 0)
|
|
{
|
|
if (NULL != itemList[count])
|
|
{
|
|
if (0 == (ToolbarItem::styleNoChevron & itemList[count]->GetStyle()))
|
|
chevronItems++;
|
|
itemList[count]->SetRectEmpty();
|
|
}
|
|
}
|
|
|
|
if (NULL != chevronItemCount)
|
|
*chevronItemCount = chevronItems;
|
|
}
|
|
|
|
static LONG Toolbar_CutoffItems(ToolbarItem **itemList, INT count, LONG cutoffCX)
|
|
{
|
|
RECT elementRect;
|
|
LONG left = cutoffCX;
|
|
ToolbarItem *item;
|
|
while(count-- > 0)
|
|
{
|
|
item = itemList[count];
|
|
if (NULL == item)
|
|
continue;
|
|
|
|
DWORD style = item->GetStyle();
|
|
if (0 == (ToolbarItem::styleChevronOnly & style) &&
|
|
(0 == (ToolbarItem::stateHidden & style) || 0 == (ToolbarItem::stylePopup & style)) &&
|
|
item->GetRect(&elementRect))
|
|
{
|
|
if (elementRect.right <= cutoffCX)
|
|
return elementRect.right;
|
|
|
|
if (0 == count)
|
|
left = elementRect.left;
|
|
|
|
item->SetRectEmpty();
|
|
}
|
|
}
|
|
return left;
|
|
}
|
|
|
|
static LONG Toolbar_CalculateClient(HWND hwnd, ToolbarItem **itemList, INT count, const RECT *prcClient, INT *deltaCX)
|
|
{
|
|
ToolbarItem *item;
|
|
RECT elementRect;
|
|
INT index;
|
|
UINT style;
|
|
LONG elementLeft = prcClient->left;
|
|
|
|
for (index = 0; index < count; index++)
|
|
{
|
|
item = itemList[index];
|
|
if (NULL != item)
|
|
{
|
|
style = item->GetStyle();
|
|
if (0 != (ToolbarItem::styleChevronOnly & style) ||
|
|
(0 != (ToolbarItem::stateHidden & style) && 0!= (ToolbarItem::stylePopup & style)))
|
|
{
|
|
item->SetRectEmpty();
|
|
continue;
|
|
}
|
|
|
|
CopyRect(&elementRect, prcClient);
|
|
elementRect.left = elementLeft;
|
|
|
|
if (0 != (ToolbarItem::styleFlexible & style))
|
|
{
|
|
RECT testRect;
|
|
INT flexMinimum = 0;
|
|
SetRect(&testRect, elementRect.left, elementRect.top, elementRect.left, elementRect.bottom);
|
|
if (item->AdjustRect(hwnd, &testRect) && testRect.right > elementRect.left)
|
|
{
|
|
flexMinimum = (testRect.right - elementRect.left);
|
|
}
|
|
|
|
if (index != (count -1))
|
|
{
|
|
INT delta = 0;
|
|
INT section;
|
|
|
|
if ((elementRect.left + flexMinimum) < prcClient->right)
|
|
{
|
|
CopyRect(&testRect, &elementRect);
|
|
testRect.left += flexMinimum;
|
|
|
|
section = Toolbar_CalculateClient(hwnd, itemList + (index + 1),
|
|
count - index - 1, &testRect, &delta);
|
|
}
|
|
else
|
|
{
|
|
section = prcClient->right - (elementRect.left + flexMinimum);
|
|
}
|
|
|
|
if (section < 0)
|
|
{ // we need to move back
|
|
item->SetRectEmpty();
|
|
elementLeft += (flexMinimum - section);
|
|
if (index > 0)
|
|
elementLeft = Toolbar_CutoffItems(itemList, index, elementLeft);
|
|
return (elementLeft - prcClient->left);
|
|
}
|
|
|
|
if (NULL != deltaCX)
|
|
*deltaCX += delta;
|
|
|
|
elementRect.right = elementRect.right - section + delta;
|
|
if (elementRect.right < elementRect.left)
|
|
elementRect.right = elementRect.left;
|
|
}
|
|
|
|
if (item->AdjustRect(hwnd, &elementRect))
|
|
{
|
|
item->SetRect(&elementRect);
|
|
Toolbar_OffsetItems(itemList + (index + 1), count - index - 1, elementRect.right - elementRect.left - flexMinimum, 0);
|
|
elementLeft = prcClient->right;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (item->AdjustRect(hwnd, &elementRect))
|
|
{
|
|
if (elementRect.right > prcClient->right)
|
|
{
|
|
INT chevronItems;
|
|
Toolbar_HideItems(itemList + index, count - index, &chevronItems);
|
|
|
|
if (chevronItems > 0)
|
|
{
|
|
LONG delta = Toolbar_ShowChevron(hwnd, prcClient);
|
|
if (NULL != deltaCX) *deltaCX += delta;
|
|
elementLeft = (index > 0) ?
|
|
Toolbar_CutoffItems(itemList, index, prcClient->right + delta) :
|
|
(prcClient->left + delta);
|
|
}
|
|
break;
|
|
}
|
|
|
|
item->SetRect(&elementRect);
|
|
elementLeft += (elementRect.right - elementRect.left);
|
|
}
|
|
}
|
|
}
|
|
return (elementLeft - prcClient->left);
|
|
}
|
|
|
|
|
|
static void Toolbar_UpdateLayout(HWND hwnd, BOOL fRedraw)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (0 != (TBS_LOCKUPDATE & windowStyle)) return;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
RECT clientRect;
|
|
if (!Toolbar_GetClientRect(hwnd, &clientRect)) return;
|
|
|
|
Toolbar_UpdateTextMetrics(hwnd);
|
|
|
|
size_t count = (NULL != toolbar->items) ? toolbar->items->size() : 0;
|
|
|
|
if (NULL != toolbar->chevron)
|
|
{
|
|
INT chevronOnly = 0;
|
|
ToolbarItem *item;
|
|
for (size_t i = 0; i < count; i++)
|
|
{
|
|
item = toolbar->items->at(i);
|
|
UINT style = item->GetStyle();
|
|
|
|
if (NULL != item &&
|
|
0 != (ToolbarItem::styleChevronOnly & style) &&
|
|
0 == (ToolbarItem::stateHidden & style))
|
|
{
|
|
chevronOnly++;
|
|
}
|
|
}
|
|
|
|
toolbar->chevron->SetRectEmpty();
|
|
if (0 != chevronOnly)
|
|
clientRect.right += Toolbar_ShowChevron(hwnd, &clientRect);
|
|
}
|
|
|
|
|
|
Toolbar_CalculateClient(hwnd, toolbar->items->size() ? &toolbar->items->at(0) : nullptr, (INT)count, &clientRect, NULL);
|
|
|
|
if (((size_t)-1) != toolbar->iFocused)
|
|
{
|
|
size_t focusIndex = Toolbar_GetFocusIndex(hwnd, toolbar->iFocused, -1, FALSE);
|
|
if (focusIndex != toolbar->iFocused)
|
|
{
|
|
ToolbarItem *itemNew, *itemOld;
|
|
|
|
itemOld = Toolbar_GetItem(toolbar, toolbar->iFocused);
|
|
itemNew = Toolbar_GetItem(toolbar, focusIndex);
|
|
toolbar->iFocused = focusIndex;
|
|
|
|
if (NULL != itemOld)
|
|
itemOld->SetFocus(hwnd, itemNew, FALSE);
|
|
if (NULL != itemNew)
|
|
itemNew->SetFocus(hwnd, itemOld, TRUE);
|
|
}
|
|
}
|
|
|
|
if (FALSE != fRedraw)
|
|
{
|
|
RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_NOERASE);
|
|
}
|
|
}
|
|
|
|
static ToolbarItem *Toolbar_HitTest(HWND hwnd, POINT pt)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar)
|
|
{
|
|
ToolbarItem *item;
|
|
size_t count = (NULL != toolbar->items) ? toolbar->items->size() : 0;
|
|
for (size_t i = 0; i <= count; i++)
|
|
{
|
|
item = (i < count) ? toolbar->items->at(i) : toolbar->chevron;
|
|
|
|
if (NULL != item && item->PtInItem(pt))
|
|
return item;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
static HFONT Toolbar_CreateFont(HFONT skinFont)
|
|
{
|
|
LOGFONT lf;
|
|
if (NULL == skinFont) return NULL;
|
|
|
|
INT skinHeight = (sizeof(LOGFONT) == GetObject(skinFont, sizeof(LOGFONT), &lf)) ? lf.lfHeight : -11;
|
|
ZeroMemory(&lf, sizeof(LOGFONT));
|
|
|
|
lf.lfHeight = skinHeight;
|
|
lf.lfWeight = FW_DONTCARE;
|
|
lf.lfItalic = FALSE;
|
|
lf.lfUnderline = FALSE;
|
|
lf.lfStrikeOut = FALSE;
|
|
lf.lfCharSet = DEFAULT_CHARSET;
|
|
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
|
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
|
lf.lfQuality = DEFAULT_QUALITY;
|
|
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
|
StringCchCopy(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), L"MS Shell Dlg 2");
|
|
|
|
return CreateFontIndirect(&lf);
|
|
}
|
|
|
|
|
|
static HWND Toolbar_CreateTooltip(HINSTANCE hInstance, HWND hOwner)
|
|
{
|
|
HWND hTooltip = CreateWindowExW(WS_EX_TRANSPARENT , TOOLTIPS_CLASS, NULL,
|
|
WS_POPUP | TTS_ALWAYSTIP,
|
|
0, 0, 0, 0,
|
|
hOwner, NULL, hInstance, NULL);
|
|
|
|
if (NULL == hTooltip)
|
|
return NULL;
|
|
|
|
SetWindowPos(hTooltip, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
|
|
SendMessage(hTooltip, TTM_SETDELAYTIME, TTDT_INITIAL, MAKELPARAM(1000, 0));
|
|
SendMessage(hTooltip, TTM_SETDELAYTIME, TTDT_RESHOW, MAKELPARAM(-2, 0));
|
|
|
|
OSVERSIONINFO ov;
|
|
ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if (::GetVersionEx(&ov) &&
|
|
ov.dwMajorVersion >= 6 &&
|
|
VER_PLATFORM_WIN32_NT == ov.dwPlatformId)
|
|
{
|
|
RECT rcMargin;
|
|
SetRect(&rcMargin, 3, 1, 3, 1);
|
|
SendMessage(hTooltip, TTM_SETMARGIN, 0, (LPARAM)&rcMargin);
|
|
}
|
|
|
|
TOOLINFO ti;
|
|
ZeroMemory(&ti, sizeof(TOOLINFO));
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.hwnd = hOwner;
|
|
ti.lpszText = LPSTR_TEXTCALLBACK;
|
|
SendMessage(hTooltip, TTM_ADDTOOL, 0, (LPARAM)&ti);
|
|
|
|
SendMessage(hTooltip, TTM_SETMAXTIPWIDTH, 0, 1000);
|
|
|
|
return hTooltip;
|
|
}
|
|
static void Toolbar_RelayTooltipMsg(HWND hTooltip, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
MSG msg;
|
|
|
|
msg.hwnd = hwnd;
|
|
msg.message = uMsg;
|
|
msg.wParam = wParam;
|
|
msg.lParam = lParam;
|
|
|
|
//DWORD pts = GetMessagePos();
|
|
//POINTSTOPOINT(msg.pt, pts);
|
|
//msg.time = GetMessageTime();
|
|
|
|
SendMessage(hTooltip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
|
|
}
|
|
static void Toolbar_SetTooltipItem(HWND hwnd, ToolbarItem *item)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
TOOLINFO ti;
|
|
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.hwnd = hwnd;
|
|
ti.uId = 0;
|
|
ti.lpszText = NULL;
|
|
|
|
if (SendMessage(toolbar->hTooltip, TTM_GETTOOLINFO, 0, (LPARAM)&ti))
|
|
{
|
|
RECT clientRect, toolRect;
|
|
Toolbar_GetClientRect(hwnd, &clientRect);
|
|
|
|
if (NULL == item || FALSE == item->GetRect(&toolRect))
|
|
{
|
|
SendMessage(toolbar->hTooltip, TTM_ACTIVATE, FALSE, 0L);
|
|
return;
|
|
}
|
|
|
|
toolRect.top = clientRect.top;
|
|
toolRect.bottom = clientRect.bottom;
|
|
|
|
if (ti.lParam != (LPARAM)item || !::EqualRect(&ti.rect, &toolRect))
|
|
{
|
|
CopyRect(&ti.rect, &toolRect);
|
|
ti.lParam = (LPARAM)item;
|
|
SendMessage(toolbar->hTooltip, TTM_SETTOOLINFO, 0, (LPARAM)&ti);
|
|
}
|
|
SendMessage(toolbar->hTooltip, TTM_ACTIVATE, TRUE, 0L);
|
|
}
|
|
|
|
}
|
|
static void Toolbar_ClearBrushCache(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
for (INT i = 0; i < ARRAYSIZE(toolbar->szBrushes); i++)
|
|
{
|
|
if (NULL != toolbar->szBrushes[i])
|
|
{
|
|
DeleteObject(toolbar->szBrushes[i]);
|
|
toolbar->szBrushes[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static HBRUSH Toolbar_GetBrush(HWND hwnd, UINT brushId)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return NULL;
|
|
|
|
if (brushId >= ARRAYSIZE(toolbar->szBrushes))
|
|
return NULL;
|
|
|
|
if (NULL == toolbar->szBrushes[brushId])
|
|
{
|
|
COLORREF brushColor = 0x00FF00FF;
|
|
switch(brushId)
|
|
{
|
|
case TOOLBRUSH_BACK: brushColor = toolbar->rgbBk;break;
|
|
case TOOLBRUSH_FRAME: brushColor = toolbar->rgbFrame; break;
|
|
case TOOLBRUSH_ITEMBK: brushColor = toolbar->rgbEditBk; break;
|
|
}
|
|
toolbar->szBrushes[brushId] = CreateSolidBrush(brushColor);
|
|
}
|
|
return toolbar->szBrushes[brushId];
|
|
}
|
|
|
|
|
|
static HRGN Toolbar_GetFrameRgn(const RECT *prcToolbar, BOOL bottomDock)
|
|
{
|
|
if (TOOLBAR_SPACE_TOP < 1)
|
|
return NULL;
|
|
|
|
HRGN regionFrame;
|
|
INT origY = (FALSE != bottomDock) ? prcToolbar->top : prcToolbar->bottom - 1;
|
|
regionFrame = CreateRectRgn(prcToolbar->left, origY, prcToolbar->right, origY + 1);
|
|
return regionFrame;
|
|
}
|
|
|
|
static void Toolbar_PaintBack(HWND hwnd, HDC hdc, const RECT *prcToolbar, HRGN regionPaint)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
|
|
if (0 == (TBS_HIDDEN & toolbar->flags))
|
|
{
|
|
HRGN regionFrame = Toolbar_GetFrameRgn(prcToolbar, (0 != (TBS_BOTTOMDOCK & windowStyle)));
|
|
if (NULL != regionFrame)
|
|
{
|
|
if (FillRgn(hdc, regionFrame, Toolbar_GetBrush(hwnd, TOOLBRUSH_FRAME)))
|
|
CombineRgn(regionPaint, regionPaint, regionFrame, RGN_DIFF);
|
|
DeleteObject(regionFrame);
|
|
}
|
|
}
|
|
|
|
FillRgn(hdc, regionPaint, Toolbar_GetBrush(hwnd, TOOLBRUSH_BACK));
|
|
}
|
|
|
|
|
|
|
|
static void Toolbar_Paint(HWND hwnd, HDC hdc, const RECT *prcPaint, BOOL fErase)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
RECT clientRect;
|
|
GetClientRect(hwnd, &clientRect);
|
|
|
|
DWORD windowStyle = GetWindowStyle(hwnd);
|
|
|
|
HRGN paintRegion = CreateRectRgnIndirect(prcPaint);
|
|
|
|
if (0 == (TBS_HIDDEN & toolbar->flags))
|
|
{
|
|
INT savedDC = SaveDC(hdc);
|
|
|
|
HRGN itemRegion = CreateRectRgn(0,0,0,0);
|
|
|
|
SetBkColor(hdc, toolbar->rgbBk);
|
|
SetTextColor(hdc, toolbar->rgbText);
|
|
SelectObject(hdc, toolbar->textFont);
|
|
|
|
ToolbarItem *item;
|
|
RECT paintRect;
|
|
UINT style;
|
|
|
|
BOOL fFocused = (GetFocus() == hwnd);
|
|
UINT commonState= 0;
|
|
|
|
if (0 != (WS_DISABLED & windowStyle))
|
|
commonState |= ToolbarItem::stateDisabled;
|
|
|
|
size_t count = (NULL != toolbar->items) ? toolbar->items->size() : 0;
|
|
for (size_t i = 0; i <= count; i++)
|
|
{
|
|
item = (i < count) ? toolbar->items->at(i) : toolbar->chevron;
|
|
|
|
if (NULL != item && item->IntersectRect(&paintRect, prcPaint))
|
|
{
|
|
style = item->GetStyle() | commonState;
|
|
if (i == toolbar->iFocused && fFocused)
|
|
style |= ToolbarItem::stateFocused;
|
|
|
|
if (0 != (TBS_NOFOCUSRECT & toolbar->flags))
|
|
style |= ToolbarItem::stateNoFocusRect;
|
|
|
|
if (0 == (ToolbarItem::stateHidden & style) &&
|
|
item->Paint(hwnd, hdc, &paintRect, style))
|
|
{
|
|
SetRectRgn(itemRegion, paintRect.left, paintRect.top, paintRect.right, paintRect.bottom);
|
|
CombineRgn(paintRegion, paintRegion, itemRegion, RGN_DIFF);
|
|
}
|
|
}
|
|
}
|
|
DeleteObject(itemRegion);
|
|
RestoreDC(hdc, savedDC);
|
|
}
|
|
|
|
Toolbar_PaintBack(hwnd, hdc, &clientRect, paintRegion);
|
|
DeleteObject(paintRegion);
|
|
|
|
}
|
|
|
|
static INT Toolbar_FindListItem(ToolbarItem **itemList, INT start, INT count, LPCSTR pszName, INT cchName)
|
|
{
|
|
ToolbarItem *item;
|
|
for (INT i = start; i < count; i++)
|
|
{
|
|
item = itemList[i];
|
|
if (NULL != item && item->IsEqual(pszName, cchName))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
return ITEM_ERR;
|
|
}
|
|
static INT Toolbar_ResolveName(HWND hwnd, LPCSTR pszName)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->items)
|
|
return ITEM_ERR;
|
|
|
|
UINT index;
|
|
UINT count = (UINT)toolbar->items->size();
|
|
|
|
if (IS_INTRESOURCE(pszName))
|
|
{
|
|
index = (UINT)(UINT_PTR)pszName;
|
|
|
|
if (index == count && NULL != toolbar->chevron)
|
|
return index;
|
|
|
|
return (index < count) ? index : ITEM_ERR;
|
|
}
|
|
|
|
INT cchName = lstrlenA(pszName);
|
|
if (0 == cchName) return ITEM_ERR;
|
|
|
|
if (count == toolbar->resolveCache)
|
|
{
|
|
if (toolbar->chevron->IsEqual(pszName, cchName))
|
|
index = count;
|
|
else
|
|
{
|
|
index = ITEM_ERR;
|
|
toolbar->resolveCache = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
index = ITEM_ERR;
|
|
}
|
|
|
|
if (ITEM_ERR == index)
|
|
index = Toolbar_FindListItem(toolbar->items->size() ? & toolbar->items->at(0) : nullptr, toolbar->resolveCache, count, pszName, cchName);
|
|
|
|
if (ITEM_ERR == index && 0 != toolbar->resolveCache)
|
|
index = Toolbar_FindListItem(toolbar->items->size() ? &toolbar->items->at(0) : nullptr, 0, toolbar->resolveCache, pszName, cchName);
|
|
|
|
if (ITEM_ERR == index && NULL != toolbar->chevron && toolbar->chevron->IsEqual(pszName, cchName))
|
|
index = count;
|
|
|
|
|
|
toolbar->resolveCache = (ITEM_ERR != index) ? index : 0;
|
|
return index;
|
|
}
|
|
|
|
static BOOL Toolbar_DisplayChevronMenu(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->items) return FALSE;
|
|
|
|
HMENU hMenu = CreatePopupMenu();
|
|
if (NULL == hMenu) return FALSE;
|
|
|
|
size_t count = toolbar->items->size();
|
|
UINT insertedCount = 0;
|
|
MENUITEMINFO mi;
|
|
mi.cbSize = sizeof(MENUITEMINFO);
|
|
|
|
UINT style;
|
|
WCHAR szBuffer[80] = {0};
|
|
INT commandId = 0;
|
|
ToolbarItem *item;
|
|
BOOL insertBreak = FALSE;
|
|
for (size_t i = 0; i < count; i++)
|
|
{
|
|
item = toolbar->items->at(i);
|
|
if (NULL != item)
|
|
{
|
|
style = item->GetStyle();
|
|
if(0 == ((ToolbarItem::stateHidden | ToolbarItem::styleNoChevron) & style) &&
|
|
item->IsRectEmpty() &&
|
|
FALSE != item->FillMenuInfo(hwnd, &mi, szBuffer, ARRAYSIZE(szBuffer)))
|
|
{
|
|
if (MIIM_FTYPE == mi.fMask && MFT_MENUBREAK == mi.fType)
|
|
{
|
|
if (insertedCount > 0)
|
|
insertBreak = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (FALSE != InsertMenuItem(hMenu, insertedCount, TRUE, &mi))
|
|
{
|
|
if (insertBreak)
|
|
{
|
|
mi.fMask = MIIM_FTYPE;
|
|
mi.fType = MFT_MENUBREAK;
|
|
if (InsertMenuItem(hMenu, insertedCount, TRUE, &mi))
|
|
insertedCount++;
|
|
insertBreak = FALSE;
|
|
}
|
|
insertedCount++;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NULL != hMenu && insertedCount > 0)
|
|
{
|
|
RECT windowRect;
|
|
GetWindowRect(hwnd, &windowRect);
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
UINT menuStyle = TPM_RIGHTALIGN | TPM_RETURNCMD;
|
|
POINT menuOrig;
|
|
menuOrig.x = windowRect.right;
|
|
if (0 != (TBS_BOTTOMDOCK & windowStyle))
|
|
{
|
|
menuOrig.y = windowRect.top;
|
|
menuStyle |= (TPM_BOTTOMALIGN | TPM_VERNEGANIMATION);
|
|
}
|
|
else
|
|
{
|
|
menuOrig.y = windowRect.bottom;
|
|
menuStyle |= (TPM_TOPALIGN | TPM_VERPOSANIMATION);
|
|
}
|
|
|
|
commandId = Menu_TrackPopup(hMenu, menuStyle, menuOrig.x, menuOrig.y, hwnd, NULL);
|
|
|
|
|
|
}
|
|
|
|
DestroyMenu(hMenu);
|
|
|
|
if (0 != commandId)
|
|
Toolbar_SendCommand(hwnd, commandId);
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void Toolbar_DisplayContextMenu(HWND hwnd, INT x, INT y)
|
|
{
|
|
HMENU hMenu = Menu_GetMenu(MENU_TOOLBAR, 0);
|
|
if (NULL != hMenu)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
CheckMenuRadioItem(hMenu, ID_TOOLBAR_DOCKTOP, ID_TOOLBAR_DOCKBOTTOM,
|
|
(0 != (TBS_BOTTOMDOCK & windowStyle)) ? ID_TOOLBAR_DOCKBOTTOM :ID_TOOLBAR_DOCKTOP,
|
|
MF_BYCOMMAND);
|
|
|
|
CheckMenuItem(hMenu, ID_TOOLBAR_AUTOHIDE,
|
|
MF_BYCOMMAND | ((0 != (TBS_AUTOHIDE & windowStyle)) ? MF_CHECKED :MF_UNCHECKED));
|
|
|
|
CheckMenuItem(hMenu, ID_TOOLBAR_TABSTOP,
|
|
MF_BYCOMMAND | ((0 != (TBS_TABSTOP & windowStyle)) ? MF_CHECKED :MF_UNCHECKED));
|
|
|
|
Menu_TrackPopup(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN, x, y, hwnd, NULL);
|
|
|
|
Menu_ReleaseMenu(hMenu, MENU_TOOLBAR);
|
|
}
|
|
|
|
}
|
|
|
|
static BOOL Toolbar_InstallMouseHook(HWND hwnd)
|
|
{
|
|
if (TLS_OUT_OF_INDEXES == tlsIndex)
|
|
{
|
|
tlsIndex = Plugin_TlsAlloc();
|
|
if (TLS_OUT_OF_INDEXES == tlsIndex) return FALSE;
|
|
}
|
|
|
|
TOOLBARMOUSEHOOK *hook = (TOOLBARMOUSEHOOK*)calloc(1, sizeof(TOOLBARMOUSEHOOK));
|
|
if (NULL == hook) return FALSE;
|
|
|
|
hook->hwnd = hwnd;
|
|
hook->hHook = SetWindowsHookEx(WH_MOUSE, Toolbar_MouseHook, NULL, GetCurrentThreadId());
|
|
if (NULL == hook->hHook)
|
|
{
|
|
free(hook);
|
|
return FALSE;
|
|
}
|
|
|
|
Plugin_TlsSetValue(tlsIndex, hook);
|
|
return TRUE;
|
|
}
|
|
|
|
static void Toolbar_TrackMouseLeave(HWND hwnd)
|
|
{
|
|
TRACKMOUSEEVENT tm;
|
|
tm.cbSize = sizeof(TRACKMOUSEEVENT);
|
|
tm.dwFlags = TME_QUERY;
|
|
tm.hwndTrack = hwnd;
|
|
if (TrackMouseEvent(&tm) && 0 == (TME_LEAVE & tm.dwFlags))
|
|
{
|
|
tm.cbSize = sizeof(TRACKMOUSEEVENT);
|
|
tm.dwFlags = TME_LEAVE;
|
|
tm.hwndTrack = hwnd;
|
|
TrackMouseEvent(&tm);
|
|
}
|
|
}
|
|
|
|
static BOOL Toolbar_RemoveMouseHook(HWND hwnd, BOOL fOnlyMine)
|
|
{
|
|
if (TLS_OUT_OF_INDEXES == tlsIndex) return FALSE;
|
|
|
|
TOOLBARMOUSEHOOK *hook = (TOOLBARMOUSEHOOK*)Plugin_TlsGetValue(tlsIndex);
|
|
if (NULL == hook) return FALSE;
|
|
|
|
if (FALSE != fOnlyMine && hwnd != hook->hwnd)
|
|
return FALSE;
|
|
|
|
Plugin_TlsSetValue(tlsIndex, NULL);
|
|
|
|
if (NULL != hook->hHook)
|
|
UnhookWindowsHookEx(hook->hHook);
|
|
|
|
if (NULL != hook->hwnd && hwnd != hook->hwnd)
|
|
{
|
|
Toolbar_TrackMouseLeave(hook->hwnd);
|
|
}
|
|
|
|
free(hook);
|
|
return TRUE;
|
|
}
|
|
|
|
static void Toolbar_AutoShowWindow(HWND hwnd)
|
|
{
|
|
KillTimer(hwnd, TIMER_AUTOHIDE_ID);
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
HWND hFocus = GetFocus();
|
|
|
|
BOOL fFocused = (hFocus == hwnd);
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if ((TBS_AUTOHIDE | WS_VISIBLE) != ((TBS_AUTOHIDE | WS_VISIBLE) & windowStyle))
|
|
return;
|
|
|
|
if (0 == (TBS_HIDDEN & toolbar->flags))
|
|
{
|
|
if (0 != (TBS_HIDETIMERSET & toolbar->flags))
|
|
toolbar->flags &= ~TBS_HIDETIMERSET;
|
|
|
|
if (FALSE == fFocused)
|
|
Toolbar_TrackMouseLeave(hwnd);
|
|
return;
|
|
}
|
|
|
|
Toolbar_RemoveMouseHook(hwnd, FALSE);
|
|
|
|
if (FALSE == fFocused && FALSE == Toolbar_InstallMouseHook(hwnd))
|
|
return;
|
|
|
|
toolbar->flags &= ~TBS_HIDDEN;
|
|
|
|
RECT windowRect;
|
|
if (GetWindowRect(hwnd, &windowRect))
|
|
{
|
|
HWND hParent = GetParent(hwnd);
|
|
if(NULL != hParent)
|
|
{
|
|
MapWindowPoints(HWND_DESKTOP, hParent, (POINT*)&windowRect, 2);
|
|
INT height = Toolbar_GetIdealHeight(hwnd);
|
|
INT x = windowRect.left;
|
|
INT y = windowRect.top;
|
|
UINT swpFlags = SWP_NOMOVE | SWP_NOREDRAW;
|
|
UINT animateFlags = AW_SLIDE | AW_VER_POSITIVE;
|
|
|
|
if (0 != (TBS_BOTTOMDOCK & windowStyle))
|
|
{
|
|
y = windowRect.bottom - height;
|
|
swpFlags &= ~SWP_NOMOVE;
|
|
animateFlags = AW_SLIDE | AW_VER_NEGATIVE;
|
|
}
|
|
SetWindowPos(hwnd, HWND_TOP, x, y, windowRect.right - windowRect.left, height, swpFlags);
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
|
|
BOOL result = AnimateWindow(hwnd, AUTOHIDE_ANIMATETIME, animateFlags);
|
|
if (!result)
|
|
{
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | WS_VISIBLE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (FALSE == fFocused)
|
|
Toolbar_TrackMouseLeave(hwnd);
|
|
}
|
|
|
|
static void CALLBACK Toolbar_AutoHideTimerProc(HWND hwnd, UINT uMsg, UINT_PTR eventId, DWORD time)
|
|
{
|
|
KillTimer(hwnd, eventId);
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (0 == (TBS_AUTOHIDE & windowStyle)) return;
|
|
|
|
toolbar->flags &= ~TBS_HIDETIMERSET;
|
|
if (0 != ((TBS_HIDDEN | TBS_MENULOOP) & toolbar->flags))
|
|
return;
|
|
|
|
HWND hFocus = ::GetFocus();
|
|
if (hwnd == hFocus || IsChild(hwnd, hFocus))
|
|
return;
|
|
|
|
Toolbar_RemoveMouseHook(hwnd, TRUE);
|
|
RECT windowRect;
|
|
if (GetWindowRect(hwnd, &windowRect))
|
|
{
|
|
HWND hParent = GetParent(hwnd);
|
|
if(NULL != hParent)
|
|
{
|
|
MapWindowPoints(HWND_DESKTOP, hParent, (POINT*)&windowRect, 2);
|
|
INT height = TOOLBAR_HIDDENHEIGHT;
|
|
INT x = windowRect.left;
|
|
INT y = windowRect.top;
|
|
UINT swpFlags = SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW;
|
|
UINT animateFlags = AW_HIDE | AW_SLIDE | AW_VER_NEGATIVE;
|
|
HWND zOrder = HWND_TOP;
|
|
|
|
if (0 != (TBS_BOTTOMDOCK & windowStyle))
|
|
{
|
|
y = windowRect.bottom - height;
|
|
swpFlags &= ~SWP_NOMOVE;
|
|
zOrder = HWND_BOTTOM;
|
|
animateFlags = AW_HIDE | AW_SLIDE | AW_VER_POSITIVE;
|
|
}
|
|
|
|
AnimateWindow(hwnd, AUTOHIDE_ANIMATETIME, animateFlags);
|
|
|
|
if (NULL != toolbar->hBrowser)
|
|
{
|
|
RECT invalidRect;
|
|
CopyRect(&invalidRect, &windowRect);
|
|
MapWindowPoints(hParent, toolbar->hBrowser, (POINT*)&invalidRect, 2);
|
|
RedrawWindow(toolbar->hBrowser, &invalidRect, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
|
}
|
|
|
|
SetWindowPos(hwnd, zOrder, x, y, windowRect.right - windowRect.left, height, swpFlags);
|
|
|
|
if (0 != (WS_VISIBLE & windowStyle))
|
|
{
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | WS_VISIBLE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
toolbar->flags |= TBS_HIDDEN;
|
|
}
|
|
|
|
static void Toolbar_AutoHideWindow(HWND hwnd, BOOL fImmediate)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
if (0 != ((TBS_HIDDEN | TBS_MENULOOP) & toolbar->flags))
|
|
{
|
|
return;
|
|
}
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (0 == (TBS_AUTOHIDE & windowStyle)) return;
|
|
|
|
if (FALSE == fImmediate)
|
|
{
|
|
if (SetTimer(hwnd, TIMER_AUTOHIDE_ID, TIMER_AUTOHIDE_DELAY, Toolbar_AutoHideTimerProc))
|
|
toolbar->flags |= TBS_HIDETIMERSET;
|
|
}
|
|
else
|
|
{
|
|
Toolbar_AutoHideTimerProc(hwnd, WM_TIMER, TIMER_AUTOHIDE_ID, GetTickCount());
|
|
}
|
|
}
|
|
|
|
static void Toolbar_UpdateUiFlags(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
UINT uiState = (UINT)SendMessage(hwnd, WM_QUERYUISTATE, 0, 0L);
|
|
|
|
if (0 != (UISF_HIDEFOCUS & uiState)) toolbar->flags |= TBS_NOFOCUSRECT;
|
|
else toolbar->flags &= ~TBS_NOFOCUSRECT;
|
|
}
|
|
static void Toolbar_NotifyParent(HWND hwnd, UINT eventId)
|
|
{
|
|
HWND hParent = GetParent(hwnd);
|
|
if (NULL == hParent) return;
|
|
UINT controlId = (UINT)GetWindowLongPtr(hwnd, GWLP_ID);
|
|
SENDCMD(hParent, controlId, eventId, hwnd);
|
|
}
|
|
static LRESULT Toolbar_OnCreate(HWND hwnd, CREATESTRUCT *pcs)
|
|
{
|
|
TOOLBAR *toolbar = (TOOLBAR*)calloc(1, sizeof(TOOLBAR));
|
|
if (NULL != toolbar)
|
|
{
|
|
Toolbar_AddRef(toolbar);
|
|
|
|
SetLastError(ERROR_SUCCESS);
|
|
if (!SetWindowLongPtr(hwnd, 0, (LONGX86)(LONG_PTR)toolbar) && ERROR_SUCCESS != GetLastError())
|
|
{
|
|
free(toolbar);
|
|
toolbar = NULL;
|
|
}
|
|
}
|
|
|
|
if (NULL == toolbar)
|
|
{
|
|
DestroyWindow(hwnd);
|
|
return -1;
|
|
}
|
|
|
|
toolbar->chevron = Toolbar_CreateItem(TOOLITEM_CHEVRON, 0);
|
|
toolbar->items = new ItemList();
|
|
toolbar->hTooltip = Toolbar_CreateTooltip(pcs->hInstance, hwnd);
|
|
|
|
if (NULL != toolbar->hTooltip)
|
|
{
|
|
ifc_skinhelper *skinHelper;
|
|
if (SUCCEEDED(Plugin_GetSkinHelper(&skinHelper)))
|
|
{
|
|
skinHelper->SkinControl(toolbar->hTooltip, SKINNEDWND_TYPE_TOOLTIP,
|
|
SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT);
|
|
|
|
skinHelper->Release();
|
|
}
|
|
}
|
|
|
|
if (0 != (TBS_AUTOHIDE & pcs->style))
|
|
toolbar->flags |= TBS_HIDDEN;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void Toolbar_OnDestroy(HWND hwnd)
|
|
{
|
|
Toolbar_RemoveMouseHook(hwnd, TRUE);
|
|
Toolbar_ClearBrushCache(hwnd);
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
SetWindowLongPtr(hwnd, 0, 0L);
|
|
|
|
Toolbar_Release(toolbar);
|
|
}
|
|
|
|
static void Toolbar_OnPaint(HWND hwnd)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
if (BeginPaint(hwnd, &ps))
|
|
{
|
|
if (ps.rcPaint.left != ps.rcPaint.right)
|
|
Toolbar_Paint(hwnd, ps.hdc, &ps.rcPaint, ps.fErase);
|
|
EndPaint(hwnd, &ps);
|
|
}
|
|
}
|
|
|
|
static void Toolbar_OnPrintClient(HWND hwnd, HDC hdc, UINT options)
|
|
{
|
|
RECT clientRect;
|
|
if (GetClientRect(hwnd, &clientRect))
|
|
Toolbar_Paint(hwnd, hdc, &clientRect, 0 != (PRF_ERASEBKGND & options));
|
|
}
|
|
|
|
static void Toolbar_OnWindowPosChanged(HWND hwnd, WINDOWPOS *pwp)
|
|
{
|
|
if (SWP_NOSIZE == ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
|
|
return;
|
|
|
|
Toolbar_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & pwp->flags));
|
|
}
|
|
|
|
static void Toolbar_OnSetRedraw(HWND hwnd, BOOL allowRedraw)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (FALSE == allowRedraw)
|
|
{
|
|
if (0 == (TBS_LOCKUPDATE & windowStyle))
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | TBS_LOCKUPDATE);
|
|
}
|
|
else
|
|
{
|
|
if (0 != (TBS_LOCKUPDATE & windowStyle))
|
|
{
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~TBS_LOCKUPDATE);
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
Toolbar_UpdateLayout(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
}
|
|
DefWindowProcW(hwnd, WM_SETREDRAW, (WPARAM)allowRedraw, 0L);
|
|
}
|
|
|
|
|
|
static void Toolbar_OnEnterMenuLoop(HWND hwnd, BOOL fContext)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
toolbar->flags |= TBS_MENULOOP;
|
|
}
|
|
static void Toolbar_OnExitMenuLoop(HWND hwnd, BOOL fContext)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
toolbar->flags &= ~TBS_MENULOOP;
|
|
|
|
Toolbar_TrackMouseLeave(hwnd);
|
|
}
|
|
|
|
static void Toolbar_OnSetFocus(HWND hwnd, HWND hFocus)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
|
|
BOOL focusDirLeft = FALSE;
|
|
if (0 != (0x8000 & GetAsyncKeyState(VK_LEFT)))
|
|
{
|
|
focusDirLeft = TRUE;
|
|
}
|
|
else if (0 != (0x8000 & GetAsyncKeyState(VK_TAB)))
|
|
{
|
|
if (0 != (0x8000 & GetAsyncKeyState(VK_SHIFT)))
|
|
focusDirLeft = TRUE;
|
|
}
|
|
else if (0 != (0x8000 & GetAsyncKeyState(VK_LBUTTON)) || 0 != (0x8000 & GetAsyncKeyState(VK_RBUTTON)) ||
|
|
0 != (0x8000 & GetAsyncKeyState(VK_MBUTTON)) || 0 != (0x8000 & GetAsyncKeyState(VK_XBUTTON1)) ||
|
|
0 != (0x8000 & GetAsyncKeyState(VK_XBUTTON2)))
|
|
{
|
|
// mouse press (?)
|
|
}
|
|
|
|
if ((size_t)-1 != toolbar->iFocused)
|
|
toolbar->iFocused = Toolbar_GetFocusIndex(hwnd, toolbar->iFocused, 0, FALSE);
|
|
|
|
if ((size_t)-1 == toolbar->iFocused)
|
|
{
|
|
if (0 != (TBS_TABSTOP & windowStyle))
|
|
{
|
|
if (FALSE == focusDirLeft)
|
|
toolbar->iFocused = Toolbar_GetFocusIndex(hwnd, 0, 1, FALSE);
|
|
else
|
|
{
|
|
size_t last = (NULL != toolbar->items) ? toolbar->items->size() : 0;
|
|
if (last > 0)
|
|
toolbar->iFocused = Toolbar_GetFocusIndex(hwnd, last - 1, -1, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
size_t lim, index;
|
|
INT inc;
|
|
if (FALSE == focusDirLeft)
|
|
{
|
|
lim = toolbar->items->size();
|
|
index = 0;
|
|
inc = 1;
|
|
}
|
|
else
|
|
{
|
|
lim = (size_t)-1;
|
|
index = toolbar->items->size();
|
|
if (index > 0) index--;
|
|
inc = -1;
|
|
}
|
|
|
|
for (; index != lim; index += inc)
|
|
{
|
|
UINT itemStyle = toolbar->items->at(index)->GetStyle();
|
|
UINT mask = ToolbarItem::styleTabstop | ToolbarItem::stateDisabled | ToolbarItem::stateHidden;
|
|
if (ToolbarItem::styleTabstop == (mask & itemStyle))
|
|
{
|
|
toolbar->iFocused = index;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (((size_t)-1) != toolbar->iFocused)
|
|
{
|
|
ToolbarItem *item = Toolbar_GetItem(toolbar, toolbar->iFocused);
|
|
if (NULL != item) item->SetFocus(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
|
|
if (0 != (WS_TABSTOP & windowStyle))
|
|
Toolbar_AutoShowWindow(hwnd);
|
|
}
|
|
|
|
static void Toolbar_OnKillFocus(HWND hwnd, HWND hFocus)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && ((size_t)-1) != toolbar->iFocused)
|
|
{
|
|
ToolbarItem *item = Toolbar_GetItem(toolbar, toolbar->iFocused);
|
|
if (NULL != item) item->SetFocus(hwnd, NULL, FALSE);
|
|
toolbar->iFocused = ((size_t)-1);
|
|
}
|
|
Toolbar_AutoHideWindow(hwnd, TRUE);
|
|
}
|
|
|
|
static void Toolbar_OnKeyDown(HWND hwnd, INT vKey, UINT flags)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
Toolbar_AutoShowWindow(hwnd);
|
|
|
|
INT searchDirection = 0;
|
|
if (VK_LEFT == vKey) searchDirection = -1;
|
|
else if (VK_RIGHT == vKey) searchDirection = 1;
|
|
|
|
toolbar->iFocused = Toolbar_GetFocusIndex(hwnd, toolbar->iFocused, searchDirection, FALSE);
|
|
|
|
ToolbarItem *focusedItem = Toolbar_GetItem(toolbar, toolbar->iFocused);
|
|
|
|
BOOL fHandled = (NULL != focusedItem && focusedItem->KeyDown(hwnd, vKey, flags));
|
|
if (!fHandled)
|
|
{
|
|
switch(vKey)
|
|
{
|
|
case VK_LEFT:
|
|
Toolbar_NextItem(hwnd, TBNS_PREVITEM, FALSE);
|
|
break;
|
|
case VK_RIGHT:
|
|
Toolbar_NextItem(hwnd, TBNS_NEXTITEM, FALSE);
|
|
break;
|
|
case VK_HOME:
|
|
case VK_PRIOR:
|
|
{
|
|
size_t first = 0;
|
|
first = Toolbar_GetFocusIndex(hwnd, first, 1, FALSE);
|
|
if (((size_t)-1) != first)
|
|
Toolbar_NextItem(hwnd, MAKEINTRESOURCE(first), TRUE);
|
|
}
|
|
break;
|
|
case VK_END:
|
|
case VK_NEXT:
|
|
{
|
|
size_t last = toolbar->items->size();
|
|
last = Toolbar_GetFocusIndex(hwnd, last, -1, FALSE);
|
|
if (((size_t)-1) != last)
|
|
Toolbar_NextItem(hwnd, MAKEINTRESOURCE(last), TRUE);
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Toolbar_OnKeyUp(HWND hwnd, INT vKey, UINT flags)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
toolbar->iFocused = Toolbar_GetFocusIndex(hwnd, toolbar->iFocused, FALSE, FALSE);
|
|
|
|
ToolbarItem *focusedItem = Toolbar_GetItem(toolbar, toolbar->iFocused);
|
|
|
|
BOOL fHandled = (NULL != focusedItem && focusedItem->KeyUp(hwnd, vKey, flags));
|
|
}
|
|
|
|
static void Toolbar_OnMouseMove(HWND hwnd, UINT mouseFlags, POINTS pts)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
Toolbar_AutoShowWindow(hwnd);
|
|
|
|
POINT pt;
|
|
POINTSTOPOINT(pt, pts);
|
|
|
|
RECT clientRect;
|
|
Toolbar_GetClientRect(hwnd, &clientRect);
|
|
|
|
if (NULL != toolbar->pressed)
|
|
{
|
|
if (!PtInRect(&clientRect, pt))
|
|
{
|
|
toolbar->pressed->MouseLeave(hwnd);
|
|
}
|
|
else
|
|
{
|
|
toolbar->pressed->MouseMove(hwnd, mouseFlags, pt);
|
|
}
|
|
return;
|
|
}
|
|
|
|
ToolbarItem *item = (PtInRect(&clientRect, pt)) ? Toolbar_HitTest(hwnd, pt) : NULL;
|
|
|
|
ToolbarItem *prevHighlighted = toolbar->highlighted;
|
|
if (NULL != toolbar->highlighted)
|
|
{
|
|
if (item != toolbar->highlighted)
|
|
{
|
|
toolbar->highlighted->MouseLeave(hwnd);
|
|
toolbar->highlighted = NULL;
|
|
}
|
|
}
|
|
|
|
if (NULL != item)
|
|
{
|
|
UINT style = item->GetStyle();
|
|
if (0 == ((ToolbarItem::stateDisabled | ToolbarItem::stateHidden | ToolbarItem::styleStatic) & style))
|
|
{
|
|
toolbar->highlighted = item;
|
|
item->MouseMove(hwnd, mouseFlags, pt);
|
|
Toolbar_TrackMouseLeave(hwnd);
|
|
}
|
|
}
|
|
|
|
if (NULL != toolbar->hTooltip)
|
|
{
|
|
if (prevHighlighted == toolbar->highlighted || NULL != prevHighlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_MOUSEMOVE, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
|
|
if (prevHighlighted != toolbar->highlighted)
|
|
{
|
|
Toolbar_SetTooltipItem(hwnd, toolbar->highlighted);
|
|
if (NULL != toolbar->highlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_MOUSEMOVE, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Toolbar_OnMouseLeave(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
if (NULL != toolbar->highlighted)
|
|
{
|
|
toolbar->highlighted->MouseLeave(hwnd);
|
|
toolbar->highlighted = NULL;
|
|
}
|
|
|
|
Toolbar_SetTooltipItem(hwnd, NULL);
|
|
|
|
|
|
POINT cursor;
|
|
if (GetFocus() != hwnd && GetCursorPos(&cursor))
|
|
{
|
|
HWND hCursor = WindowFromPoint(cursor);
|
|
if (NULL != hCursor &&
|
|
GetWindowThreadProcessId(hwnd, NULL) != GetWindowThreadProcessId(hCursor, NULL))
|
|
{
|
|
Toolbar_AutoHideWindow(hwnd, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Toolbar_OnLButtonDown(HWND hwnd, UINT mouseFlags, POINTS pts)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
Toolbar_SetTooltipItem(hwnd, NULL);
|
|
|
|
if (NULL != toolbar->highlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_LBUTTONDOWN, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
|
|
POINT pt;
|
|
POINTSTOPOINT(pt, pts);
|
|
|
|
RECT clientRect;
|
|
Toolbar_GetClientRect(hwnd, &clientRect);
|
|
|
|
ToolbarItem *item = (PtInRect(&clientRect, pt)) ? Toolbar_HitTest(hwnd, pt) : NULL;
|
|
|
|
if (NULL != item)
|
|
{
|
|
if (0 == ((ToolbarItem::stateDisabled | ToolbarItem::stateHidden | ToolbarItem::styleStatic) & item->GetStyle()))
|
|
{
|
|
item->LButtonDown(hwnd, mouseFlags, pt);
|
|
toolbar->pressed = item;
|
|
}
|
|
}
|
|
|
|
SetCapture(hwnd);
|
|
}
|
|
|
|
static void Toolbar_OnLButtonUp(HWND hwnd, UINT mouseFlags, POINTS pts)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
if (NULL != toolbar->highlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_LBUTTONUP, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
|
|
POINT pt;
|
|
POINTSTOPOINT(pt, pts);
|
|
|
|
RECT clientRect;
|
|
Toolbar_GetClientRect(hwnd, &clientRect);
|
|
|
|
ToolbarItem *item = (PtInRect(&clientRect, pt)) ? Toolbar_HitTest(hwnd, pt) : NULL;
|
|
|
|
if (NULL != toolbar->pressed)
|
|
{
|
|
ToolbarItem *pressed = toolbar->pressed;
|
|
toolbar->pressed = NULL;
|
|
Toolbar_AddRef(toolbar);
|
|
pressed->AddRef();
|
|
if (pressed == item)
|
|
pressed->Click(hwnd, mouseFlags, pt);
|
|
|
|
pressed->LButtonUp(hwnd, mouseFlags, pt);
|
|
pressed->Release();
|
|
Toolbar_Release(toolbar);
|
|
}
|
|
|
|
if (hwnd == GetCapture())
|
|
ReleaseCapture();
|
|
}
|
|
|
|
static void Toolbar_OnRButtonDown(HWND hwnd, UINT mouseFlags, POINTS pts)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
Toolbar_SetTooltipItem(hwnd, NULL);
|
|
|
|
if (NULL != toolbar->highlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_RBUTTONDOWN, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
|
|
}
|
|
|
|
static void Toolbar_OnRButtonUp(HWND hwnd, UINT mouseFlags, POINTS pts)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
if (NULL != toolbar->highlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_RBUTTONUP, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
}
|
|
|
|
static void Toolbar_OnMButtonDown(HWND hwnd, UINT mouseFlags, POINTS pts)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
Toolbar_SetTooltipItem(hwnd, NULL);
|
|
|
|
if (NULL != toolbar->highlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_MBUTTONDOWN, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
}
|
|
|
|
static void Toolbar_OnMButtonUp(HWND hwnd, UINT mouseFlags, POINTS pts)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
if (NULL != toolbar->highlighted)
|
|
Toolbar_RelayTooltipMsg(toolbar->hTooltip, hwnd, WM_MBUTTONUP, (WPARAM)mouseFlags, *((LPARAM*)(&pts)));
|
|
}
|
|
|
|
static void Toolbar_OnContextMenu(HWND hwnd, HWND hOwner, POINTS pts)
|
|
{
|
|
POINT pt;
|
|
POINTSTOPOINT(pt, pts);
|
|
|
|
if (-1 == pt.x || -1 == pt.y)
|
|
{
|
|
RECT windowRect;
|
|
GetWindowRect(hwnd, &windowRect);
|
|
if (!GetCursorPos(&pt) || !PtInRect(&windowRect, pt))
|
|
{
|
|
pt.x = windowRect.left + 2;
|
|
pt.y = windowRect.top + 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
POINT localPt = pt;
|
|
MapWindowPoints(HWND_DESKTOP, hwnd, &localPt, 1);
|
|
|
|
RECT clientRect;
|
|
Toolbar_GetClientRect(hwnd, &clientRect);
|
|
ToolbarItem *item = (PtInRect(&clientRect, localPt)) ? Toolbar_HitTest(hwnd, localPt) : NULL;
|
|
|
|
if (NULL != item)
|
|
{
|
|
UINT itemStyle = item->GetStyle();
|
|
if (0 == ((ToolbarItem::stateHidden | ToolbarItem::stateDisabled) & itemStyle))
|
|
{
|
|
RECT itemRect;
|
|
if (item->GetRect(&itemRect) && PtInRect(&itemRect, localPt))
|
|
{
|
|
if (FALSE != item->DisplayContextMenu(hwnd, pt.x, pt.y))
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Toolbar_DisplayContextMenu(hwnd, pt.x, pt.y);
|
|
}
|
|
static void Toolbar_OnCaptureChanged(HWND hwnd, HWND hCapture)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
Toolbar_TrackMouseLeave(hwnd);
|
|
}
|
|
static LRESULT Toolbar_OnGetFont(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return NULL;
|
|
return (LRESULT)toolbar->textFont;
|
|
}
|
|
|
|
|
|
static void Toolbar_OnSetFont(HWND hwnd, HFONT hFont, BOOL fRedraw)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
toolbar->textFont = hFont;
|
|
|
|
Toolbar_UpdateTextMetrics(hwnd);
|
|
|
|
if (FALSE != fRedraw)
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
|
|
static void Toolbar_GetTootipDispInfo(HWND hwnd, NMTTDISPINFO *pdisp)
|
|
{
|
|
ToolbarItem *item = (ToolbarItem*)pdisp->lParam;
|
|
if (NULL != item)
|
|
{
|
|
item->GetTip(pdisp->szText, ARRAYSIZE(pdisp->szText));
|
|
}
|
|
}
|
|
|
|
static LRESULT Toolbar_OnTooltipNotify(HWND hwnd, NMHDR *pnmh)
|
|
{
|
|
switch(pnmh->code)
|
|
{
|
|
case TTN_GETDISPINFO:
|
|
Toolbar_GetTootipDispInfo(hwnd, (NMTTDISPINFO*)pnmh);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
static LRESULT Toolbar_OnNotify(HWND hwnd, INT controlId, NMHDR *pnmh)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return 0;
|
|
|
|
if (toolbar->hTooltip == pnmh->hwndFrom && NULL != toolbar->hTooltip)
|
|
return Toolbar_OnTooltipNotify(hwnd, pnmh);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void Toolbar_OnCommand(HWND hwnd, INT commandId, INT eventId, HWND hControl)
|
|
{
|
|
BOOL fEnabled;
|
|
switch(commandId)
|
|
{
|
|
case ID_TOOLBAR_DOCKTOP:
|
|
case ID_TOOLBAR_DOCKBOTTOM:
|
|
fEnabled = (ID_TOOLBAR_DOCKBOTTOM == commandId);
|
|
if (fEnabled != Toolbar_EnableBottomDock(hwnd, fEnabled))
|
|
Toolbar_NotifyParent(hwnd, TBN_DOCKCHANGED);
|
|
break;
|
|
case ID_TOOLBAR_AUTOHIDE:
|
|
fEnabled = (0 == (TBS_AUTOHIDE & GetWindowStyle(hwnd)));
|
|
if (fEnabled != Toolbar_EnableAutoHide(hwnd, fEnabled))
|
|
Toolbar_NotifyParent(hwnd, TBN_AUTOHIDECHANGED);
|
|
break;
|
|
case ID_TOOLBAR_TABSTOP:
|
|
fEnabled = (0 == (TBS_TABSTOP & GetWindowStyle(hwnd)));
|
|
if (fEnabled != Toolbar_EnableTabStop(hwnd, fEnabled))
|
|
Toolbar_NotifyParent(hwnd, TBN_TABSTOPCHANGED);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static BOOL Toolbar_ProcessTabKey(HWND hwnd, UINT messageId)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return FALSE;
|
|
|
|
BOOL focusDirLeft = (0 != (0x8000 & GetAsyncKeyState(VK_SHIFT)));
|
|
|
|
size_t lim, index;
|
|
INT inc;
|
|
if (FALSE == focusDirLeft)
|
|
{
|
|
inc = 1;
|
|
lim = toolbar->items->size();
|
|
index = toolbar->iFocused;
|
|
if ((size_t)-1 == index) index = 0;
|
|
index++;
|
|
if (index >= lim) return FALSE;
|
|
}
|
|
else
|
|
{
|
|
inc = -1;
|
|
lim = (size_t)-1;
|
|
index = toolbar->iFocused;
|
|
if ((size_t)-1 == index) index = toolbar->items->size();
|
|
index--;
|
|
if (index >= toolbar->items->size()) return FALSE;
|
|
}
|
|
|
|
for (; index != lim; index += inc)
|
|
{
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (FALSE != Toolbar_IsItemAcceptFocus(item, TRUE))
|
|
{
|
|
item->SetFocus(hwnd, NULL, TRUE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetDlgCode(HWND hwnd, INT vKey, MSG *pMsg)
|
|
{
|
|
if (NULL != pMsg)
|
|
{
|
|
switch(vKey)
|
|
{
|
|
case VK_TAB:
|
|
if (FALSE == Toolbar_ProcessTabKey(hwnd, pMsg->message))
|
|
{
|
|
if (WM_KEYDOWN == pMsg->message)
|
|
Toolbar_AutoHideWindow(hwnd, TRUE);
|
|
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
return DLGC_WANTALLKEYS;
|
|
}
|
|
|
|
|
|
static void Toolbar_OnUpdateUiState(HWND hwnd, INT action, INT state)
|
|
{
|
|
DefWindowProc(hwnd, WM_UPDATEUISTATE, MAKEWPARAM(action, state), 0L);
|
|
Toolbar_UpdateUiFlags(hwnd);
|
|
}
|
|
|
|
static void Toolbar_OnEnable(HWND hwnd, BOOL fEnable)
|
|
{
|
|
InvalidateRect(hwnd, NULL, FALSE);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnSetCursor(HWND hwnd, HWND hCursor, UINT hitTest, UINT messageId)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return FALSE;
|
|
|
|
if (0 == (TBS_MENULOOP & toolbar->flags) && hwnd == hCursor)
|
|
{
|
|
ToolbarItem *item = (NULL != toolbar->pressed) ? toolbar->pressed : toolbar->highlighted;
|
|
if (NULL != item && FALSE != item->SetCursor(hwnd, hCursor, hitTest, messageId))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return DefWindowProcW(hwnd, WM_SETCURSOR, (WPARAM)hCursor, MAKELPARAM(hitTest, messageId));
|
|
}
|
|
|
|
static LRESULT Toolbar_OnColorEdit(HWND hwnd, HDC hdcCtrl, HWND hwndCtrl)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return 0;
|
|
|
|
SetTextColor(hdcCtrl, toolbar->rgbEdit);
|
|
SetBkColor(hdcCtrl, toolbar->rgbEditBk);
|
|
return (LRESULT)Toolbar_GetBrush(hwnd, TOOLBRUSH_ITEMBK);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnColorStatic(HWND hwnd, HDC hdcCtrl, HWND hwndCtrl)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return 0;
|
|
|
|
SetTextColor(hdcCtrl, toolbar->rgbText);
|
|
SetBkColor(hdcCtrl, toolbar->rgbBk);
|
|
return (LRESULT)Toolbar_GetBrush(hwnd, TOOLBRUSH_BACK);
|
|
}
|
|
|
|
|
|
static LRESULT Toolbar_OnGetIdealHeight(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->imageList) return 0;
|
|
|
|
INT toolbarHeight, iconWidth;
|
|
if (!ImageList_GetIconSize(toolbar->imageList, &iconWidth, &toolbarHeight))
|
|
toolbarHeight = 0;
|
|
else
|
|
toolbarHeight /= TOOLBAR_ICONSTATE_COUNT;
|
|
|
|
HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
|
if (NULL != hdc)
|
|
{
|
|
HFONT originalFont = (HFONT)SelectObject(hdc, toolbar->textFont);
|
|
TEXTMETRIC tm;
|
|
if (GetTextMetrics(hdc, &tm))
|
|
{
|
|
tm.tmHeight += ((tm.tmHeight - (tm.tmAscent - tm.tmInternalLeading))/2 + 2);
|
|
if (toolbarHeight <= tm.tmHeight)
|
|
toolbarHeight = tm.tmHeight + 4;
|
|
}
|
|
SelectObject(hdc, originalFont);
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
return toolbarHeight + TOOLBAR_SPACE_TOP + TOOLBAR_SPACE_BOTTOM;
|
|
}
|
|
|
|
static void Toolbar_OnUpdateSkin(HWND hwnd, BOOL fRedraw)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return;
|
|
|
|
ifc_skinhelper *skinHelper;
|
|
if (FAILED(Plugin_GetSkinHelper(&skinHelper)))
|
|
skinHelper = NULL;
|
|
|
|
Toolbar_UpdateColorTable(hwnd, skinHelper);
|
|
Toolbar_ClearBrushCache(hwnd);
|
|
|
|
if (NULL != toolbar->imageList)
|
|
ImageList_Destroy(toolbar->imageList);
|
|
|
|
toolbar->imageList = Toolbar_LoadImagelist(toolbar, Plugin_GetInstance(),
|
|
MAKEINTRESOURCE(IDR_TOOLBARLARGE_IMAGE),
|
|
21, TOOLBAR_ICONSTATE_COUNT);
|
|
|
|
if (NULL != toolbar->ownedFont)
|
|
{
|
|
DeleteObject(toolbar->ownedFont);
|
|
}
|
|
|
|
HFONT font = (NULL != skinHelper) ? skinHelper->GetFont() : NULL;
|
|
|
|
if (0/* create custom font */)
|
|
{
|
|
toolbar->ownedFont = Toolbar_CreateFont(font);
|
|
if (NULL != toolbar->ownedFont)
|
|
font = toolbar->ownedFont;
|
|
}
|
|
else
|
|
{
|
|
toolbar->ownedFont = NULL;
|
|
}
|
|
|
|
SendMessage(hwnd, WM_SETFONT, (WPARAM)font, FALSE);
|
|
|
|
if (NULL != toolbar->hTooltip)
|
|
{
|
|
SendMessage(toolbar->hTooltip, WM_SETFONT, (WPARAM)(toolbar->textFont), TRUE);
|
|
}
|
|
|
|
Toolbar_UpdateUiFlags(hwnd);
|
|
|
|
if (NULL != toolbar->items)
|
|
{
|
|
size_t index = toolbar->items->size();
|
|
while(index-- > 0)
|
|
{
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL != item)
|
|
{
|
|
item->UpdateSkin(hwnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
Toolbar_UpdateLayout(hwnd, FALSE);
|
|
|
|
if (FALSE != fRedraw)
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
|
|
if (NULL != skinHelper)
|
|
skinHelper->Release();
|
|
}
|
|
|
|
|
|
static LRESULT Toolbar_OnGetIconSize(HWND hwnd, INT iconIndex, SIZE *pSize)
|
|
{
|
|
if (NULL == pSize) return FALSE;
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
|
|
if (ICON_CHEVRON == iconIndex)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
iconIndex = (0 != (TBS_BOTTOMDOCK & windowStyle)) ? ICON_CHEVRON_BOTTOM : ICON_CHEVRON_TOP;
|
|
}
|
|
|
|
if (NULL == toolbar ||
|
|
NULL == toolbar->imageList ||
|
|
iconIndex < 0 ||
|
|
iconIndex >= ImageList_GetImageCount(toolbar->imageList))
|
|
{
|
|
ZeroMemory(pSize, sizeof(SIZE));
|
|
return FALSE;
|
|
}
|
|
|
|
INT cx, cy;
|
|
BOOL result = ImageList_GetIconSize(toolbar->imageList, &cx, &cy);
|
|
|
|
if (FALSE != result)
|
|
{
|
|
pSize->cy = cy / TOOLBAR_ICONSTATE_COUNT;
|
|
switch(iconIndex)
|
|
{
|
|
case ICON_SEPARATOR:
|
|
pSize->cx = ICON_SEPARATOR_WIDTH;
|
|
break;
|
|
case ICON_CHEVRON_TOP:
|
|
case ICON_CHEVRON_BOTTOM:
|
|
pSize->cx = ICON_CHEVRON_WIDTH;
|
|
break;
|
|
case ICON_HISTORY:
|
|
pSize->cx = ICON_HISTORY_WIDTH;
|
|
break;
|
|
case ICON_BACK:
|
|
case ICON_FORWARD:
|
|
pSize->cx =ICON_ARROW_WIDTH;
|
|
break;
|
|
default:
|
|
pSize->cx = cx;
|
|
break;
|
|
}
|
|
|
|
}
|
|
else
|
|
ZeroMemory(pSize, sizeof(SIZE));
|
|
return result;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnSendCommand(HWND hwnd, INT commandId)
|
|
{
|
|
HWND hParent = GetParent(hwnd);
|
|
if (NULL == hParent) return FALSE;
|
|
|
|
if (ID_CHEVRON_CLICKED == commandId)
|
|
{
|
|
Toolbar_DisplayChevronMenu(hwnd);
|
|
return 0;
|
|
}
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && NULL != toolbar->items)
|
|
{
|
|
size_t index= toolbar->items->size();
|
|
while(index--)
|
|
toolbar->items->at(index)->CommandSent(hwnd, commandId);
|
|
}
|
|
return SendMessage(hParent, WM_COMMAND, MAKEWPARAM(commandId, 0), (LPARAM)hwnd);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnDrawIcon(HWND hwnd, TOOLBARDRAWICONPARAM *iconParam)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == iconParam) return FALSE;
|
|
INT iconIndex = iconParam->iconIndex;
|
|
if (ICON_CHEVRON == iconIndex)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
iconIndex = (0 != (TBS_BOTTOMDOCK & windowStyle)) ? ICON_CHEVRON_BOTTOM : ICON_CHEVRON_TOP;
|
|
}
|
|
|
|
if (NULL == toolbar->imageList ||
|
|
iconIndex < 0 ||
|
|
iconIndex >= ImageList_GetImageCount(toolbar->imageList))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
INT frameHeight, frameWidth;
|
|
if (!ImageList_GetIconSize(toolbar->imageList, &frameWidth, &frameHeight))
|
|
{
|
|
frameHeight = 0;
|
|
frameWidth = 0;
|
|
}
|
|
|
|
INT offsetY;
|
|
if (0 != (ToolbarItem::stateDisabled & iconParam->itemState))
|
|
offsetY = TOOLBAR_ICONSTATE_DISABLED;
|
|
else if (0 != (ToolbarItem::statePressed & iconParam->itemState))
|
|
offsetY = TOOLBAR_ICONSTATE_PRESSED;
|
|
else if (0 != (ToolbarItem::stateHighlighted & iconParam->itemState))
|
|
offsetY = TOOLBAR_ICONSTATE_HIGHLIGHTED;
|
|
else
|
|
offsetY = TOOLBAR_ICONSTATE_NORMAL;
|
|
|
|
frameHeight = frameHeight / TOOLBAR_ICONSTATE_COUNT;
|
|
|
|
IMAGELISTDRAWPARAMS param;
|
|
param.cbSize = sizeof(IMAGELISTDRAWPARAMS) - sizeof(DWORD) * 3;
|
|
param.himl = toolbar->imageList;
|
|
param.i = iconIndex;
|
|
param.hdcDst = iconParam->hdcDst;
|
|
param.x = iconParam->x;
|
|
param.y = iconParam->y;
|
|
param.cx = (iconParam->cx > frameWidth) ? frameWidth : iconParam->cx;
|
|
param.cy = (iconParam->cy > frameHeight) ? frameHeight : iconParam->cy;
|
|
param.xBitmap = 0;
|
|
param.yBitmap = frameHeight * offsetY;
|
|
param.rgbBk = CLR_NONE;
|
|
param.rgbFg = CLR_NONE;
|
|
param.fStyle = ILD_NORMAL;
|
|
param.dwRop = SRCCOPY;
|
|
param.fState = ILS_NORMAL;
|
|
param.Frame = 0;
|
|
param.crEffect = 0;
|
|
|
|
return ImageList_DrawIndirect(¶m);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetItemCount(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->items) return 0;
|
|
return (INT)toolbar->items->size();
|
|
}
|
|
|
|
static LRESULT Toolbar_OnClear(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return FALSE;
|
|
if (NULL == toolbar->items) return TRUE;
|
|
|
|
Toolbar_ClearItems(toolbar);
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (0 == (TBS_LOCKUPDATE & windowStyle))
|
|
{
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
Toolbar_UpdateLayout(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnInsertItem(HWND hwnd, TOOLBARINSERTITEM *insertItem)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->items ||
|
|
NULL == insertItem || insertItem->cbSize != sizeof(TOOLBARINSERTITEM))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
INT index = ITEM_ERR;
|
|
|
|
UINT styleOverride = 0;
|
|
if (0 != (TBIS_HIDDEN & insertItem->style)) styleOverride |= ToolbarItem::stateHidden;
|
|
if (0 != (TBIS_DISABLED & insertItem->style)) styleOverride |= ToolbarItem::stateDisabled;
|
|
if (0 != (TBIS_CHEVRONONLY & insertItem->style)) styleOverride |= ToolbarItem::styleChevronOnly;
|
|
if (0 != (TBIS_NOCHEVRON & insertItem->style)) styleOverride |= ToolbarItem::styleNoChevron;
|
|
if (0 != (TBIS_POPUP & insertItem->style)) styleOverride |= ToolbarItem::stylePopup;
|
|
|
|
ToolbarItem *item = Toolbar_CreateItem(insertItem->pszName, styleOverride);
|
|
if (NULL != item)
|
|
{
|
|
index = Toolbar_InsertItemInternal(toolbar, item, insertItem->insertBefore, hwnd);
|
|
item->Release();
|
|
if (ITEM_ERR != index)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (0 == (TBS_LOCKUPDATE & windowStyle))
|
|
{
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
Toolbar_UpdateLayout(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnFindItem(HWND hwnd, LPCSTR pszName)
|
|
{
|
|
return Toolbar_ResolveName(hwnd, pszName);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnRemoveItem(HWND hwnd, LPCSTR pszName)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->items || index == toolbar->items->size())
|
|
return FALSE;
|
|
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
toolbar->items->erase(toolbar->items->begin() + index);
|
|
if (NULL != item) item->Release();
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (0 == (TBS_LOCKUPDATE & windowStyle))
|
|
{
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
Toolbar_UpdateLayout(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static LRESULT Toolbar_OnSetItemInt(HWND hwnd, LPCSTR pszName, INT value)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (index == toolbar->items->size()) return FALSE;
|
|
return toolbar->items->at(index)->SetValueInt(hwnd, value);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnSetItemString(HWND hwnd, LPCSTR pszName, LPCWSTR value)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (index == toolbar->items->size()) return FALSE;
|
|
return toolbar->items->at(index)->SetValueStr(hwnd, value);
|
|
}
|
|
static COLORREF Toolbar_OnGetBkColor(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
return (NULL != toolbar) ? toolbar->rgbBk : 0x00FF00FF;
|
|
}
|
|
static COLORREF Toolbar_OnGetFgColor(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
return (NULL != toolbar) ? toolbar->rgbFg : 0x00FF00FF;
|
|
}
|
|
|
|
static COLORREF Toolbar_OnGetTextColor(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
return (NULL != toolbar) ? toolbar->rgbText : 0x00FF00FF;
|
|
}
|
|
|
|
static COLORREF Toolbar_OnGetHiliteColor(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
return (NULL != toolbar) ? toolbar->rgbHilite : 0x00FF00FF;
|
|
}
|
|
|
|
static COLORREF Toolbar_OnGetEditColor(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
return (NULL != toolbar) ? toolbar->rgbEdit : 0x00FF00FF;
|
|
}
|
|
|
|
static COLORREF Toolbar_OnGetEditBkColor(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
return (NULL != toolbar) ? toolbar->rgbEditBk : 0x00FF00FF;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnEnableItem(HWND hwnd, LPCSTR pszName, BOOL fEnable)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (index == toolbar->items->size()) return FALSE;
|
|
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL == item) return FALSE;
|
|
|
|
item->SetStyle(hwnd, (0 != fEnable) ? 0 : ToolbarItem::stateDisabled, ToolbarItem::stateDisabled);
|
|
if (FALSE == fEnable && toolbar->highlighted == item)
|
|
Toolbar_SetTooltipItem(hwnd, NULL);
|
|
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetItemStyle(HWND hwnd, LPCSTR pszName, UINT fMask)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return 0;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (index == toolbar->items->size()) return 0;
|
|
|
|
UINT itemStyle = toolbar->items->at(index)->GetStyle();
|
|
return (itemStyle & fMask);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetItemCommand(HWND hwnd, LPCSTR pszName)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return 0;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (index == toolbar->items->size()) return 0;
|
|
|
|
return toolbar->items->at(index)->GetCommandId();
|
|
}
|
|
|
|
static LRESULT Toolbar_OnShowItem(HWND hwnd, LPCSTR pszName, BOOL fShow)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (index == toolbar->items->size()) return FALSE;
|
|
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL == item) return FALSE;
|
|
|
|
UINT style = item->GetStyle();
|
|
if ((0 != (ToolbarItem::stateHidden & style)) == (FALSE == fShow))
|
|
return TRUE;
|
|
|
|
item->SetStyle(hwnd, (0 != fShow) ? 0 : ToolbarItem::stateHidden, ToolbarItem::stateHidden);
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
if (0 == (TBS_LOCKUPDATE & windowStyle))
|
|
{
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
Toolbar_UpdateLayout(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnSetItemDescription(HWND hwnd, LPCSTR pszName, LPCWSTR pszDescription)
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (index == toolbar->items->size()) return FALSE;
|
|
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL == item) return FALSE;
|
|
|
|
if (FALSE == item->SetDescription(hwnd, pszDescription))
|
|
return FALSE;
|
|
|
|
if (IsWindowVisible(hwnd) && IsWindowEnabled(hwnd))
|
|
Toolbar_UpdateTip(hwnd);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static void Toolbar_OnUpdateTip(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && NULL != toolbar->hTooltip)
|
|
{
|
|
TOOLINFO ti;
|
|
ti.cbSize = sizeof(TOOLINFO);
|
|
ti.uId = 0;
|
|
ti.hinst = NULL;
|
|
ti.hwnd = hwnd;
|
|
ti.lpszText = LPSTR_TEXTCALLBACK;
|
|
SendMessage(toolbar->hTooltip, TTM_UPDATETIPTEXT, 0, (LPARAM)&ti);
|
|
}
|
|
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetTextMetrics(HWND hwnd, TOOLBARTEXTMETRIC *metric)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return FALSE;
|
|
CopyMemory(metric, &toolbar->textMetric, sizeof(TOOLBARTEXTMETRIC));
|
|
return TRUE;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetBkBrush(HWND hwnd)
|
|
{
|
|
return (LRESULT)Toolbar_GetBrush(hwnd, TOOLBRUSH_BACK);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnLayout(HWND hwnd, TOOLBARLAYOUT *layout)
|
|
{
|
|
if (NULL == layout)
|
|
return FALSE;
|
|
|
|
CopyRect(&layout->clientRect, layout->prcParent);
|
|
DWORD windowStyle = GetWindowStyle(hwnd);
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || 0 == (WS_VISIBLE & windowStyle))
|
|
{
|
|
layout->insertAfter = HWND_BOTTOM;
|
|
SetRectEmpty(&layout->toolbarRect);
|
|
return TRUE;
|
|
}
|
|
|
|
CopyRect(&layout->toolbarRect, layout->prcParent);
|
|
|
|
INT toolbarHeight, clientInflate;
|
|
|
|
if (0 != (TBS_AUTOHIDE & windowStyle))
|
|
{
|
|
clientInflate = TOOLBAR_HIDDENHEIGHT;
|
|
toolbarHeight = (0 == (TBS_HIDDEN & toolbar->flags)) ?
|
|
Toolbar_GetIdealHeight(hwnd) : TOOLBAR_HIDDENHEIGHT;
|
|
}
|
|
else
|
|
{
|
|
toolbarHeight = Toolbar_GetIdealHeight(hwnd);
|
|
clientInflate = toolbarHeight;
|
|
}
|
|
|
|
|
|
if (0 != (TBS_BOTTOMDOCK & windowStyle))
|
|
{
|
|
layout->toolbarRect.top = layout->toolbarRect.bottom - toolbarHeight;
|
|
if (layout->toolbarRect.top < layout->prcParent->top)
|
|
layout->toolbarRect.top = layout->prcParent->top;
|
|
layout->clientRect.bottom -= clientInflate;
|
|
layout->insertAfter = (0 == (TBS_AUTOHIDE & windowStyle) || 0 != (TBS_HIDDEN & toolbar->flags)) ?
|
|
HWND_BOTTOM : HWND_TOP;
|
|
}
|
|
else
|
|
{
|
|
layout->toolbarRect.bottom = layout->toolbarRect.top + toolbarHeight;
|
|
if (layout->toolbarRect.bottom > layout->prcParent->bottom)
|
|
layout->toolbarRect.bottom = layout->prcParent->bottom;
|
|
layout->clientRect.top += clientInflate;
|
|
layout->insertAfter = HWND_TOP;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL Toolbar_OnNextItem(HWND hwnd, LPCSTR pszName, BOOL fUseName)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return FALSE;
|
|
|
|
size_t focusIndex = toolbar->iFocused;
|
|
if (FALSE == fUseName)
|
|
{
|
|
focusIndex = Toolbar_GetFocusIndex(hwnd, toolbar->iFocused, 0, FALSE);
|
|
if (((size_t)-1) == focusIndex)
|
|
{
|
|
if (TBNS_NEXTITEM == pszName)
|
|
{
|
|
focusIndex = toolbar->items->size();
|
|
if (focusIndex > 0) focusIndex--;
|
|
}
|
|
else
|
|
{
|
|
focusIndex = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (TBNS_NEXTITEM == pszName)
|
|
{
|
|
if (focusIndex <= toolbar->items->size())
|
|
focusIndex = Toolbar_GetFocusIndex(hwnd, focusIndex + 1, 1, FALSE);
|
|
}
|
|
else
|
|
{
|
|
if (focusIndex > 0)
|
|
focusIndex = Toolbar_GetFocusIndex(hwnd, focusIndex - 1, -1, FALSE);
|
|
}
|
|
|
|
if (((size_t)-1) == focusIndex)
|
|
focusIndex = toolbar->iFocused;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index ||
|
|
!Toolbar_IsItemAcceptFocus(Toolbar_GetItem(toolbar, index), FALSE))
|
|
return FALSE;
|
|
focusIndex = (size_t)index;
|
|
}
|
|
|
|
BOOL focusChanged = FALSE;
|
|
if (focusIndex != toolbar->iFocused)
|
|
{
|
|
ToolbarItem *itemNew, *itemOld;
|
|
|
|
itemOld = Toolbar_GetItem(toolbar, toolbar->iFocused);
|
|
itemNew = Toolbar_GetItem(toolbar, focusIndex);
|
|
toolbar->iFocused = focusIndex;
|
|
|
|
if (NULL != itemOld) itemOld->SetFocus(hwnd, itemNew, FALSE);
|
|
if (NULL != itemNew) itemNew->SetFocus(hwnd, itemOld, TRUE);
|
|
|
|
focusChanged = TRUE;
|
|
}
|
|
|
|
HWND hFocus = GetFocus();
|
|
if (hwnd != hFocus && FALSE == IsChild(hwnd, hFocus))
|
|
{
|
|
if (IsWindowVisible(hwnd) && IsWindowEnabled(hwnd))
|
|
{
|
|
HWND hRoot = GetAncestor(hwnd, GA_ROOT);
|
|
if (NULL != hRoot)
|
|
SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hwnd, TRUE);
|
|
if (hwnd != GetFocus())
|
|
SetFocus(hwnd);
|
|
}
|
|
}
|
|
else if (FALSE == focusChanged)
|
|
{
|
|
ToolbarItem *item = Toolbar_GetItem(toolbar, toolbar->iFocused);
|
|
if (NULL != item) item->SetFocus(hwnd, item, TRUE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL Toolbar_OnGetItemInfo(HWND hwnd, LPCSTR pszName, TBITEMINFO *itemInfo)
|
|
{
|
|
if (NULL == itemInfo)
|
|
return FALSE;
|
|
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || index == toolbar->items->size()) return FALSE;
|
|
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL == item) return FALSE;
|
|
|
|
BOOL result = TRUE;
|
|
|
|
itemInfo->commandId = item->GetCommandId();
|
|
itemInfo->style = item->GetStyle();
|
|
|
|
if (NULL != itemInfo->pszText)
|
|
{
|
|
if (FAILED(item->GetText(itemInfo->pszText, itemInfo->cchText)))
|
|
result = FALSE;
|
|
}
|
|
|
|
if (NULL != itemInfo->pszDescription)
|
|
{
|
|
if (FAILED(item->GetDescription(itemInfo->pszDescription, itemInfo->cchDescription)))
|
|
result = FALSE;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
static HRESULT Toolbar_GetServiceCommandState(HWND hBrowser,ifc_omservicecommand *serviceCommand, const GUID *commandGroup, UINT commandId, HRESULT defaultState)
|
|
{
|
|
HRESULT state = (NULL != serviceCommand) ? serviceCommand->QueryState(hBrowser, commandGroup, commandId) : defaultState;
|
|
if (E_NOTIMPL == state)
|
|
state = defaultState;
|
|
return state;
|
|
}
|
|
|
|
static INT Toolbar_InsertItemHelper(HWND hwnd, LPCSTR pszName, UINT overrideStyle, INT insertBefore)
|
|
{
|
|
INT index = ITEM_ERR;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && NULL != toolbar->items)
|
|
{
|
|
ToolbarItem *item = Toolbar_CreateItem(pszName, overrideStyle);
|
|
if (NULL != item)
|
|
{
|
|
index = Toolbar_InsertItemInternal(toolbar, item, insertBefore, hwnd);
|
|
item->Release();
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
static INT Toolbar_AddItemHelper(HWND hwnd, LPCSTR pszName, UINT overrideStyle)
|
|
{
|
|
return Toolbar_InsertItemHelper(hwnd, pszName, overrideStyle, TBIP_LAST);
|
|
}
|
|
|
|
static INT Toolbar_AddItemHelper2(HWND hwnd, LPCSTR pszName, UINT overrideStyle, ifc_omservicecommand *serviceCommand, const GUID *commandGroup, ULONG commandId, HRESULT defaultState)
|
|
{
|
|
HWND hBrowser = GetParent(hwnd);
|
|
HRESULT commandState = Toolbar_GetServiceCommandState(hBrowser, serviceCommand, commandGroup, commandId, defaultState);
|
|
if (CMDSTATE_ENABLED != commandState)
|
|
return ITEM_ERR;
|
|
|
|
return Toolbar_AddItemHelper(hwnd, pszName, overrideStyle);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnAutoPopulate(HWND hwnd, ifc_omservice *service, UINT flags)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar || NULL == toolbar->items)
|
|
return 0;
|
|
|
|
ifc_omservicecommand *serviceCommand;
|
|
if (NULL == service || FAILED(service->QueryInterface(IFC_OmServiceCommand, (void**)&serviceCommand)))
|
|
serviceCommand = NULL;
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
|
|
Toolbar_ClearItems(toolbar);
|
|
|
|
ToolbarItem *item;
|
|
HRESULT commandStatus;
|
|
size_t blockSize, currentSize;
|
|
|
|
HWND hBrowser = GetParent(hwnd);
|
|
|
|
// Back/Forward
|
|
commandStatus = Toolbar_GetServiceCommandState(hBrowser, serviceCommand, &CMDGROUP_NAVIGATION, NAVCOMMAND_BACKFORWARD, CMDSTATE_ENABLED);
|
|
if (SUCCEEDED(commandStatus))
|
|
{
|
|
Toolbar_AddItemHelper(hwnd, TOOLITEM_BUTTON_BACK, ToolbarItem::stateDisabled);
|
|
Toolbar_AddItemHelper(hwnd, TOOLITEM_BUTTON_FORWARD, ToolbarItem::stateDisabled);
|
|
|
|
// History
|
|
if (0 != toolbar->items->size())
|
|
{
|
|
Toolbar_AddItemHelper2(hwnd, TOOLITEM_BUTTON_HISTORY, ToolbarItem::stateDisabled | ToolbarItem::styleNoChevron,
|
|
serviceCommand, &CMDGROUP_NAVIGATION, NAVCOMMAND_HISTORY, CMDSTATE_ENABLED);
|
|
}
|
|
}
|
|
|
|
blockSize = toolbar->items->size();
|
|
|
|
// Home
|
|
Toolbar_AddItemHelper2(hwnd, TOOLITEM_BUTTON_HOME, ToolbarItem::stateDisabled,
|
|
serviceCommand, &CMDGROUP_NAVIGATION, NAVCOMMAND_HOME, CMDSTATE_ENABLED);
|
|
|
|
// Refresh
|
|
Toolbar_AddItemHelper2(hwnd, TOOLITEM_BUTTON_REFRESH, ToolbarItem::stateDisabled,
|
|
serviceCommand, &CMDGROUP_NAVIGATION, NAVCOMMAND_REFRESH, CMDSTATE_ENABLED);
|
|
|
|
// Stop
|
|
Toolbar_AddItemHelper2(hwnd, TOOLITEM_BUTTON_STOP, ToolbarItem::stateDisabled,
|
|
serviceCommand, &CMDGROUP_NAVIGATION, NAVCOMMAND_STOP, CMDSTATE_ENABLED);
|
|
|
|
currentSize = toolbar->items->size();
|
|
if (0 != blockSize && 0 != currentSize && blockSize != currentSize)
|
|
Toolbar_InsertItemHelper(hwnd, TOOLITEM_SPACE, ToolbarItem::styleNoChevron, (INT)blockSize);
|
|
|
|
BOOL fShowFlexSpace = TRUE;
|
|
|
|
// Addressbar
|
|
UINT style = ToolbarItem::styleNoChevron | ToolbarItem::stateDisabled | ToolbarItem::stylePopup;
|
|
|
|
if (0 == (TBS_FORCEADDRESS & windowStyle) &&
|
|
CMDSTATE_ENABLED != Toolbar_GetServiceCommandState(hBrowser, serviceCommand,
|
|
&CMDGROUP_ADDRESSBAR, ADDRESSCOMMAND_VISIBLE,
|
|
(0 != (TBS_SHOWADDRESS & windowStyle)) ? CMDSTATE_ENABLED : CMDSTATE_DISABLED))
|
|
{
|
|
style |= ToolbarItem::stateHidden;
|
|
}
|
|
|
|
if (CMDSTATE_ENABLED == Toolbar_GetServiceCommandState(hBrowser, serviceCommand,
|
|
&CMDGROUP_ADDRESSBAR, ADDRESSCOMMAND_READONLY,
|
|
(0 != (TBPF_READONLYADDRESS & flags) ? CMDSTATE_ENABLED : CMDSTATE_DISABLED)))
|
|
{
|
|
style |= ToolbarAddress::styleAddressReadonly;
|
|
}
|
|
|
|
if (0 == (TBS_FANCYADDRESS & windowStyle))
|
|
style |= ToolbarAddress::styleAddressShowReal;
|
|
|
|
if (ITEM_ERR != Toolbar_AddItemHelper(hwnd, TOOLITEM_ADDRESSBAR, style))
|
|
{
|
|
currentSize++;
|
|
if (0 == (ToolbarItem::stateHidden & style))
|
|
fShowFlexSpace = FALSE;
|
|
}
|
|
|
|
|
|
|
|
if (0 != currentSize)
|
|
{
|
|
Toolbar_AddItemHelper(hwnd, TOOLITEM_FLEXSPACE, ToolbarItem::stylePopup | ((FALSE == fShowFlexSpace) ? ToolbarItem::stateHidden : 0));
|
|
}
|
|
|
|
if (NULL != serviceCommand && 0 == (TBPF_NOSERVICECOMMANDS & flags))
|
|
{
|
|
blockSize = toolbar->items->size();
|
|
|
|
// Rating
|
|
commandStatus = Toolbar_GetServiceCommandState(hBrowser, serviceCommand, &CMDGROUP_SERVICE, SVCCOMMAND_RATE, CMDSTATE_UNKNOWN);
|
|
if (SUCCEEDED(commandStatus))
|
|
{
|
|
UINT rating;
|
|
if (NULL != service && SUCCEEDED(service->GetRating(&rating)))
|
|
{
|
|
if (ITEM_ERR != Toolbar_AddItemHelper(hwnd, TOOLITEM_USERRATING, 0))
|
|
Toolbar_SetItemInt(hwnd, TOOLITEM_USERRATING, rating);
|
|
}
|
|
}
|
|
|
|
// Show Info
|
|
Toolbar_AddItemHelper2(hwnd, TOOLITEM_CMDLINK_INFO, ToolbarItem::styleChevronOnly,
|
|
serviceCommand, &CMDGROUP_SERVICE, SVCCOMMAND_SHOWINFO, CMDSTATE_UNKNOWN);
|
|
|
|
// Report
|
|
Toolbar_AddItemHelper2(hwnd, TOOLITEM_CMDLINK_REPORT, ToolbarItem::styleChevronOnly,
|
|
serviceCommand, &CMDGROUP_SERVICE, SVCCOMMAND_REPORT, CMDSTATE_UNKNOWN);
|
|
|
|
// Remove
|
|
Toolbar_AddItemHelper2(hwnd, TOOLITEM_CMDLINK_UNSUBSCRIBE, ToolbarItem::styleChevronOnly,
|
|
serviceCommand, &CMDGROUP_SERVICE, SVCCOMMAND_UNSUBSCRIBE, CMDSTATE_UNKNOWN);
|
|
|
|
currentSize = toolbar->items->size();
|
|
|
|
if (0 != currentSize && blockSize != currentSize)
|
|
Toolbar_AddItemHelper(hwnd, TOOLITEM_SEPARATOR, ToolbarItem::styleChevronOnly);
|
|
|
|
}
|
|
|
|
const TOOLBARITEMINSERTREC szBrowserTools[] =
|
|
{
|
|
{ TOOLITEM_BUTTON_SECURECONNECTION, ToolbarItem::stateHidden | ToolbarItem::stylePopup | ToolbarItem::styleNoChevron /*| TBIS_NOREMOVE*/ },
|
|
{ TOOLITEM_BUTTON_SCRIPTERROR, ToolbarItem::stateHidden | ToolbarItem::stylePopup | ToolbarItem::styleNoChevron /*| TBIS_NOREMOVE*/},
|
|
{ TOOLITEM_DOWNLOADPROGRESS, ToolbarItem::styleNoChevron | ToolbarItem::stateDisabled /*| TBIS_NOREMOVE*/},
|
|
};
|
|
|
|
for (INT i = 0; i < ARRAYSIZE(szBrowserTools); i++)
|
|
{
|
|
item = Toolbar_CreateItem(szBrowserTools[i].name, szBrowserTools[i].style);
|
|
if (NULL != item)
|
|
{
|
|
Toolbar_InsertItemInternal(toolbar, item, TBIP_LAST, hwnd);
|
|
item->Release();
|
|
}
|
|
}
|
|
|
|
if (0 == (TBS_LOCKUPDATE & windowStyle))
|
|
{
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
Toolbar_UpdateLayout(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
if (NULL != serviceCommand)
|
|
serviceCommand->Release();
|
|
|
|
return (INT)(INT_PTR)toolbar->items->size();
|
|
|
|
}
|
|
|
|
static LRESULT Toolbar_OnEnableBottomDock(HWND hwnd, BOOL fEnable)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
UINT newStyle = windowStyle;
|
|
|
|
if (FALSE == fEnable)
|
|
newStyle &= ~TBS_BOTTOMDOCK;
|
|
else
|
|
newStyle |= TBS_BOTTOMDOCK;
|
|
|
|
if(newStyle == windowStyle)
|
|
return fEnable;
|
|
|
|
if (0 != (TBS_AUTOHIDE & windowStyle))
|
|
{
|
|
HWND hFocus = GetFocus();
|
|
if (hwnd == hFocus || IsChild(hwnd, hFocus))
|
|
Toolbar_AutoHideWindow(hwnd, TRUE);
|
|
}
|
|
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
|
|
|
|
|
|
HWND hParent = GetParent(hwnd);
|
|
if (NULL != hParent)
|
|
{
|
|
SetWindowPos(hParent, NULL, 0, 0, 0, 0,
|
|
SWP_NOSIZE |SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
|
}
|
|
|
|
HWND insertAfter = HWND_TOP;
|
|
if (0 != (TBS_BOTTOMDOCK & newStyle))
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar ||
|
|
0 == (TBS_AUTOHIDE & windowStyle) ||
|
|
0 != (TBS_HIDDEN & toolbar->flags))
|
|
{
|
|
insertAfter = HWND_BOTTOM;
|
|
}
|
|
}
|
|
|
|
SetWindowPos(hwnd, insertAfter, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
|
|
return !fEnable;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnEnableAutoHide(HWND hwnd, BOOL fEnable)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return 0;
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
UINT newStyle = windowStyle;
|
|
|
|
KillTimer(hwnd, TIMER_AUTOHIDE_ID);
|
|
toolbar->flags &= ~TBS_HIDETIMERSET;
|
|
|
|
if (FALSE == fEnable)
|
|
{
|
|
newStyle &= ~TBS_AUTOHIDE;
|
|
toolbar->flags &= ~TBS_HIDDEN;
|
|
}
|
|
else
|
|
{
|
|
newStyle |= TBS_AUTOHIDE;
|
|
|
|
HWND hFocus = GetFocus();
|
|
if (hwnd != hFocus && FALSE == IsChild(hwnd, hFocus))
|
|
toolbar->flags |= TBS_HIDDEN;
|
|
}
|
|
|
|
if(newStyle == windowStyle)
|
|
return fEnable;
|
|
|
|
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
|
|
|
|
HWND hParent = GetParent(hwnd);
|
|
if (NULL != hParent)
|
|
{
|
|
SetWindowPos(hParent, NULL, 0, 0, 0, 0,
|
|
SWP_NOSIZE |SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
|
}
|
|
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
|
|
return !fEnable;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnEnableTabStop(HWND hwnd, BOOL fEnable)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
UINT newStyle = windowStyle;
|
|
|
|
if (FALSE == fEnable)
|
|
newStyle &= ~TBS_TABSTOP;
|
|
else
|
|
newStyle |= TBS_TABSTOP;
|
|
|
|
if(newStyle == windowStyle)
|
|
return fEnable;
|
|
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
|
|
|
|
Toolbar_UpdateTabstop(hwnd);
|
|
|
|
return !fEnable;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnEnableForceAddress(HWND hwnd, BOOL fEnable)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
UINT newStyle = windowStyle;
|
|
|
|
if (FALSE == fEnable)
|
|
newStyle &= ~TBS_FORCEADDRESS;
|
|
else
|
|
newStyle |= TBS_FORCEADDRESS;
|
|
|
|
if(newStyle == windowStyle)
|
|
return fEnable;
|
|
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && NULL != toolbar->items)
|
|
{
|
|
size_t index = toolbar->items->size();
|
|
while(index--)
|
|
{
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL != item && item->IsEqual(TOOLITEM_ADDRESSBAR, -1))
|
|
{
|
|
UINT itemStyle = item->GetStyle();
|
|
if (FALSE != fEnable)
|
|
{
|
|
if (0 != (ToolbarItem::stateHidden & itemStyle))
|
|
{
|
|
Toolbar_LockUpdate(hwnd, TRUE);
|
|
if (FALSE != Toolbar_ShowItem(hwnd, MAKEINTRESOURCE(index), TRUE))
|
|
{
|
|
size_t nextIndex = index + 1;
|
|
if (nextIndex < toolbar->items->size())
|
|
{
|
|
ToolbarItem *nextItem = toolbar->items->at(nextIndex);
|
|
if (NULL != nextItem && nextItem->IsEqual(TOOLITEM_FLEXSPACE, -1))
|
|
{
|
|
Toolbar_ShowItem(hwnd, MAKEINTRESOURCE(nextIndex), FALSE);
|
|
}
|
|
}
|
|
}
|
|
Toolbar_LockUpdate(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HRESULT commandState = E_NOTIMPL;
|
|
HWND hBrowser = GetParent(hwnd);
|
|
ifc_omservice *service;
|
|
if (NULL != hBrowser && FALSE != BrowserControl_GetService(hBrowser, &service))
|
|
{
|
|
ifc_omservicecommand *serviceCommand;
|
|
if (SUCCEEDED(service->QueryInterface(IFC_OmServiceCommand, (void**)&serviceCommand)))
|
|
{
|
|
commandState = serviceCommand->QueryState(hBrowser, &CMDGROUP_ADDRESSBAR, ADDRESSCOMMAND_VISIBLE);
|
|
serviceCommand->Release();
|
|
}
|
|
service->Release();
|
|
}
|
|
|
|
if (E_NOTIMPL == commandState)
|
|
commandState = (0 != (TBS_SHOWADDRESS & windowStyle)) ? CMDSTATE_ENABLED : CMDSTATE_DISABLED;
|
|
|
|
if (0 == (ToolbarItem::stateHidden & itemStyle) && CMDSTATE_ENABLED != commandState)
|
|
{
|
|
Toolbar_LockUpdate(hwnd, TRUE);
|
|
if (FALSE != Toolbar_ShowItem(hwnd, MAKEINTRESOURCE(index), FALSE))
|
|
{
|
|
size_t nextIndex = index + 1;
|
|
if (nextIndex < toolbar->items->size())
|
|
{
|
|
ToolbarItem *nextItem = toolbar->items->at(nextIndex);
|
|
if (NULL != nextItem && nextItem->IsEqual(TOOLITEM_FLEXSPACE, -1))
|
|
{
|
|
Toolbar_ShowItem(hwnd, MAKEINTRESOURCE(nextIndex), TRUE);
|
|
}
|
|
}
|
|
}
|
|
Toolbar_LockUpdate(hwnd, FALSE);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
}
|
|
|
|
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return !fEnable;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnEnableFancyAddress(HWND hwnd, BOOL fEnable)
|
|
{
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
UINT newStyle = windowStyle;
|
|
|
|
if (FALSE == fEnable)
|
|
newStyle &= ~TBS_FANCYADDRESS;
|
|
else
|
|
newStyle |= TBS_FANCYADDRESS;
|
|
|
|
if(newStyle == windowStyle)
|
|
return fEnable;
|
|
|
|
SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL != toolbar && NULL != toolbar->items)
|
|
{
|
|
size_t index = toolbar->items->size();
|
|
while(index--)
|
|
{
|
|
ToolbarItem *item = toolbar->items->at(index);
|
|
if (NULL != item && item->IsEqual(TOOLITEM_ADDRESSBAR, -1))
|
|
{
|
|
UINT style = (FALSE != fEnable) ? 0 : ToolbarAddress::styleAddressShowReal;
|
|
item->SetStyle(hwnd, style, ToolbarAddress::styleAddressShowReal);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return !fEnable;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnSetBrowserHost(HWND hwnd, HWND hBrowser)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return 0;
|
|
|
|
toolbar->hBrowser = hBrowser;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static LRESULT Toolbar_OnGetImageListHeight(HWND hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
INT iconCX, iconCY;
|
|
if (NULL == toolbar ||
|
|
NULL == toolbar->imageList ||
|
|
FALSE == ImageList_GetIconSize(toolbar->imageList, &iconCX, &iconCY))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return iconCY/TOOLBAR_ICONSTATE_COUNT;
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetNextTabItem(HWND hwnd, LPCSTR pszName, BOOL fPrevious)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return ITEM_ERR;
|
|
|
|
INT index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index)
|
|
return ITEM_ERR;
|
|
|
|
if (0 == index && FALSE == fPrevious)
|
|
return ITEM_ERR;
|
|
|
|
UINT windowStyle = GetWindowStyle(hwnd);
|
|
BOOL fTabstopOnly = (0 == (TBS_TABSTOP & windowStyle));
|
|
INT direction = (FALSE == fPrevious) ? 1 : -1;
|
|
return Toolbar_GetFocusIndex(hwnd, index + direction, direction, fTabstopOnly);
|
|
}
|
|
|
|
static void Toolbar_OnCheckHide(HWND hwnd, BOOL fImmediate)
|
|
{
|
|
Toolbar_AutoHideWindow(hwnd, fImmediate);
|
|
}
|
|
|
|
static LRESULT Toolbar_OnGetTextLength(HWND hwnd, LPCSTR pszName, size_t *textLength)
|
|
{
|
|
if (NULL == textLength) return FALSE;
|
|
*textLength = 0;
|
|
|
|
TOOLBAR *toolbar = GetToolbar(hwnd);
|
|
if (NULL == toolbar) return FALSE;
|
|
|
|
size_t index = Toolbar_ResolveName(hwnd, pszName);
|
|
if (ITEM_ERR == index) return FALSE;
|
|
|
|
ToolbarItem *item = Toolbar_GetItem(toolbar, index);
|
|
if (NULL == item) return FALSE;
|
|
|
|
if (FAILED(item->GetTextLength(textLength)))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static LRESULT CALLBACK Toolbar_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE: return Toolbar_OnCreate(hwnd, (CREATESTRUCT*)lParam);
|
|
case WM_DESTROY: Toolbar_OnDestroy(hwnd); break;
|
|
case WM_PAINT: Toolbar_OnPaint(hwnd); return 0;
|
|
case WM_PRINTCLIENT: Toolbar_OnPrintClient(hwnd, (HDC)wParam, (UINT)lParam); return 0;
|
|
case WM_ERASEBKGND: return 0;
|
|
case WM_WINDOWPOSCHANGED: Toolbar_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return 0;
|
|
case WM_SETREDRAW: Toolbar_OnSetRedraw(hwnd, (BOOL)wParam); return 0;
|
|
case WM_MOUSEMOVE: Toolbar_OnMouseMove(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); return 0;
|
|
case WM_MOUSELEAVE: Toolbar_OnMouseLeave(hwnd); return 0;
|
|
case WM_LBUTTONDOWN:
|
|
Toolbar_OnLButtonDown(hwnd, (UINT)wParam, MAKEPOINTS(lParam));
|
|
break;
|
|
case WM_LBUTTONUP: Toolbar_OnLButtonUp(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); break;
|
|
case WM_RBUTTONDOWN: Toolbar_OnRButtonDown(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); break;
|
|
case WM_RBUTTONUP: Toolbar_OnRButtonUp(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); break;
|
|
case WM_MBUTTONDOWN: Toolbar_OnMButtonDown(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); break;
|
|
case WM_MBUTTONUP: Toolbar_OnMButtonUp(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); break;
|
|
case WM_CAPTURECHANGED: Toolbar_OnCaptureChanged(hwnd, (HWND)lParam); return 0;
|
|
case WM_GETFONT: return Toolbar_OnGetFont(hwnd);
|
|
case WM_SETFONT: Toolbar_OnSetFont(hwnd, (HFONT)wParam, (BOOL)LOWORD(lParam)); return 0;
|
|
case WM_NOTIFY: return Toolbar_OnNotify(hwnd, (INT)wParam, (NMHDR*)lParam);
|
|
case WM_COMMAND: Toolbar_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return 0;
|
|
case WM_ENTERMENULOOP: Toolbar_OnEnterMenuLoop(hwnd, (BOOL)wParam); return 0;
|
|
case WM_EXITMENULOOP: Toolbar_OnExitMenuLoop(hwnd, (BOOL)wParam); return 0;
|
|
case WM_SETFOCUS: Toolbar_OnSetFocus(hwnd, (HWND)wParam); return 0;
|
|
case WM_KILLFOCUS: Toolbar_OnKillFocus(hwnd, (HWND)wParam); return 0;
|
|
case WM_CONTEXTMENU: Toolbar_OnContextMenu(hwnd, (HWND)wParam, MAKEPOINTS(lParam)); return 0;
|
|
case WM_KEYDOWN: Toolbar_OnKeyDown(hwnd, (INT)wParam, (UINT)lParam); return 0;
|
|
case WM_KEYUP: Toolbar_OnKeyUp(hwnd, (INT)wParam, (UINT)lParam); return 0;
|
|
case WM_GETDLGCODE: return Toolbar_OnGetDlgCode(hwnd, (INT)wParam, (MSG*)lParam);
|
|
case WM_UPDATEUISTATE: Toolbar_OnUpdateUiState(hwnd, LOWORD(wParam), HIWORD(wParam)); return 0;
|
|
case WM_ENABLE: Toolbar_OnEnable(hwnd, (BOOL)wParam); return 0;
|
|
case WM_SETCURSOR: return Toolbar_OnSetCursor(hwnd, (HWND)wParam, LOWORD(lParam), HIWORD(lParam));
|
|
case WM_CTLCOLOREDIT: return Toolbar_OnColorEdit(hwnd, (HDC)wParam, (HWND)lParam);
|
|
case WM_CTLCOLORSTATIC: return Toolbar_OnColorStatic(hwnd, (HDC)wParam, (HWND)lParam);
|
|
|
|
case TBM_UPDATESKIN: Toolbar_OnUpdateSkin(hwnd, (BOOL)lParam); return 0;
|
|
case TBM_GETIDEALHEIGHT: return Toolbar_OnGetIdealHeight(hwnd);
|
|
case TBM_GETICONSIZE: return Toolbar_OnGetIconSize(hwnd, (INT)wParam, (SIZE*)lParam);
|
|
case TBM_SENDCOMMAND: return Toolbar_OnSendCommand(hwnd, (INT)wParam);
|
|
case TBM_DRAWICON: return Toolbar_OnDrawIcon(hwnd, (TOOLBARDRAWICONPARAM*)lParam);
|
|
case TBM_GETITEMCOUNT: return Toolbar_OnGetItemCount(hwnd);
|
|
case TBM_CLEAR: return Toolbar_OnClear(hwnd);
|
|
case TBM_INSERTITEM: return Toolbar_OnInsertItem(hwnd, (TOOLBARINSERTITEM*)lParam);
|
|
case TBM_FINDITEM: return Toolbar_OnFindItem(hwnd, (LPCSTR)lParam);
|
|
case TBM_REMOVEITEM: return Toolbar_OnRemoveItem(hwnd, (LPCSTR)lParam);
|
|
case TBM_SETITEMINT: return Toolbar_OnSetItemInt(hwnd, (LPCSTR)lParam, (INT)wParam);
|
|
case TBM_SETITEMSTRING: return Toolbar_OnSetItemString(hwnd, (LPCSTR)lParam, (LPCWSTR)wParam);
|
|
case TBM_GETBKCOLOR: return Toolbar_OnGetBkColor(hwnd);
|
|
case TBM_GETFGCOLOR: return Toolbar_OnGetFgColor(hwnd);
|
|
case TBM_GETTEXTCOLOR: return Toolbar_OnGetTextColor(hwnd);
|
|
case TBM_GETHILITECOLOR: return Toolbar_OnGetHiliteColor(hwnd);
|
|
case TBM_ENABLEITEM: return Toolbar_OnEnableItem(hwnd,(LPCSTR)lParam, (BOOL)wParam);
|
|
case TBM_SHOWITEM: return Toolbar_OnShowItem(hwnd,(LPCSTR)lParam, (BOOL)wParam);
|
|
case TBM_UPDATETIP: Toolbar_OnUpdateTip(hwnd); return 0;
|
|
case TBM_GETTEXTMETRICS: return Toolbar_OnGetTextMetrics(hwnd, (TOOLBARTEXTMETRIC*)lParam);
|
|
case TBM_GETBKBRUSH: return Toolbar_OnGetBkBrush(hwnd);
|
|
case TBM_LAYOUT: return Toolbar_OnLayout(hwnd, (TOOLBARLAYOUT*)lParam);
|
|
case TBM_NEXTITEM: return Toolbar_OnNextItem(hwnd, (LPCSTR)lParam, (BOOL)wParam);
|
|
case TBM_GETITEMSTYLE: return Toolbar_OnGetItemStyle(hwnd, (LPCSTR)lParam, (UINT)wParam);
|
|
case TBM_GETITEMCOMMAND: return Toolbar_OnGetItemCommand(hwnd, (LPCSTR)lParam);
|
|
case TBM_SETITEMDESCRIPTION:return Toolbar_OnSetItemDescription(hwnd, (LPCSTR)lParam, (LPCWSTR)wParam);
|
|
case TBM_GETITEMINFO: return Toolbar_OnGetItemInfo(hwnd, (LPCSTR)lParam, (TBITEMINFO*)wParam);
|
|
case TBM_AUTOPOPULATE: return Toolbar_OnAutoPopulate(hwnd, (ifc_omservice*)lParam, (UINT)wParam);
|
|
case TBM_ENABLEBOTTOMDOCK: return Toolbar_OnEnableBottomDock(hwnd, (BOOL)lParam);
|
|
case TBM_ENABLEAUTOHIDE: return Toolbar_OnEnableAutoHide(hwnd, (BOOL)lParam);
|
|
case TBM_ENABLETABSTOP: return Toolbar_OnEnableTabStop(hwnd, (BOOL)lParam);
|
|
case TBM_ENABLEFORCEADDRESS: return Toolbar_OnEnableForceAddress(hwnd, (BOOL)lParam);
|
|
case TBM_ENABLEFANCYADDRESS: return Toolbar_OnEnableFancyAddress(hwnd, (BOOL)lParam);
|
|
case TBM_SETBROWSERHOST: return Toolbar_OnSetBrowserHost(hwnd, (HWND)lParam);
|
|
case TBM_GETEDITCOLOR: return Toolbar_OnGetEditColor(hwnd);
|
|
case TBM_GETEDITBKCOLOR: return Toolbar_OnGetEditBkColor(hwnd);
|
|
case TBM_GETIMAGELISTHEIGHT:return Toolbar_OnGetImageListHeight(hwnd);
|
|
case TBM_GETNEXTTABITEM: return Toolbar_OnGetNextTabItem(hwnd, (LPCSTR)lParam, (BOOL)wParam);
|
|
case TBM_CHECKHIDE: Toolbar_OnCheckHide(hwnd, (BOOL)lParam); return 0;
|
|
case TBM_GETTEXTLENGTH: return Toolbar_OnGetTextLength(hwnd, (LPCSTR)lParam, (size_t*)wParam);
|
|
}
|
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
static LRESULT CALLBACK Toolbar_MouseHook(INT code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
TOOLBARMOUSEHOOK *hook = (TOOLBARMOUSEHOOK*)Plugin_TlsGetValue(tlsIndex);
|
|
if (NULL == hook || NULL == hook->hHook) return FALSE;
|
|
|
|
|
|
if (code >= 0)
|
|
{
|
|
MOUSEHOOKSTRUCT *mouseHook = (MOUSEHOOKSTRUCT*)lParam;
|
|
if (mouseHook->hwnd != hook->hwnd)
|
|
{
|
|
TOOLBAR *toolbar = GetToolbar(hook->hwnd);
|
|
if (NULL != toolbar)
|
|
{
|
|
if (0 != (TBS_HIDDEN & toolbar->flags))
|
|
{
|
|
Toolbar_RemoveMouseHook(hook->hwnd, TRUE);
|
|
}
|
|
else if (0 == ((TBS_MENULOOP | TBS_HIDETIMERSET) & toolbar->flags))
|
|
{
|
|
HWND hAncestor = GetAncestor(mouseHook->hwnd, GA_ROOT);
|
|
BOOL autoHide;
|
|
if (NULL == hAncestor || FALSE == IsChild(hAncestor, hook->hwnd))
|
|
{
|
|
autoHide = TRUE;
|
|
}
|
|
else
|
|
{
|
|
RECT toolbarRect;
|
|
if (!GetWindowRect(hook->hwnd, &toolbarRect))
|
|
SetRectEmpty(&toolbarRect);
|
|
toolbarRect.top -= 6;
|
|
toolbarRect.bottom += 6;
|
|
autoHide = !PtInRect(&toolbarRect, mouseHook->pt);
|
|
}
|
|
|
|
if (FALSE != autoHide)
|
|
Toolbar_AutoHideWindow(hook->hwnd, FALSE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return CallNextHookEx(hook->hHook, code, wParam, lParam);
|
|
} |