Exemple #1
0
BOOL CIconMenu::AppendMenuIcon(UINT_PTR nIDNewItem, LPCTSTR lpszNewItem, UINT uIcon /* = 0 */,  HMENU hsubmenu)
{
	TCHAR menutextbuffer[255] = {0};
	_tcscpy_s(menutextbuffer, 255, lpszNewItem);

	if (uIcon == 0)
		return CMenu::AppendMenu(MF_STRING | MF_ENABLED, nIDNewItem, menutextbuffer);

	MENUITEMINFO info = {0};
	info.cbSize = sizeof(info);
	info.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
	info.fType = MFT_STRING;

	if(hsubmenu)
	{
		info.fMask |= MIIM_SUBMENU;
		info.hSubMenu = hsubmenu;
	}


	info.wID = (UINT)nIDNewItem;
	info.dwTypeData = menutextbuffer;
	if (SysInfo::Instance().IsVistaOrLater())
	{
		info.fMask |= MIIM_BITMAP;
		info.hbmpItem = IconToBitmapPARGB32(uIcon);
	}
	else
	{
		info.fMask |= MIIM_BITMAP;
		info.hbmpItem = HBMMENU_CALLBACK;
	}
	icons[nIDNewItem] = uIcon;
	return InsertMenuItem((UINT)nIDNewItem, &info);
}
UINT CGitExtensionsShellEx::AddMenuItem(HMENU hMenu, LPTSTR text, int resource, UINT uidFirstCmd, UINT id, UINT position, bool isSubMenu)
{
    MENUITEMINFO mii;
    memset(&mii, 0, sizeof(mii));
    mii.cbSize = sizeof(mii);
    mii.fMask = MIIM_STRING | MIIM_ID;
    if (resource)
    {
        mii.fMask |= MIIM_BITMAP;
        mii.hbmpItem = IsVistaOrLater() ? IconToBitmapPARGB32(resource) : HBMMENU_CALLBACK;
        myIDMap[id] = resource;
        myIDMap[uidFirstCmd + id] = resource;
    }
    mii.wID	= uidFirstCmd + id;
    std::wstring textEx;
    if (isSubMenu)
        mii.dwTypeData = text;
    else
    {
        textEx = std::wstring(L"GitEx ") + text;
        mii.dwTypeData = &textEx[0];
    }

    InsertMenuItem(hMenu, position, TRUE, &mii);
    return id;
}
HBITMAP IconBitmapUtils::IconToBitmapPARGB32(HINSTANCE hInst, UINT uIcon)
{
    std::map<UINT, HBITMAP>::iterator bitmap_it = bitmaps.lower_bound(uIcon);
    if (bitmap_it != bitmaps.end() && bitmap_it->first == uIcon)
        return bitmap_it->second;

    HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(uIcon), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

    HBITMAP hBmp = IconToBitmapPARGB32(hIcon);

    DestroyIcon(hIcon);

    if(hBmp)
        bitmaps.insert(bitmap_it, std::make_pair(uIcon, hBmp));

    return hBmp;
}
HBITMAP IconBitmapUtils::IconToBitmapPARGB32(HINSTANCE hInst, UINT uIcon)
{
	std::map<UINT, HBITMAP>::iterator bitmap_it = bitmaps.lower_bound(uIcon);
	if (bitmap_it != bitmaps.end() && bitmap_it->first == uIcon)
		return bitmap_it->second;
	int iconWidth = GetSystemMetrics(SM_CXSMICON);
	int iconHeight = GetSystemMetrics(SM_CYSMICON);
	auto hIcon = LoadIconEx(hInst, MAKEINTRESOURCE(uIcon), iconWidth, iconHeight);

	HBITMAP hBmp = IconToBitmapPARGB32(hIcon, iconWidth, iconHeight);

	DestroyIcon(hIcon);

	if(hBmp)
		bitmaps.insert(bitmap_it, std::make_pair(uIcon, hBmp));

	return hBmp;
}
void CGitExtensionsShellEx::AddMenuItem(HMENU hMenu, LPSTR text, int resource, int firstId, int id, UINT position)
{
    MENUITEMINFO mii;
    memset(&mii, 0, sizeof(mii));
    mii.cbSize = sizeof(mii);
    mii.fMask = MIIM_STRING | MIIM_ID;
    if (resource)
    {
        mii.fMask |= MIIM_BITMAP;
        mii.hbmpItem = IsVistaOrLater() ? IconToBitmapPARGB32(resource) : HBMMENU_CALLBACK;
        myIDMap[id] = resource;
        myIDMap[firstId + id] = resource;
    }
    mii.wID	= firstId + id;
    mii.dwTypeData	= text;

    InsertMenuItem(hMenu, position, TRUE, &mii);
}
STDMETHODIMP CGitExtensionsShellEx::QueryContextMenu  (
    HMENU hmenu, UINT uMenuIndex, UINT uidFirstCmd,
    UINT uidLastCmd, UINT uFlags )
{
    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
    if ( uFlags & CMF_DEFAULTONLY )
        return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );

    int id = 0;

    CString szCascadeContextMenu = GetRegistryValue(HKEY_CURRENT_USER, "SOFTWARE\\GitExtensions\\GitExtensions", "ShellCascadeContextMenu");

    CascadeContextMenu = !(szCascadeContextMenu == "False");

    if (CascadeContextMenu)
    {
        // show context menu cascaded in submenu
        HMENU popupMenu = CreateMenu();

        id = PopulateMenu(popupMenu, uidFirstCmd, id, true);

        MENUITEMINFO info;

        info.cbSize = sizeof( MENUITEMINFO );
        info.fMask = MIIM_STRING | MIIM_ID | MIIM_BITMAP | MIIM_SUBMENU;
        info.wID = uidFirstCmd + 1;
        info.hbmpItem = IsVistaOrLater() ? IconToBitmapPARGB32(IDI_GITEXTENSIONS) : HBMMENU_CALLBACK;
        myIDMap[1] = IDI_GITEXTENSIONS;
        myIDMap[uidFirstCmd + 1] = IDI_GITEXTENSIONS;
        info.dwTypeData = _T("Git Extensions");
        info.hSubMenu = popupMenu;
        InsertMenuItem(hmenu, 0, true, &info);
    }
    else
    {
        // show menu items directly
        id = PopulateMenu(hmenu, uidFirstCmd, id, false);
    }

    return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, id );
}
STDMETHODIMP CGitExtensionsShellEx::QueryContextMenu  (
    HMENU hMenu, UINT menuIndex, UINT uidFirstCmd,
    UINT uidLastCmd, UINT uFlags )
{
    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
    if ( uFlags & CMF_DEFAULTONLY )
        return S_OK;

    CString szCascadeShellMenuItems = GetRegistryValue(HKEY_CURRENT_USER, L"SOFTWARE\\GitExtensions\\GitExtensions", L"CascadeShellMenuItems");
    if (szCascadeShellMenuItems.IsEmpty())
        szCascadeShellMenuItems = "110111000111111111";
    bool CascadeContextMenu = szCascadeShellMenuItems.Find('1') != -1;
    HMENU popupMenu = NULL;
    if (CascadeContextMenu)
        popupMenu = CreateMenu();

    bool isValidDir = IsValidGitDir(m_szFile);
    bool isFile = IsFileExists(m_szFile);

    // preset values, if not used
    commandsId.clear();

    UINT submenuIndex = 0;
    int id = 0;
    int cmdid;
    bool isSubMenu;

    if (isValidDir)
    {
        if (!isFile)
        {
            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcBrowse);
            cmdid = AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Browse", IDI_ICONBROWSEFILEEXPLORER, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcBrowse;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCommit);
            cmdid = AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Commit", IDI_ICONCOMMIT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCommit;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcPull);
            cmdid = AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Pull", IDI_ICONPULL, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcPull;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcPush);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Push", IDI_ICONPUSH, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcPush;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcStash);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"View stash", IDI_ICONSTASH, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcStash;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcViewDiff);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"View changes", IDI_ICONVIEWCHANGES, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcViewDiff;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCheckoutBranch);
            if (isSubMenu && submenuIndex > 0) {
                InsertMenu(popupMenu, submenuIndex++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); ++id;
            }
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Checkout branch", IDI_ICONBRANCHCHECKOUT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCheckoutBranch;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCheckoutRevision);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Checkout revision", IDI_ICONREVISIONCHECKOUT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCheckoutRevision;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCreateBranch);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Create branch", IDI_ICONBRANCHCREATE, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCreateBranch;
        }

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcDiffTool);
        if (isSubMenu && submenuIndex > 0) {
            InsertMenu(popupMenu, submenuIndex++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); ++id;
        }
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Open with difftool", IDI_ICONVIEWCHANGES, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcDiffTool;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcFileHistory);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"File history", IDI_ICONFILEHISTORY, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcFileHistory;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcResetFileChanges);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Reset file changes", IDI_ICONTRESETFILETO, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcResetFileChanges;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcAddFiles);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Add files", IDI_ICONADDED, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcAddFiles;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcApplyPatch);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Apply patch", 0, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcApplyPatch;
    }
    else 
    {
        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcClone);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Clone", IDI_ICONCLONEREPOGIT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcClone;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCreateRepository);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Create new repository", IDI_ICONCREATEREPOSITORY, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcCreateRepository;
    }

    isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcSettings);
    if (isSubMenu && submenuIndex > 0) {
        InsertMenu(popupMenu, submenuIndex++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); ++id;
    }
    cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Settings", IDI_ICONSETTINGS, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
    commandsId[cmdid]=gcSettings;

    ++id;

    if (CascadeContextMenu)
    {
        MENUITEMINFO info;
        info.cbSize = sizeof( MENUITEMINFO );
        info.fMask = MIIM_STRING | MIIM_ID | MIIM_BITMAP | MIIM_SUBMENU;
        info.wID = uidFirstCmd + 1;
        info.hbmpItem = IsVistaOrLater() ? IconToBitmapPARGB32(IDI_GITEXTENSIONS) : HBMMENU_CALLBACK;
        myIDMap[1] = IDI_GITEXTENSIONS;
        myIDMap[uidFirstCmd + 1] = IDI_GITEXTENSIONS;
        info.dwTypeData = _T("Git Extensions");
        info.hSubMenu = popupMenu;
        InsertMenuItem(hMenu, menuIndex, true, &info);
    }

    return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, id);
}
Exemple #8
0
// *** IContextMenu methods ***
STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/) {
	UINT idCmd = idCmdFirst;

	FORMATETC fmte = {
		CF_HDROP,
		(DVTARGETDEVICE FAR *)NULL,
		DVASPECT_CONTENT,
		-1,
		TYMED_HGLOBAL
	};

	HRESULT hres = m_pDataObj->GetData(&fmte, &m_stgMedium);

	if (SUCCEEDED(hres)) {
		if (m_stgMedium.hGlobal)
			m_cbFiles = DragQueryFile((HDROP)m_stgMedium.hGlobal, (UINT)-1, 0, 0);
	}

	UINT nIndex = indexMenu++;

	InsertMenu(hMenu, nIndex, MF_STRING|MF_BYPOSITION, idCmd++, m_szMenuTitle);

	if (m_showIcon) {
		HBITMAP icon = NULL;
		if (m_winVer >= WINVER_VISTA) {
			icon = NULL;
			HICON hicon;
			DWORD menuIconWidth = GetSystemMetrics(SM_CXMENUCHECK);
			DWORD menuIconHeight = GetSystemMetrics(SM_CYMENUCHECK);
			HRESULT hr = LoadShellIcon(menuIconWidth, menuIconHeight, &hicon);
			if (SUCCEEDED(hr)) {
				icon = IconToBitmapPARGB32(hicon, menuIconWidth, menuIconHeight);
				DestroyIcon(hicon);
			}
		} else {
			icon = HBMMENU_CALLBACK;
		}

		if (icon != NULL) {
			MENUITEMINFO mii;
			ZeroMemory(&mii, sizeof(mii));
			mii.cbSize = sizeof(mii);
			mii.fMask = MIIM_BITMAP;
			mii.hbmpItem = icon;
			//mii.hbmpChecked = icon;
			//mii.hbmpUnchecked = icon;

			SetMenuItemInfo(hMenu, nIndex, MF_BYPOSITION, &mii);

			if (m_winVer >= WINVER_VISTA) {
				MENUINFO MenuInfo;
				MenuInfo.cbSize = sizeof(MenuInfo);
				MenuInfo.fMask = MIM_STYLE;
				MenuInfo.dwStyle = MNS_CHECKORBMP;

				SetMenuInfo(hMenu, &MenuInfo);
			}

		}
	}

	m_hMenu = hMenu;
	m_menuID = idCmd;

	return ResultFromShort(idCmd-idCmdFirst);
}
STDMETHODIMP CGitExtensionsShellEx::QueryContextMenu(
    HMENU hMenu, UINT menuIndex, UINT uidFirstCmd, UINT uidLastCmd, UINT uFlags)
{
    DBG_TRACE(L"CGitExtensionsShellEx::QueryContextMenu(menuIndex=%u,uidLastCmd=%u,uFlags=%u)", menuIndex, uidLastCmd, uFlags);
    // If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
    if (uFlags & CMF_DEFAULTONLY)
        return S_OK;

    //check if we already added our menu entry for a folder.
    //we check that by iterating through all menu entries and check if
    //the dwItemData member points to our global ID string. That string is set
    //by our shell extension when the folder menu is inserted.
    TCHAR menubuf[MAX_PATH];
    int count = GetMenuItemCount(hMenu);
    for (int i=0; i<count; ++i)
    {
        MENUITEMINFO miif;
        SecureZeroMemory(&miif, sizeof(MENUITEMINFO));
        miif.cbSize = sizeof(MENUITEMINFO);
        miif.fMask = MIIM_DATA;
        miif.dwTypeData = menubuf;
        miif.cch = _countof(menubuf);
        GetMenuItemInfo(hMenu, i, TRUE, &miif);
        if (miif.dwItemData == (ULONG_PTR)_Module.GetModuleInstance())
        {
            DBG_TRACE(L"Menu already added");
            return S_OK;
        }
    }

    CString szCascadeShellMenuItems = GetRegistryValue(HKEY_CURRENT_USER, L"SOFTWARE\\GitExtensions", L"CascadeShellMenuItems");
    if (szCascadeShellMenuItems.IsEmpty())
        szCascadeShellMenuItems = "110111000111111111";
    bool cascadeContextMenu = szCascadeShellMenuItems.Find('1') != -1;
    bool alwaysShowAllCommands = GetRegistryBoolValue(HKEY_CURRENT_USER, L"SOFTWARE\\GitExtensions", L"AlwaysShowAllCommands");

    HMENU popupMenu = NULL;
    if (cascadeContextMenu)
        popupMenu = CreateMenu();

    bool isValidDir = true;
    bool isFolder = true;
    if (!alwaysShowAllCommands)
    {
        isValidDir = IsValidGitDir(m_szFile);
        isFolder = !IsFileExists(m_szFile);
    }

    // preset values, if not used
    commandsId.clear();

    UINT submenuIndex = 0;
    int id = 0;
    int cmdid;
    bool isSubMenu;

    if (alwaysShowAllCommands || !isValidDir)
    {
        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcClone);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Clone...", IDI_ICONCLONEREPOGIT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcClone;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCreateRepository);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Create new repository...", IDI_ICONCREATEREPOSITORY, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcCreateRepository;
    }
    if (isValidDir)
    {
        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcBrowse);
        cmdid = AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Browse", IDI_ICONBROWSEFILEEXPLORER, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcBrowse;

        if (isFolder)
        {
            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCommit);
            cmdid = AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Commit...", IDI_ICONCOMMIT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCommit;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcPull);
            cmdid = AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Pull...", IDI_ICONPULL, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcPull;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcPush);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Push...", IDI_ICONPUSH, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcPush;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcStash);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"View stash", IDI_ICONSTASH, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcStash;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcViewDiff);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"View changes", IDI_ICONVIEWCHANGES, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcViewDiff;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCheckoutBranch);
            if (isSubMenu && submenuIndex > 0) {
                InsertMenu(popupMenu, submenuIndex++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); ++id;
            }
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Checkout branch...", IDI_ICONBRANCHCHECKOUT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCheckoutBranch;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCheckoutRevision);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Checkout revision...", IDI_ICONREVISIONCHECKOUT, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCheckoutRevision;

            isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcCreateBranch);
            cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Create branch...", IDI_ICONBRANCHCREATE, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
            commandsId[cmdid]=gcCreateBranch;
        }

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcDiffTool);
        if (isSubMenu && submenuIndex > 0) {
            InsertMenu(popupMenu, submenuIndex++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); ++id;
        }
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Open with difftool", IDI_ICONVIEWCHANGES, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcDiffTool;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcFileHistory);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"File history", IDI_ICONFILEHISTORY, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcFileHistory;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcResetFileChanges);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Reset file changes...", IDI_ICONTRESETFILETO, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcResetFileChanges;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcAddFiles);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Add files...", IDI_ICONADDED, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcAddFiles;

        isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcApplyPatch);
        cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Apply patch...", 0, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
        commandsId[cmdid]=gcApplyPatch;
    }

    isSubMenu = DisplayInSubmenu(szCascadeShellMenuItems, gcSettings);
    if (isSubMenu && submenuIndex > 0) {
        InsertMenu(popupMenu, submenuIndex++, MF_SEPARATOR|MF_BYPOSITION, 0, NULL); ++id;
    }
    cmdid=AddMenuItem(!isSubMenu ? hMenu : popupMenu, L"Settings", IDI_ICONSETTINGS, uidFirstCmd, ++id, !isSubMenu ? menuIndex++ : submenuIndex++, isSubMenu);
    commandsId[cmdid]=gcSettings;

    ++id;

    if (cascadeContextMenu)
    {
        MENUITEMINFO info;
        info.cbSize = sizeof(MENUITEMINFO);
        info.fMask = MIIM_STRING | MIIM_ID | MIIM_BITMAP | MIIM_SUBMENU;
        info.wID = uidFirstCmd + 1;
        info.hbmpItem = IsVistaOrLater() ? IconToBitmapPARGB32(IDI_GITEXTENSIONS) : HBMMENU_CALLBACK;
        myIDMap[1] = IDI_GITEXTENSIONS;
        myIDMap[uidFirstCmd + 1] = IDI_GITEXTENSIONS;
        info.dwTypeData = _T("Git Extensions");
        info.hSubMenu = popupMenu;
        InsertMenuItem(hMenu, menuIndex, true, &info);
    }

    return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, id);
}
Exemple #10
0
STDMETHODIMP CDeskBand::QueryContextMenu(HMENU hMenu,
                                         UINT indexMenu,
                                         UINT idCmdFirst,
                                         UINT /*idCmdLast*/,
                                         UINT uFlags)
{
    if ((uFlags & CMF_DEFAULTONLY)!=0)
        return S_OK;                    //we don't change the default action

    if (((uFlags & 0x000f)!=CMF_NORMAL)&&(!(uFlags & CMF_EXPLORE))&&(!(uFlags & CMF_VERBSONLY)))
        return S_OK;

    if ((m_ContextDirectory.empty()) && (m_ContextItems.empty()))
        return S_OK;


    if (m_ContextDirectory.empty())
    {
        // folder is empty, but maybe files are selected
        if (m_ContextItems.empty())
            return S_OK;    // nothing selected - we don't have a menu to show
        // check whether a selected entry is an UID - those are namespace extensions
        // which we can't handle
        for (std::map<tstring, ULONG>::const_iterator it = m_ContextItems.begin(); it != m_ContextItems.end(); ++it)
        {
            if (_tcsncmp(it->first.c_str(), _T("::{"), 3)==0)
                return S_OK;
        }
    }
    else
    {
        // ignore namespace extensions
        if (_tcsncmp(m_ContextDirectory.c_str(), _T("::{"), 3)==0)
            return S_OK;
    }

    if (DWORD(CRegStdDWORD(_T("Software\\StefansTools\\StExBar\\ContextMenu"), TRUE)) == FALSE)
        return S_OK;

    //check if we already added our menu entry for a folder.
    //we check that by iterating through all menu entries and check if
    //the dwItemData member points to our global ID string. That string is set
    //by our shell extension when the folder menu is inserted.
    TCHAR menubuf[MAX_PATH];
    int count = GetMenuItemCount(hMenu);
    for (int i=0; i<count; ++i)
    {
        MENUITEMINFO miif;
        SecureZeroMemory(&miif, sizeof(MENUITEMINFO));
        miif.cbSize = sizeof(MENUITEMINFO);
        miif.fMask = MIIM_DATA;
        miif.dwTypeData = menubuf;
        miif.cch = _countof(menubuf);
        GetMenuItemInfo(hMenu, i, TRUE, &miif);
        if (miif.dwItemData == (ULONG_PTR)g_MenuIDString)
            return S_OK;
    }

    UINT idCmd = idCmdFirst;

    //create the sub menu
    HMENU subMenu = CreateMenu();
    int indexSubMenu = 0;


    m_commands.LoadFromFile();

    int index = 0;
    for (int j = 0; j < m_commands.GetCount(); ++j)
    {
        MENUITEMINFO menuiteminfo = {0};

        Command cmd = m_commands.GetCommand(j);
        m_hotkeys[cmd.key] = j;
        if ((cmd.commandline.compare(INTERNALCOMMANDHIDDEN)==0)&&(cmd.name.compare(_T("Options")) == 0))
        {
            cmd.commandline = INTERNALCOMMAND;  // make sure the options button is never hidden.
            m_commands.SetCommand(j, cmd);
        }
        if ((cmd.name.compare(_T("StexBar Internal Edit Box")) == 0)||
            (cmd.commandline.compare(INTERNALCOMMANDHIDDEN) == 0)||
            (cmd.name.compare(_T("New Folder")) == 0))
        {
            continue;
        }
        bool bEnabled = cmd.enabled_viewpath ||
                        (cmd.enabled_fileselected && !m_ContextItems.empty()) ||
                        (cmd.enabled_folderselected && (!m_ContextItems.empty() || !m_ContextDirectory.empty())) ||
                        (cmd.enabled_noselection && (m_ContextItems.empty())) ||
                        (cmd.enabled_selectedcount && (cmd.enabled_selectedcount == (int)!m_ContextItems.empty()));

        HICON hIcon = LoadCommandIcon(cmd);
        if (hIcon)
        {
            menuiteminfo.hbmpItem = IsWindowsVistaOrGreater() ? IconToBitmapPARGB32(hIcon) : HBMMENU_CALLBACK;
            DestroyIcon(hIcon);
        }
        else
            menuiteminfo.hbmpItem = NULL;
        if (!cmd.separator)
            m_tooltips[j] = cmd.name.c_str();

        myIDMap[idCmd - idCmdFirst] = j;
        myIDMap[idCmd] = j;

        menuiteminfo.cbSize = sizeof(menuiteminfo);
        menuiteminfo.fMask = cmd.separator ? MIIM_FTYPE : MIIM_FTYPE | MIIM_ID | MIIM_BITMAP | MIIM_STRING | MIIM_STATE;
        menuiteminfo.fType = cmd.separator ? MFT_SEPARATOR : MFT_STRING;
        menuiteminfo.fState = bEnabled ? MFS_ENABLED : MFS_DISABLED;
        TCHAR menutextbuf[100];
        _tcscpy_s(menutextbuf, _countof(menutextbuf), m_commands.GetCommandPtr(j)->name.c_str());
        menuiteminfo.dwTypeData = menutextbuf;
        menuiteminfo.wID = idCmd++;
        InsertMenuItem(subMenu, indexSubMenu++, TRUE, &menuiteminfo);
        index++;
    }

    //add sub menu to main context menu
    //don't use InsertMenu because this will lead to multiple menu entries in the explorer file menu.
    //see http://support.microsoft.com/default.aspx?scid=kb;en-us;214477 for details of that.
    MENUITEMINFO menuiteminfo = {0};
    SecureZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
    menuiteminfo.cbSize = sizeof(menuiteminfo);
    menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_STRING;
    menuiteminfo.fType = MFT_STRING;
    menuiteminfo.dwTypeData = _T("StEx");

    menuiteminfo.hSubMenu = subMenu;
    menuiteminfo.wID = idCmd++;
    InsertMenuItem(hMenu, indexMenu++, TRUE, &menuiteminfo);

    //return number of menu items added
    return ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(idCmd - idCmdFirst)));
}