Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
#include "stdafx.h"#include "TortoiseUtils.h"#include "StringUtils.h"#include "Dirstatecache.h"#include "Thgstatus.h"#include "Winstat.h"#include "InitStatus.h"#include "SysInfo.h"#include "ShellExt.h"#include "RegistryConfig.h"#include "TortoiseIconBitmap.h"#include <map>#include "CShellExtCMenu.h"structMenuDescription{std::stringname;std::wstringmenuText;std::wstringhelpText;std::stringiconName;UINTidCmd;};// According to http://msdn.microsoft.com/en-us/library/bb776094%28VS.85%29.aspx// the help texts for the commands should be reasonably short (under 40 characters)MenuDescriptionmenuDescList[]={{"commit",L"Commit...",L"Commit changes in repository","menucommit.ico",0},{"init",L"Create Repository Here",L"Create a new repository","menucreaterepos.ico",0},{"clone",L"Clone...",L"Create clone here from source","menuclone.ico",0},{"status",L"View File Status",L"Repository status & changes","menushowchanged.ico",0},{"shelve",L"Shelve Changes",L"Shelve or unshelve file changes","shelve.ico",0},{"add",L"Add Files...",L"Add files to version control","menuadd.ico",0},{"revert",L"Revert Files...",L"Revert file changes","menurevert.ico",0},{"remove",L"Remove Files...",L"Remove files from version control","menudelete.ico",0},{"rename",L"Rename File...",L"Rename file or directory","general.ico",0},{"log",L"Repository Explorer",L"View change history in repository","menulog.ico",0},{"synch",L"Synchronize",L"Synchronize with remote repository","menusynch.ico",0},{"serve",L"Web Server",L"Start web server for this repository","proxy.ico",0},{"update",L"Update...",L"Update working directory","menucheckout.ico",0},{"recover",L"Recovery...",L"Repair and recovery of repository","general.ico",0},{"thgstatus",L"Update Icons",L"Update icons for this repository","refresh_overlays.ico",0},{"userconf",L"Global Settings",L"Configure user wide settings","settings_user.ico",0},{"repoconf",L"Repository Settings",L"Configure repository settings","settings_repo.ico",0},{"about",L"About TortoiseHg",L"Show About Dialog","menuabout.ico",0},{"datamine",L"Annotate Files",L"Changeset information per file line","menublame.ico",0},{"vdiff",L"Visual Diff",L"View changes using GUI diff tool","TortoiseMerge.ico",0},{"hgignore",L"Edit Ignore Filter",L"Edit repository ignore filter","ignore.ico",0},{"guess",L"Guess Renames",L"Detect renames and copies","detect_rename.ico",0},{"grep",L"Search History",L"Search file revisions for patterns","menurepobrowse.ico",0},{"forget",L"Forget Files...",L"Remove files from version control","menudelete.ico",0},{"shellconf",L"Explorer Extension Settings",L"Configure Explorer extension","settings_repo.ico",0},/* Add new items here */// template {"", L"", L"", ".ico", 0},
};
-const char* RepoNoFilesMenu =
+const char* const RepoNoFilesMenu =
"commit status shelve vidff sep"
" add revert rename forget remove sep"
" log update grep sep"
" synch serve clone init thgstatus sep"" ignore guess recover sep"" shellconf repoconf userconf sep" " about"
;
-const char* RepoFilesMenu =
+const char* const RepoFilesMenu =
"commit status vidff sep"
" add revert rename forget remove sep"
" log datamine sep"
" about"
;
-const char* NoRepoMenu =
+const char* const NoRepoMenu =
"clone init shellconf userconf thgstatus sep"
" about"
;
typedefstd::map<std::string,MenuDescription>MenuDescriptionMap;typedefstd::map<UINT,MenuDescription>MenuIdCmdMap;MenuDescriptionMapMenuDescMap;MenuIdCmdMapMenuIdMap;voidAddMenuList(UINTidCmd,conststd::string&name){TDEBUG_TRACE("AddMenuList: idCmd = "<<idCmd<<" name = "<<name);MenuIdMap[idCmd]=MenuDescMap[name];}voidGetCMenuTranslation(conststd::string&lang,conststd::string&name,std::wstring&menuText,std::wstring&helpText){std::wstringsubkey=L"Software\\TortoiseHg\\CMenu\\";subkey+=_WCSTR(lang.c_str());subkey+=L"\\";subkey+=_WCSTR(name.c_str());TDEBUG_TRACEW(L"GetCMenuTranslation: "<<subkey);HKEYhkey=0;LONGrv=RegOpenKeyExW(HKEY_CURRENT_USER,subkey.c_str(),0,KEY_READ,&hkey);if(rv==ERROR_SUCCESS&&hkey){GetRegSZValueW(hkey,L"menuText",menuText);GetRegSZValueW(hkey,L"helpText",helpText);}else{TDEBUG_TRACEW(L"GetCMenuTranslation: RegOpenKeyExW(\""<<subkey<<"\") failed");}if(hkey)RegCloseKey(hkey);}voidInitMenuMaps(){if(MenuDescMap.empty()){std::stringlang;GetRegistryConfig("CMenuLang",lang);std::size_tsz=sizeof(menuDescList)/sizeof(MenuDescription);for(std::size_ti=0;i<sz;i++){MenuDescriptionmd=menuDescList[i];if(md.name.size()==0)break;TDEBUG_TRACE("InitMenuMaps: adding "<<md.name);// Look for translation of menu and help textif(lang.size())GetCMenuTranslation(lang,md.name,md.menuText,md.helpText);MenuDescMap[md.name]=md;}}MenuIdMap.clear();}voidInsertMenuItemWithIcon1(HMENUhMenu,UINTindexMenu,UINTidCmd,conststd::wstring&menuText,conststd::string&iconName){MENUITEMINFOWmi;memset(&mi,0,sizeof(mi));mi.cbSize=sizeof(mi);mi.dwTypeData=const_cast<wchar_t*>(menuText.c_str());mi.cch=static_cast<UINT>(menuText.length());mi.wID=idCmd;mi.fType=MFT_STRING;if(SysInfo::Instance().IsVistaOrLater()){TDEBUG_TRACE(" InsertMenuItemWithIcon1: Vista or later detected, using modern context menu style");HBITMAPhBmp=GetTortoiseIconBitmap(iconName);if(hBmp){mi.fMask=MIIM_STRING|MIIM_FTYPE|MIIM_ID|MIIM_BITMAP;mi.hbmpItem=hBmp;}else{TDEBUG_TRACE(" InsertMenuItemWithIcon1: can't find "+iconName);mi.fMask=MIIM_TYPE|MIIM_ID;}}else{HICONh=GetTortoiseIcon(iconName);if(h){mi.fMask=MIIM_STRING|MIIM_FTYPE|MIIM_ID|MIIM_BITMAP|MIIM_DATA;mi.dwItemData=(ULONG_PTR)h;mi.hbmpItem=HBMMENU_CALLBACK;}else{TDEBUG_TRACE(" InsertMenuItemWithIcon1: can't find "+iconName);mi.fMask=MIIM_TYPE|MIIM_ID;}}InsertMenuItemW(hMenu,indexMenu,TRUE,&mi);TDEBUG_TRACEW(L"InsertMenuItemWithIcon1(\""<<menuText<<L"\") finished");}voidInsertSubMenuItemWithIcon2(HMENUhMenu,HMENUhSubMenu,UINTindexMenu,UINTidCmd,conststd::wstring&menuText,conststd::string&iconName){MENUITEMINFOWmi;memset(&mi,0,sizeof(mi));mi.cbSize=sizeof(mi);mi.fType=MFT_STRING;mi.dwTypeData=const_cast<wchar_t*>(menuText.c_str());mi.cch=static_cast<UINT>(menuText.length());mi.wID=idCmd;mi.hSubMenu=hSubMenu;if(SysInfo::Instance().IsVistaOrLater()){TDEBUG_TRACE(" InsertMenuItemWithIcon1: Vista or later detected, using modern context menu style");HBITMAPhBmp=GetTortoiseIconBitmap(iconName);if(hBmp){mi.fMask=MIIM_SUBMENU|MIIM_STRING|MIIM_FTYPE|MIIM_ID|MIIM_BITMAP;mi.hbmpItem=hBmp;}else{TDEBUG_TRACE(" InsertSubMenuItemWithIcon2: can't find "+iconName);mi.fMask=MIIM_TYPE|MIIM_ID;}}else{HICONh=GetTortoiseIcon(iconName);if(h){mi.fMask=MIIM_SUBMENU|MIIM_STRING|MIIM_ID;mi.dwItemData=(ULONG_PTR)h;mi.hbmpItem=HBMMENU_CALLBACK;}else{TDEBUG_TRACE(" InsertSubMenuItemWithIcon2: can't find "+iconName);mi.fMask=MIIM_TYPE|MIIM_ID;}}InsertMenuItemW(hMenu,indexMenu,TRUE,&mi);TDEBUG_TRACEW(L"InsertMenuItemWithIcon2(\""<<menuText<<L"\") finished");}voidInsertMenuItemByName(HMENUhMenu,conststd::string&name,UINTindexMenu,UINTidCmd,UINTidCmdFirst,conststd::wstring&prefix){MenuDescriptionMap::iteratoriter=MenuDescMap.find(name);if(iter==MenuDescMap.end()){TDEBUG_TRACE("InsertMenuItemByName: can't find menu info for "<<name);return;}MenuDescriptionmd=iter->second;AddMenuList(idCmd-idCmdFirst,name);InsertMenuItemWithIcon1(hMenu,indexMenu,idCmd,prefix+md.menuText,md.iconName);}conststd::wstringTortoiseHgMenuEntryString=L"TortoiseHg";intHasTortoiseMenu(HMENUhMenu,bool&hasmenu)// returns -1 on error, 0 otherwise{hasmenu=false;constintcount=::GetMenuItemCount(hMenu);if(count==-1){TDEBUG_TRACE("HasTortoiseMenu: GetMenuItemCount returned -1");return-1;}MENUITEMINFOWmii;for(inti=0;i<count;++i){memset(&mii,0,sizeof(MENUITEMINFOW));mii.cbSize=sizeof(MENUITEMINFOW);// first GetMenuItemInfoW call: get size of menu item stringmii.fMask=MIIM_STRING;BOOLres=::GetMenuItemInfoW(hMenu,i,true,&mii);if(res==0){TDEBUG_TRACE("HasTortoiseMenu: "<<"first GetMenuItemInfo returned 0");continue;}if(mii.dwTypeData!=MFT_STRING){// not a stringcontinue;}// allocate buffer for the stringstd::vector<wchar_t>text(mii.cch+1);// second GetMenuItemInfoW call: get string into buffermii.dwTypeData=&text[0];++mii.cch;// size of buffer is one more than length of stringres=::GetMenuItemInfoW(hMenu,i,true,&mii);if(res==0){TDEBUG_TRACE("HasTortoiseMenu: "<<"second GetMenuItemInfo returned 0");continue;}conststd::wstringmenuitemtext(&text[0]);//TDEBUG_TRACEW(L"HasTortoiseMenu: "// << L"menuitemtext is '" << menuitemtext << L"'");if(menuitemtext==TortoiseHgMenuEntryString){TDEBUG_TRACE("HasTortoiseMenu: FOUND TortoiseHg menu entry");hasmenu=true;return0;}}TDEBUG_TRACE("HasTortoiseMenu: TortoiseHg menu entry NOT found");return0;}#define ResultFromShort(i) ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, 0, (USHORT)(i)))// IContextMenuSTDMETHODIMPCShellExtCMenu::QueryContextMenu(HMENUhMenu,UINTindexMenu,UINTidCmdFirst,UINTidCmdLast,UINTuFlags){TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu");UINTidCmd=idCmdFirst;BOOLbAppendItems=TRUE;if((uFlags&0x000F)==CMF_NORMAL)bAppendItems=TRUE;elseif(uFlags&CMF_VERBSONLY)bAppendItems=TRUE;elseif(uFlags&CMF_EXPLORE)bAppendItems=TRUE;elsebAppendItems=FALSE;if(!bAppendItems)returnS_OK;boolhasthgmenu=false;if(HasTortoiseMenu(hMenu,hasthgmenu)==0&&hasthgmenu){TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu: "<<"TortoiseHg menu entry already in menu -> skipping");returnS_OK;}InitMenuMaps();typedefstd::vector<std::string>entriesT;typedefentriesT::const_iteratorentriesIter;std::stringpromoted_string="commit,log";// default value if key not foundGetRegistryConfig("PromotedItems",promoted_string);entriesTpromoted;Tokenize(promoted_string,promoted,",");// Select menu to showboolfileMenu=myFiles.size()>0;boolisHgrepo=false;std::stringcwd;if(!myFolder.empty()){cwd=myFolder;}elseif(!myFiles.empty()){cwd=IsDirectory(myFiles[0])?myFiles[0]:DirName(myFiles[0]);}if(!cwd.empty()){// check if target directory is a Mercurial repositorystd::stringroot=GetHgRepoRoot(cwd);isHgrepo=!root.empty();if(myFiles.size()==1&&root==myFiles[0]){fileMenu=false;myFolder=cwd;myFiles.clear();}}TDEBUG_TRACE("CShellExtCMenu::QueryContextMenu: isHgrepo = "<<isHgrepo<<", fileMenu = "<<fileMenu);/* We have three menu types: files-selected, no-files-selected, no-repo */constchar*entries_string=0;if(isHgrepo)if(fileMenu)entries_string=RepoFilesMenu;elseentries_string=RepoNoFilesMenu;elseentries_string=NoRepoMenu;// start building TortoiseHg menus and submenusInsertMenu(hMenu,indexMenu++,MF_SEPARATOR|MF_BYPOSITION,0,NULL);entriesTentries;Tokenize(entries_string,entries," ");for(entriesIteri=entries.begin();i!=entries.end();i++){std::stringname=*i;if(contains(promoted,name)){InsertMenuItemByName(hMenu,name,indexMenu++,idCmd++,idCmdFirst,L"Hg ");}}constHMENUhSubMenu=CreatePopupMenu();if(hSubMenu){UINTindexSubMenu=0;boolisSeparator=true;for(entriesIteri=entries.begin();i!=entries.end();i++){std::stringname=*i;if(name=="sep"){if(!isSeparator){InsertMenu(hSubMenu,indexSubMenu++,MF_SEPARATOR|MF_BYPOSITION,0,NULL);isSeparator=true;}}else{if(!contains(promoted,name)){InsertMenuItemByName(hSubMenu,name,indexSubMenu++,idCmd++,idCmdFirst,L"");isSeparator=false;}}}if(isSeparator&&indexSubMenu>0)RemoveMenu(hSubMenu,indexSubMenu-1,MF_BYPOSITION);if(SysInfo::Instance().IsVistaOrLater()){MENUINFOMenuInfo;memset(&MenuInfo,0,sizeof(MenuInfo));MenuInfo.cbSize=sizeof(MenuInfo);MenuInfo.fMask=MIM_STYLE|MIM_APPLYTOSUBMENUS;MenuInfo.dwStyle=MNS_CHECKORBMP;SetMenuInfo(hSubMenu,&MenuInfo);}}TDEBUG_TRACE(" CShellExtCMenu::QueryContextMenu: adding main THG menu");InsertSubMenuItemWithIcon2(hMenu,hSubMenu,indexMenu++,idCmd++,TortoiseHgMenuEntryString,"hg.ico");InsertMenu(hMenu,indexMenu++,MF_SEPARATOR|MF_BYPOSITION,0,NULL);InitStatus::check();if(SysInfo::Instance().IsVistaOrLater()){MENUINFOMenuInfo;memset(&MenuInfo,0,sizeof(MenuInfo));MenuInfo.cbSize=sizeof(MenuInfo);MenuInfo.fMask=MIM_STYLE|MIM_APPLYTOSUBMENUS;MenuInfo.dwStyle=MNS_CHECKORBMP;SetMenuInfo(hMenu,&MenuInfo);}returnResultFromShort(idCmd-idCmdFirst);}STDMETHODIMPCShellExtCMenu::InvokeCommand(LPCMINVOKECOMMANDINFOlpcmi){TDEBUG_TRACE("CShellExtCMenu::InvokeCommand");HRESULThr=E_INVALIDARG;if(!HIWORD(lpcmi->lpVerb)){UINTidCmd=LOWORD(lpcmi->lpVerb);TDEBUG_TRACE("CShellExtCMenu::InvokeCommand: idCmd = "<<idCmd);MenuIdCmdMap::iteratoriter=MenuIdMap.find(idCmd);if(iter!=MenuIdMap.end()){DoHgtk(iter->second.name);hr=S_OK;}else{TDEBUG_TRACE("CShellExtCMenu::InvokeCommand: action not found for idCmd "<<idCmd);}}returnhr;}STDMETHODIMPCShellExtCMenu::GetCommandString(UINT_PTRidCmd,UINTuFlags,UINTFAR*reserved,LPSTRpszName,UINTcchMax){// see http://msdn.microsoft.com/en-us/library/bb776094%28VS.85%29.aspxHRESULTres=S_FALSE;constchar*psz="";constwchar_t*pszw=0;std::stringsflags="?";switch(uFlags){caseGCS_HELPTEXTW:
sflags="GCS_HELPTEXTW";break;caseGCS_HELPTEXTA:
sflags="GCS_HELPTEXTA";break;caseGCS_VALIDATEW:
sflags="GCS_VALIDATEW";break;caseGCS_VALIDATEA:
sflags="GCS_VALIDATEA";break;caseGCS_VERBW:
sflags="GCS_VERBW";break;caseGCS_VERBA:
sflags="GCS_VERBA";break;}TDEBUG_TRACE("CShellExtCMenu::GetCommandString: idCmd = "<<idCmd<<", uFlags = "<<uFlags<<" ("<<sflags<<")"<<", cchMax = "<<cchMax);MenuIdCmdMap::iteratoriter=MenuIdMap.find(static_cast<UINT>(idCmd));if(iter==MenuIdMap.end()){TDEBUG_TRACE("CShellExtCMenu::GetCommandString: idCmd not found");}else{TDEBUG_TRACE("CShellExtCMenu::GetCommandString: name = \""<<iter->second.name<<"\"");if(uFlags==GCS_HELPTEXTW){pszw=iter->second.helpText.c_str();res=S_OK;size_tsize=iter->second.helpText.size();if(size>=40){TDEBUG_TRACE("CShellExtCMenu::GetCommandString: warning:"<<" length of help text is "<<size<<", which is not reasonably short (<40)");}}elseif(uFlags==GCS_HELPTEXTA){// we don't provide ansi help textspsz="";res=S_OK;}elseif(uFlags==GCS_VERBW||uFlags==GCS_VERBA){#if 0 psz = iter->second.name.c_str();#else// bugfix: don't provide verbs ("rename" conflicted with rename of explorer)psz="";#endifres=S_OK;}elseif(uFlags==GCS_VALIDATEW||uFlags==GCS_VALIDATEA){res=S_OK;}}if(cchMax<1){TDEBUG_TRACE("CShellExtCMenu::GetCommandString: cchMax = "<<cchMax<<" (is <1)");returnres;}size_tsize=0;if(uFlags&GCS_UNICODE){wchar_t*constdest=reinterpret_cast<wchar_t*>(pszName);constwchar_t*constsrc=pszw?pszw:_WCSTR(psz);wcsncpy(dest,src,cchMax-1);*(dest+cchMax-1)=0;size=wcslen(src);TDEBUG_TRACEW(L"CShellExtCMenu::GetCommandString: res = "<<int(res)<<L", pszName (wide) = \""<<dest<<L"\"");}else{strncpy(pszName,psz,cchMax-1);*(pszName+cchMax-1)=0;size=strlen(psz);TDEBUG_TRACE("CShellExtCMenu::GetCommandString: res = "<<int(res)<<", pszName = \""<<psz<<"\"");}if(size>cchMax-1){TDEBUG_TRACE("CShellExtCMenu::GetCommandString: string was truncated: size = "<<size<<", cchMax = "<<cchMax);}returnres;}STDMETHODIMPCShellExtCMenu::HandleMenuMsg(UINTuMsg,WPARAMwParam,LPARAMlParam){LRESULTres;returnHandleMenuMsg2(uMsg,wParam,lParam,&res);}STDMETHODIMPCShellExtCMenu::HandleMenuMsg2(UINTuMsg,WPARAMwParam,LPARAMlParam,LRESULT*pResult){// A great tutorial on owner drawn menus in shell extension can be found// here: http://www.codeproject.com/shell/shellextguide7.aspLRESULTres;if(!pResult)pResult=&res;*pResult=FALSE;switch(uMsg){caseWM_MEASUREITEM:
{MEASUREITEMSTRUCT*lpmis=(MEASUREITEMSTRUCT*)lParam;if(lpmis==NULL)break;lpmis->itemWidth+=2;if(lpmis->itemHeight<16)lpmis->itemHeight=16;*pResult=TRUE;}break;caseWM_DRAWITEM:
{DRAWITEMSTRUCT*lpdis=(DRAWITEMSTRUCT*)lParam;if(!lpdis||(lpdis->CtlType!=ODT_MENU)||!lpdis->itemData)break;//not for a menuDrawIconEx(lpdis->hDC,lpdis->rcItem.left-16,lpdis->rcItem.top+(lpdis->rcItem.bottom-lpdis->rcItem.top-16)/2,(HICON)lpdis->itemData,16,16,0,0,DI_NORMAL);*pResult=TRUE;}break;default:returnS_OK;}returnS_OK;}voidCShellExtCMenu::DoHgtk(conststd::string&cmd){std::stringdir=GetTHgProgRoot();if(dir.empty()){TDEBUG_TRACE("DoHgtk: THG root is empty");return;}std::stringhgcmd=dir+"\\hgtk.exe";WIN32_FIND_DATAAdata;HANDLEhfind=FindFirstFileA(hgcmd.c_str(),&data);if(hfind==INVALID_HANDLE_VALUE)hgcmd=dir+"\\hgtk.cmd";elseFindClose(hfind);hgcmd=Quote(hgcmd)+" --nofork "+cmd;std::stringcwd;if(!myFolder.empty()){cwd=myFolder;}elseif(!myFiles.empty()){cwd=IsDirectory(myFiles[0])?myFiles[0]:DirName(myFiles[0]);}else{TDEBUG_TRACE("DoHgtk: can't get cwd");return;}if(!myFiles.empty()){conststd::stringtempfile=GetTemporaryFile();if(tempfile.empty()){TDEBUG_TRACE("DoHgtk: error: GetTemporaryFile returned empty string");return;}TDEBUG_TRACE("DoHgtk: temp file = "<<tempfile);HANDLEtempfileHandle=CreateFileA(tempfile.c_str(),GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);if(tempfileHandle==INVALID_HANDLE_VALUE){TDEBUG_TRACE("DoHgtk: error: failed to create file "<<tempfile);return;}typedefstd::vector<std::string>::size_typeST;for(STi=0;i<myFiles.size();i++){DWORDdwWritten;TDEBUG_TRACE("DoHgtk: temp file adding "<<myFiles[i]);WriteFile(tempfileHandle,myFiles[i].c_str(),static_cast<DWORD>(myFiles[i].size()),&dwWritten,0);WriteFile(tempfileHandle,"\n",1,&dwWritten,0);}CloseHandle(tempfileHandle);hgcmd+=" --listfile "+Quote(tempfile);}if(cmd=="thgstatus"){Thgstatus::remove(cwd);InitStatus::check();return;}LaunchCommand(hgcmd,cwd);InitStatus::check();}STDMETHODIMPCShellExtCMenu::Initialize(LPCITEMIDLISTpIDFolder,LPDATAOBJECTpDataObj,HKEYhRegKey){TCHARname[MAX_PATH+1];TDEBUG_TRACE("CShellExtCMenu::Initialize");TDEBUG_TRACE(" pIDFolder: "<<pIDFolder);TDEBUG_TRACE(" pDataObj: "<<pDataObj);myFolder.clear();myFiles.clear();if(pDataObj){FORMATETCfmt={CF_HDROP,NULL,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};STGMEDIUMstg={TYMED_HGLOBAL};if(SUCCEEDED(pDataObj->GetData(&fmt,&stg))&&stg.hGlobal){HDROPhDrop=(HDROP)GlobalLock(stg.hGlobal);if(hDrop){UINTuNumFiles=DragQueryFile(hDrop,0xFFFFFFFF,NULL,0);TDEBUG_TRACE(" hDrop uNumFiles = "<<uNumFiles);for(UINTi=0;i<uNumFiles;++i){if(DragQueryFile(hDrop,i,name,MAX_PATH)>0){TDEBUG_TRACE(" DragQueryFile ["<<i<<"] = "<<name);myFiles.push_back(name);}}}else{TDEBUG_TRACE(" hDrop is NULL ");}GlobalUnlock(stg.hGlobal);if(stg.pUnkForRelease){IUnknown*relInterface=(IUnknown*)stg.pUnkForRelease;relInterface->Release();}}else{TDEBUG_TRACE(" pDataObj->GetData failed");}}// if a directory backgroundif(pIDFolder){SHGetPathFromIDList(pIDFolder,name);TDEBUG_TRACE(" Folder "<<name);myFolder=name;}returnS_OK;}CShellExtCMenu::CShellExtCMenu(chardummy):m_ppszFileUserClickedOn(0){m_cRef=0L;CShellExt::IncDllRef();}CShellExtCMenu::~CShellExtCMenu(){CShellExt::DecDllRef();}STDMETHODIMP_(ULONG)CShellExtCMenu::AddRef(){ThgCriticalSectioncs(CShellExt::GetCriticalSection());return++m_cRef;}STDMETHODIMP_(ULONG)CShellExtCMenu::Release(){ThgCriticalSectioncs(CShellExt::GetCriticalSection());if(--m_cRef)returnm_cRef;deletethis;return0L;}STDMETHODIMPCShellExtCMenu::QueryInterface(REFIIDriid,LPVOIDFAR*ppv){if(ppv==0)returnE_POINTER;*ppv=NULL;if(IsEqualIID(riid,IID_IShellExtInit)||IsEqualIID(riid,IID_IUnknown)){*ppv=(LPSHELLEXTINIT)this;}elseif(IsEqualIID(riid,IID_IContextMenu)){*ppv=(LPCONTEXTMENU)this;}elseif(IsEqualIID(riid,IID_IContextMenu2)){*ppv=(IContextMenu2*)this;}elseif(IsEqualIID(riid,IID_IContextMenu3)){*ppv=(IContextMenu3*)this;}if(*ppv){AddRef();returnS_OK;}returnE_NOINTERFACE;}
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.