diff options
Diffstat (limited to 'WebCore/platform/win/ContextMenuWin.cpp')
-rw-r--r-- | WebCore/platform/win/ContextMenuWin.cpp | 196 |
1 files changed, 40 insertions, 156 deletions
diff --git a/WebCore/platform/win/ContextMenuWin.cpp b/WebCore/platform/win/ContextMenuWin.cpp index 10443aa..24c355d 100644 --- a/WebCore/platform/win/ContextMenuWin.cpp +++ b/WebCore/platform/win/ContextMenuWin.cpp @@ -32,6 +32,7 @@ #include "Node.h" #include <tchar.h> #include <windows.h> +#include <wtf/Vector.h> #include <wtf/text/CString.h> #ifndef MIIM_FTYPE @@ -43,184 +44,67 @@ namespace WebCore { -ContextMenu::ContextMenu(const HitTestResult& result) - : m_hitTestResult(result) - , m_platformDescription(0) -#if OS(WINCE) - , m_itemCount(0) -#endif +ContextMenu::ContextMenu(HMENU menu) { - setPlatformDescription(::CreatePopupMenu()); -} - -ContextMenu::ContextMenu(const HitTestResult& result, const PlatformMenuDescription menu) - : m_hitTestResult(result) - , m_platformDescription(0) -#if OS(WINCE) - , m_itemCount(0) -#endif -{ - setPlatformDescription(menu); -} - -ContextMenu::~ContextMenu() -{ - if (m_platformDescription) - ::DestroyMenu(m_platformDescription); -} - -unsigned ContextMenu::itemCount() const -{ -#if OS(WINCE) - return m_itemCount; -#else - if (!m_platformDescription) - return 0; - - return ::GetMenuItemCount(m_platformDescription); -#endif + getContextMenuItems(menu, m_items); } -#if OS(WINCE) -static bool insertMenuItem(PlatformMenuDescription menu, unsigned int position, ContextMenuItem& item) +void ContextMenu::getContextMenuItems(HMENU menu, Vector<ContextMenuItem>& items) { - UINT flags = MF_BYPOSITION; - UINT newItem = 0; - LPCWSTR title = 0; - - if (item.type() == SeparatorType) - flags |= MF_SEPARATOR; - else { - flags |= MF_STRING; - flags |= item.checked() ? MF_CHECKED : MF_UNCHECKED; - flags |= item.enabled() ? MF_ENABLED : MF_GRAYED; - - PlatformMenuItemDescription description = item.releasePlatformDescription(); - title = description->dwTypeData; - description->dwTypeData = 0; - - if (description->hSubMenu) { - flags |= MF_POPUP; - newItem = reinterpret_cast<UINT>(description->hSubMenu); - description->hSubMenu = 0; - } else - newItem = description->wID; - - free(description); - } - - return ::InsertMenuW(menu, position, flags, newItem, title); -} -#endif - -void ContextMenu::insertItem(unsigned int position, ContextMenuItem& item) -{ - if (!m_platformDescription) + int count = ::GetMenuItemCount(menu); + if (count <= 0) return; - checkOrEnableIfNeeded(item); + for (int i = 0; i < count; ++i) { + MENUITEMINFO info = {0}; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU; -#if OS(WINCE) - if (insertMenuItem(m_platformDescription, position, item)) - ++m_itemCount; -#else - ::InsertMenuItem(m_platformDescription, position, TRUE, item.releasePlatformDescription()); -#endif -} - -void ContextMenu::appendItem(ContextMenuItem& item) -{ - insertItem(itemCount(), item); -} + if (!::GetMenuItemInfo(menu, i, TRUE, &info)) + continue; -static ContextMenuItem* contextMenuItemByIdOrPosition(HMENU menu, unsigned id, BOOL byPosition) -{ - if (!menu) - return 0; - LPMENUITEMINFO info = static_cast<LPMENUITEMINFO>(malloc(sizeof(MENUITEMINFO))); - if (!info) - return 0; - - memset(info, 0, sizeof(MENUITEMINFO)); - - info->cbSize = sizeof(MENUITEMINFO); - - // Setting MIIM_DATA which is useful for WebKit clients who store data in this member for their custom menu items. - info->fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_DATA; - - if (!::GetMenuItemInfo(menu, id, byPosition, info)) { - free(info); - return 0; - } - - if (info->fType & MFT_STRING) { - LPTSTR buffer = static_cast<LPTSTR>(malloc(++info->cch * sizeof(TCHAR))); - if (!buffer) { - free(info); - return 0; + if (info.fType == MFT_SEPARATOR) { + items.append(ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String())); + continue; } - info->dwTypeData = buffer; - ::GetMenuItemInfo(menu, id, byPosition, info); - } - - return new ContextMenuItem(info); -} -ContextMenuItem* ContextMenu::itemWithAction(unsigned action) -{ - return contextMenuItemByIdOrPosition(m_platformDescription, action, FALSE); -} + int menuStringLength = info.cch + 1; + OwnArrayPtr<WCHAR> menuString(new WCHAR[menuStringLength]); + info.dwTypeData = menuString.get(); + info.cch = menuStringLength; -ContextMenuItem* ContextMenu::itemAtIndex(unsigned index, const PlatformMenuDescription platformDescription) -{ - return contextMenuItemByIdOrPosition(platformDescription, index, TRUE); + if (::GetMenuItemInfo(menu, i, TRUE, &info)) + items.append(ContextMenuItem(info)); + } } -void ContextMenu::setPlatformDescription(HMENU menu) +HMENU ContextMenu::createNativeMenuFromItems(const Vector<ContextMenuItem>& items) { - if (menu == m_platformDescription) - return; - - if (m_platformDescription) - ::DestroyMenu(m_platformDescription); + HMENU menu = ::CreatePopupMenu(); - m_platformDescription = menu; - if (!m_platformDescription) - return; + for (size_t i = 0; i < items.size(); ++i) { + const ContextMenuItem& item = items[i]; -#if !OS(WINCE) - MENUINFO menuInfo = {0}; - menuInfo.cbSize = sizeof(MENUINFO); - menuInfo.fMask = MIM_STYLE; - ::GetMenuInfo(m_platformDescription, &menuInfo); - menuInfo.fMask = MIM_STYLE; - menuInfo.dwStyle |= MNS_NOTIFYBYPOS; - ::SetMenuInfo(m_platformDescription, &menuInfo); -#endif -} + MENUITEMINFO menuItem = item.nativeMenuItem(); -HMENU ContextMenu::platformDescription() const -{ - return m_platformDescription; -} + // ContextMenuItem::nativeMenuItem doesn't set the title of the MENUITEMINFO to make the + // lifetime handling easier for callers. + String itemTitle = item.title(); + if (item.type() != SeparatorType) { + menuItem.fMask |= MIIM_STRING; + menuItem.cch = itemTitle.length(); + menuItem.dwTypeData = const_cast<LPWSTR>(itemTitle.charactersWithNullTermination()); + } -HMENU ContextMenu::releasePlatformDescription() -{ - HMENU description = m_platformDescription; - m_platformDescription = 0; - return description; -} + ::InsertMenuItem(menu, i, TRUE, &menuItem); + } -Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription) -{ - // FIXME - Implement - return Vector<ContextMenuItem>(); + return menu; } -PlatformMenuDescription platformMenuDescription(Vector<ContextMenuItem>& menuItemVector) +HMENU ContextMenu::nativeMenu() const { - // FIXME - Implement - return 0; + return createNativeMenuFromItems(m_items); } } // namespace WebCore |