From: <arn...@us...> - 2006-12-07 22:44:57
|
Revision: 686 http://svn.sourceforge.net/dcplusplus/?rev=686&view=rev Author: arnetheduck Date: 2006-12-07 14:44:50 -0800 (Thu, 07 Dec 2006) Log Message: ----------- missing files Added Paths: ----------- dcplusplus/trunk/windows/ShellContextMenu.cpp dcplusplus/trunk/windows/ShellContextMenu.h dcplusplus/trunk/windows/TabsPage.cpp dcplusplus/trunk/windows/TabsPage.h Added: dcplusplus/trunk/windows/ShellContextMenu.cpp =================================================================== --- dcplusplus/trunk/windows/ShellContextMenu.cpp (rev 0) +++ dcplusplus/trunk/windows/ShellContextMenu.cpp 2006-12-07 22:44:50 UTC (rev 686) @@ -0,0 +1,237 @@ +/* +/* +* Based on a class by R. Engels +* http://www.codeproject.com/shell/shellcontextmenu.asp +*/ + +#include "stdafx.h" +#include "../client/DCPlusPlus.h" +#include "Resource.h" + +#include "ShellContextMenu.h" + +IContextMenu2* g_IContext2 = NULL; +IContextMenu3* g_IContext3 = NULL; + +CShellContextMenu::CShellContextMenu() : bDelete(false) +{ + m_psfFolder = NULL; + m_pidlArray = NULL; + m_Menu = NULL; +} + +CShellContextMenu::~CShellContextMenu() +{ + // free all allocated datas + if(m_psfFolder && bDelete) + m_psfFolder->Release(); + m_psfFolder = NULL; + FreePIDLArray(m_pidlArray); + m_pidlArray = NULL; + + if(m_Menu) + delete m_Menu; +} + +void CShellContextMenu::SetPath(const tstring& strPath) +{ + // free all allocated datas + if(m_psfFolder && bDelete) + m_psfFolder->Release(); + m_psfFolder = NULL; + FreePIDLArray(m_pidlArray); + m_pidlArray = NULL; + + // get IShellFolder interface of Desktop(root of shell namespace) + IShellFolder* psfDesktop = NULL; + SHGetDesktopFolder(&psfDesktop); + + // ParseDisplayName creates a PIDL from a file system path relative to the IShellFolder interface + // but since we use the Desktop as our interface and the Desktop is the namespace root + // that means that it's a fully qualified PIDL, which is what we need + LPITEMIDLIST pidl = NULL; + psfDesktop->ParseDisplayName(NULL, 0, (LPOLESTR)const_cast<TCHAR*>(strPath.c_str()), NULL, &pidl, NULL); + + // now we need the parent IShellFolder interface of pidl, and the relative PIDL to that interface + SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&m_psfFolder, NULL); + + // get interface to IMalloc (need to free the PIDLs allocated by the shell functions) + LPMALLOC lpMalloc = NULL; + SHGetMalloc(&lpMalloc); + lpMalloc->Free(pidl); + + // now we need the relative pidl + IShellFolder* psfFolder = NULL; + psfDesktop->ParseDisplayName (NULL, 0, (LPOLESTR)const_cast<TCHAR*>(strPath.c_str()), NULL, &pidl, NULL); + LPITEMIDLIST pidlItem = NULL; + SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psfFolder, (LPCITEMIDLIST*)&pidlItem); + + // copy pidlItem to m_pidlArray + m_pidlArray = (LPITEMIDLIST *) realloc(m_pidlArray, sizeof (LPITEMIDLIST)); + int nSize = 0; + LPITEMIDLIST pidlTemp = pidlItem; + while(pidlTemp->mkid.cb) + { + nSize += pidlTemp->mkid.cb; + pidlTemp = (LPITEMIDLIST) (((LPBYTE) pidlTemp) + pidlTemp->mkid.cb); + } + LPITEMIDLIST pidlRet = (LPITEMIDLIST) calloc(nSize + sizeof (USHORT), sizeof (BYTE)); + CopyMemory(pidlRet, pidlItem, nSize); + m_pidlArray[0] = pidlRet; + + free(pidlItem); + lpMalloc->Free(pidl); + + lpMalloc->Release(); + psfFolder->Release(); + psfDesktop->Release(); + + bDelete = true; // indicates that m_psfFolder should be deleted by CShellContextMenu +} + +CMenu* CShellContextMenu::GetMenu() +{ + if(!m_Menu) + { + m_Menu = new CMenu; + m_Menu->CreatePopupMenu(); // create the popupmenu(its empty) + } + return m_Menu; +} + +UINT CShellContextMenu::ShowContextMenu(HWND hWnd, CPoint pt) +{ + int iMenuType = 0; // to know which version of IContextMenu is supported + LPCONTEXTMENU pContextMenu; // common pointer to IContextMenu and higher version interface + + if(!GetContextMenu((LPVOID*)&pContextMenu, iMenuType)) + return 0; // something went wrong + + if(!m_Menu) + { + delete m_Menu; + m_Menu = NULL; + m_Menu = new CMenu; + m_Menu->CreatePopupMenu(); + } + + // lets fill the popupmenu + pContextMenu->QueryContextMenu(m_Menu->m_hMenu, m_Menu->GetMenuItemCount(), ID_SHELLCONTEXTMENU_MIN, ID_SHELLCONTEXTMENU_MAX, CMF_NORMAL | CMF_EXPLORE); + + // subclass window to handle menurelated messages in CShellContextMenu + WNDPROC OldWndProc; + if(iMenuType > 1) // only subclass if its version 2 or 3 + { + OldWndProc = (WNDPROC) SetWindowLong(hWnd, GWL_WNDPROC, (DWORD) HookWndProc); + if(iMenuType == 2) + g_IContext2 = (LPCONTEXTMENU2) pContextMenu; + else // version 3 + g_IContext3 = (LPCONTEXTMENU3) pContextMenu; + } + else + OldWndProc = NULL; + + UINT idCommand = m_Menu->TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN, pt.x, pt.y, hWnd); + + if(OldWndProc) // unsubclass + SetWindowLong(hWnd, GWL_WNDPROC, (DWORD) OldWndProc); + + if(idCommand >= ID_SHELLCONTEXTMENU_MIN && idCommand <= ID_SHELLCONTEXTMENU_MAX) + { + InvokeCommand(pContextMenu, idCommand - ID_SHELLCONTEXTMENU_MIN); + idCommand = 0; + } + + pContextMenu->Release(); + g_IContext2 = NULL; + g_IContext3 = NULL; + + return idCommand; +} + +void CShellContextMenu::FreePIDLArray(LPITEMIDLIST* pidlArray) +{ + if(!pidlArray) + return; + + int iSize = _msize (pidlArray) / sizeof (LPITEMIDLIST); + + for(int i = 0; i < iSize; i++) + free(pidlArray[i]); + free(pidlArray); +} + +// this functions determines which version of IContextMenu is avaibale for those objects(always the highest one) +// and returns that interface +bool CShellContextMenu::GetContextMenu(LPVOID* ppContextMenu, int& iMenuType) +{ + *ppContextMenu = NULL; + LPCONTEXTMENU icm1 = NULL; + + // first we retrieve the normal IContextMenu interface(every object should have it) + m_psfFolder->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST *) m_pidlArray, IID_IContextMenu, NULL, (LPVOID*) &icm1); + + if(icm1) + { // since we got an IContextMenu interface we can now obtain the higher version interfaces via that + if(icm1->QueryInterface(IID_IContextMenu3, ppContextMenu) == NOERROR) + iMenuType = 3; + else if(icm1->QueryInterface(IID_IContextMenu2, ppContextMenu) == NOERROR) + iMenuType = 2; + + if(*ppContextMenu) + icm1->Release(); // we can now release version 1 interface, cause we got a higher one + else + { + iMenuType = 1; + *ppContextMenu = icm1; // since no higher versions were found + } // redirect ppContextMenu to version 1 interface + + return true; // success + } + + return false; // something went wrong +} + +void CShellContextMenu::InvokeCommand(LPCONTEXTMENU pContextMenu, UINT idCommand) +{ + CMINVOKECOMMANDINFO cmi = {0}; + cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); + cmi.lpVerb = (LPSTR) MAKEINTRESOURCE(idCommand); + cmi.nShow = SW_SHOWNORMAL; + + pContextMenu->InvokeCommand(&cmi); +} + +LRESULT CALLBACK CShellContextMenu::HookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case WM_MENUCHAR: // only supported by IContextMenu3 + if(g_IContext3) + { + LRESULT lResult = 0; + g_IContext3->HandleMenuMsg2(message, wParam, lParam, &lResult); + return lResult; + } + break; + + case WM_DRAWITEM: + case WM_MEASUREITEM: + if(wParam) + break; // if wParam != 0 then the message is not menu-related + + case WM_INITMENUPOPUP: + if(g_IContext2) + g_IContext2->HandleMenuMsg(message, wParam, lParam); + else // version 3 + g_IContext3->HandleMenuMsg(message, wParam, lParam); + return (message == WM_INITMENUPOPUP) ? 0 : TRUE; // inform caller that we handled WM_INITPOPUPMENU by ourself + break; + + default: + break; + } + + // call original WndProc of window to prevent undefined bevhaviour of window + return ::CallWindowProc((WNDPROC) GetProp( hWnd, _T("OldWndProc")), hWnd, message, wParam, lParam); +} Added: dcplusplus/trunk/windows/ShellContextMenu.h =================================================================== --- dcplusplus/trunk/windows/ShellContextMenu.h (rev 0) +++ dcplusplus/trunk/windows/ShellContextMenu.h 2006-12-07 22:44:50 UTC (rev 686) @@ -0,0 +1,37 @@ +/* +/* +* Based on a class by R. Engels +* http://www.codeproject.com/shell/shellcontextmenu.asp +*/ + +#if !defined(SHELLCONTEXTMENU_H) +#define SHELLCONTEXTMENU_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class CShellContextMenu +{ +public: + CShellContextMenu(); + virtual ~CShellContextMenu(); + + void SetPath(const tstring& strPath); + CMenu* GetMenu(); + UINT ShowContextMenu(HWND hWnd, CPoint pt); + +private: + bool bDelete; + CMenu* m_Menu; + IShellFolder* m_psfFolder; + LPITEMIDLIST* m_pidlArray; + + void FreePIDLArray(LPITEMIDLIST* pidlArray); + void SHBindToParentEx(LPCITEMIDLIST pidl, REFIID riid, LPVOID* ppv, LPCITEMIDLIST* ppidlLast); + bool GetContextMenu(LPVOID* ppContextMenu, int& iMenuType); + void InvokeCommand(LPCONTEXTMENU pContextMenu, UINT idCommand); + static LRESULT CALLBACK HookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +}; + +#endif // !defined(SHELLCONTEXTMENU_H) Added: dcplusplus/trunk/windows/TabsPage.cpp =================================================================== --- dcplusplus/trunk/windows/TabsPage.cpp (rev 0) +++ dcplusplus/trunk/windows/TabsPage.cpp 2006-12-07 22:44:50 UTC (rev 686) @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "stdafx.h" +#include "../client/DCPlusPlus.h" +#include "Resource.h" + +#include "TabsPage.h" + +#include "../client/SettingsManager.h" +#include "../client/FavoriteManager.h" +#include "WinUtil.h" + +PropPage::Item TabsPage::items[] = { + { IDC_MAX_TAB_ROWS, SettingsManager::MAX_TAB_ROWS, PropPage::T_INT }, + { 0, 0, PropPage::T_END } +}; + +PropPage::TextItem TabsPage::texts[] = { + { IDC_SETTINGS_MAX_TAB_ROWS, ResourceManager::SETTINGS_MAX_TAB_ROWS }, + { IDC_SETTINGS_BOLD_CONTENTS, ResourceManager::SETTINGS_BOLD_OPTIONS }, + { 0, ResourceManager::SETTINGS_AUTO_AWAY } +}; + +PropPage::ListItem TabsPage::listItems[] = { + { SettingsManager::BOLD_FINISHED_DOWNLOADS, ResourceManager::FINISHED_DOWNLOADS }, + { SettingsManager::BOLD_FINISHED_UPLOADS, ResourceManager::FINISHED_UPLOADS }, + { SettingsManager::BOLD_QUEUE, ResourceManager::DOWNLOAD_QUEUE }, + { SettingsManager::BOLD_HUB, ResourceManager::HUB }, + { SettingsManager::BOLD_PM, ResourceManager::PRIVATE_MESSAGE }, + { SettingsManager::BOLD_SEARCH, ResourceManager::SEARCH }, + { SettingsManager::BOLD_WAITING_USERS, ResourceManager::WAITING_USERS }, + { SettingsManager::BOLD_SYSTEM_LOG, ResourceManager::SYSTEM_LOG }, + { 0, ResourceManager::SETTINGS_AUTO_AWAY } +}; + +LRESULT TabsPage::onInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + PropPage::translate((HWND)(*this), texts); + PropPage::read((HWND)*this, items, listItems,GetDlgItem(IDC_BOLD_BOOLEANS)); + + // Do specialized reading here + return TRUE; +} + +void TabsPage::write() { + PropPage::write((HWND)*this, items, listItems,GetDlgItem(IDC_BOLD_BOOLEANS)); +} + +LRESULT TabsPage::onHelpInfo(LPNMHDR /*pnmh*/) { + HtmlHelp(m_hWnd, WinUtil::getHelpFile().c_str(), HH_HELP_CONTEXT, IDD_TABSPAGE); + return 0; +} + +LRESULT TabsPage::onHelp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { + HtmlHelp(m_hWnd, WinUtil::getHelpFile().c_str(), HH_HELP_CONTEXT, IDD_TABSPAGE); + return 0; +} Added: dcplusplus/trunk/windows/TabsPage.h =================================================================== --- dcplusplus/trunk/windows/TabsPage.h (rev 0) +++ dcplusplus/trunk/windows/TabsPage.h 2006-12-07 22:44:50 UTC (rev 686) @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#if !defined(TABS_PAGE_H) +#define TABS_PAGE_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include <atlcrack.h> +#include "PropPage.h" + +class TabsPage : public CPropertyPage<IDD_TABSPAGE>, public PropPage +{ +public: + TabsPage(SettingsManager *s) : PropPage(s) { + SetTitle(CTSTRING(SETTINGS_TABS)); + m_psp.dwFlags |= PSP_HASHELP | PSP_RTLREADING; + } + + virtual ~TabsPage() { } + + BEGIN_MSG_MAP(TabsPage) + MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog) + NOTIFY_CODE_HANDLER_EX(PSN_HELP, onHelpInfo) + MESSAGE_HANDLER(WM_HELP, onHelp) + END_MSG_MAP() + + LRESULT onInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT onHelp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT onHelpInfo(LPNMHDR /*pnmh*/); + + // Common PropPage interface + PROPSHEETPAGE *getPSP() { return (PROPSHEETPAGE *)*this; } + virtual void write(); + +protected: + static TextItem texts[]; + static Item items[]; + static ListItem listItems[]; +}; + +#endif // !defined(TABS_PAGE_H) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |