Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
query.cpp
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 173k
Category:
Windows Kernel
Development Platform:
Visual C++
- #include "pch.h"
- #include "stddef.h"
- #pragma hdrstop
- /*-----------------------------------------------------------------------------
- / Result view
- /----------------------------------------------------------------------------*/
- //
- // CDsQuery which implements IQueryHandler, IQueryForm etc
- //
- class CDsQuery; // forward reference
- typedef HRESULT (*LPCOLLECTPROC)(CDsQuery* pdq, LPARAM lParam, INT item, LPQUERYRESULT pResult);
- class CDsQuery : public IQueryHandler, IQueryForm, IObjectWithSite, IDsQueryHandler, CUnknown
- {
- friend HRESULT _ScopeProc(LPCQSCOPE pScope, UINT uMsg, LPVOID pVoid);
- friend HRESULT _AddScope(INT iIndent, LPWSTR pPath, LPWSTR pObjectClass, BOOL fSelect);
- friend LRESULT CALLBACK _ResultViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- friend int CALLBACK _BrowseForScopeCB(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
- friend HRESULT _GetIDLCollectCB(CDsQuery* pdq, LPARAM lParam, INT item, LPQUERYRESULT pResult);
- public:
- CDsQuery();
- ~CDsQuery();
- // IUnknown
- STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);
- STDMETHOD_(ULONG, AddRef)();
- STDMETHOD_(ULONG, Release)();
- // IQueryForms
- STDMETHOD(Initialize)(THIS_ HKEY hkForm);
- STDMETHOD(AddForms)(THIS_ LPCQADDFORMSPROC pAddFormsProc, LPARAM lParam);
- STDMETHOD(AddPages)(THIS_ LPCQADDPAGESPROC pAddPagesProc, LPARAM lParam);
- // IQueryHandler
- STDMETHOD(Initialize)(THIS_ IQueryFrame* pQueryFrame, DWORD dwOQWFlags, LPVOID pParameters);
- STDMETHOD(GetViewInfo)(THIS_ LPCQVIEWINFO pViewInfo);
- STDMETHOD(AddScopes)(THIS);
- STDMETHOD(BrowseForScope)(THIS_ HWND hwndParent, LPCQSCOPE pCurrentScope, LPCQSCOPE* ppScope);
- STDMETHOD(CreateResultView)(THIS_ HWND hwndParent, HWND* phWndView);
- STDMETHOD(ActivateView)(THIS_ UINT uState, WPARAM wParam, LPARAM lParam);
- STDMETHOD(InvokeCommand)(THIS_ HWND hwndParent, UINT uID);
- STDMETHOD(GetCommandString)(THIS_ UINT uID, DWORD dwFlags, LPTSTR pBuffer, INT cchBuffer);
- STDMETHOD(IssueQuery)(THIS_ LPCQPARAMS pQueryParams);
- STDMETHOD(StopQuery)(THIS);
- STDMETHOD(GetViewObject)(THIS_ UINT uScope, REFIID riid, void **ppvOut);
- STDMETHOD(LoadQuery)(THIS_ IPersistQuery* pPersistQuery);
- STDMETHOD(SaveQuery)(THIS_ IPersistQuery* pPersistQuery, LPCQSCOPE pScope);
- // IObjectWithSite
- STDMETHODIMP SetSite(IUnknown* punk);
- STDMETHODIMP GetSite(REFIID riid, void **ppv);
- // IDsQueryHandler
- STDMETHOD(UpdateView)(THIS_ DWORD dwType, LPDSOBJECTNAMES pdon);
- private:
- LRESULT OnSize(INT cx, INT cy);
- LRESULT OnNotify(HWND hWnd, WPARAM wParam, LPARAM lParam);
- HRESULT OnAddResults(DWORD dwQueryReference, HDPA hdpaResults);
- LRESULT OnContextMenu(HWND hwndMenu, LPARAM lParam);
- HRESULT OnFileProperties(VOID);
- #if !DOWNLEVEL_SHELL
- HRESULT OnFileCreateShortcut(VOID);
- #endif
- HRESULT OnFileSaveQuery(VOID);
- HRESULT OnEditSelectAll(VOID);
- HRESULT OnEditInvertSelection(VOID);
- HRESULT OnPickColumns(HWND hwndParent);
- HRESULT _InitNewQuery(LPDSQUERYPARAMS pDsQueryParams, BOOL fRefreshColumnTable);
- HRESULT _GetFilterValue(INT iColumn, HD_ITEM* pitem);
- HRESULT _FilterView(BOOL fCheck);
- HRESULT _PopulateView(INT iFirstItem, INT iLast);
- VOID _FreeResults(VOID);
- DWORD _SetViewMode(INT uID);
- VOID _SortResults(INT iColumn);
- VOID _SetFilter(BOOL fFilter);
- VOID _ShowBanner(UINT flags, UINT idPrompt);
- VOID _InitViewMenuItems(HMENU hMenu);
- HRESULT _GetQueryFormKey(REFCLSID clsidForm, HKEY* phKey);
- HRESULT _GetColumnTable(REFCLSID clsidForm, LPDSQUERYPARAMS pDsQueryParams, HDSA* pHDSA, BOOL fSetInView);
- VOID _SaveColumnTable(VOID);
- HRESULT _SaveColumnTable(REFCLSID clsidForm, HDSA hdsaColumns);
- HRESULT _CollectViewSelection(BOOL fGetAll, INT* pCount, LPCOLLECTPROC pCollectProc, LPARAM lParam);
- HRESULT _GetIDLsAndViewObject(BOOL fGetAll, REFIID riid, void **ppcm);
- VOID _GetContextMenuVerbs(IContextMenu* pcm, HMENU hMenu, DWORD dwFlags);
- HRESULT _CopyCredentials(LPWSTR *ppszUserName, LPWSTR *ppszPassword, LPWSTR *ppszServer);
- HRESULT _GetDirectorySF(IShellFolder **ppsf);
- HRESULT _ADsPathToIdList(LPITEMIDLIST* ppidl, LPWSTR pPath, LPWSTR pObjectClasse);
- VOID _DeleteViewItems(LPDSOBJECTNAMES pdon);
- private:
- IQueryFrame* _pqf; // our parent window
- IUnknown* _punkSite; // site object
- IContextMenu* _pcm; // Curerntly displayed context menu / == NULL if none
- DWORD _dwOQWFlags; // flags passed to OpenQueryWindow
- DWORD _dwFlags; // flags as part of the ds query parameters
- LPWSTR _pDefaultScope; // default scope passed
- LPWSTR _pDefaultSaveLocation; // directory to save queries into by default
- LPTSTR _pDefaultSaveName; // default save name (from the query form)
- LPWSTR _pServer; // server to target
- LPWSTR _pUserName; // user name and password to authenticate with
- LPWSTR _pPassword;
- BOOL _fNoSelection:1; // the IContextMenu was from no selection
- BOOL _fColumnsModified:1; // settings of the view modified
- BOOL _fSortDescending:1; // sort the results descending
- BOOL _fFilter:1; // filter enabled
- BOOL _fFilterSupported:1; // is the filter available, eg: comctl32 > 5.0
- INT _idViewMode; // default view mode
- INT _iSortColumn; // sort column
- HWND _hwnd; // container window
- HWND _hwndView; // listview window (child of parent)
- HWND _hwndBanner; // banner window which is a child of the list view
- DWORD _dwQueryReference; // reference value passed to query
- HANDLE _hThread; // worker thread handle
- DWORD _dwThreadId; // thread ID for the Query processing thread
- CLSID _clsidForm; // form being used for column table
- HDSA _hdsaColumns; // column information (size, filters, etc)
- HDPA _hdpaResults; // results for tr the query we have issued
- LPTSTR _pFilter; // current filter
- HMENU _hFrameMenuBar; // stored frame menu bar, stored from activate
- HMENU _hFileMenu; // added to the frames view menu
- HMENU _hEditMenu; // inserted into the menu bar
- HMENU _hViewMenu; // inserted into the menu bar
- HMENU _hHelpMenu; // inserted into the menu bar
- };
- //
- // Window classes we create to show the results
- //
- #define VIEW_CLASS TEXT("ActiveDsQueryView")
- LRESULT CALLBACK _ResultViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- #define BANNER_CLASS TEXT("ActiveDsQueryBanner")
- LRESULT CALLBACK _BannerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- //
- // Registry values used for the settings
- //
- #define VIEW_SETTINGS_VALUE TEXT("ViewSettings")
- #define ADMIN_VIEW_SETTINGS_VALUE TEXT("AdminViewSettings");
- //
- // When filtering we populate the view using PostMessage, doing so many items
- // at a time
- //
- #define FILTER_UPDATE_COUNT 128
- //
- // All items within the list view contain the following LPARAM structure used
- // for storing the magic properties we are interested in.
- //
- #define ENABLE_MENU_ITEM(hMenu, id, fEnabled)
- EnableMenuItem(hMenu, id, (fEnabled) ? (MF_BYCOMMAND|MF_ENABLED):(MF_BYCOMMAND|MF_GRAYED))
- //
- // Persisted column data, this is stored in the registry under the CLSID for the
- // form we are interested in.
- //
- typedef struct
- {
- DWORD cbSize; // offset to the next column / == 0 if none
- DWORD dwFlags; // flags
- DWORD offsetProperty; // offset to property name (UNICODE)
- DWORD offsetHeading; // offset to column heading
- INT cx; // pixel width of the column
- INT fmt; // format of the column
- } SAVEDCOLUMN, * LPSAVEDCOLUMN;
- //
- // Table to map property types to useful information
- //
- struct
- {
- LPCTSTR pMenuName;
- INT idOperator;
- INT hdft;
- }
- property_type_table[] =
- {
- 0, 0, 0,
- MAKEINTRESOURCE(IDR_OP_STRING), FILTER_CONTAINS, HDFT_ISSTRING,
- MAKEINTRESOURCE(IDR_OP_STRING), FILTER_CONTAINS, HDFT_ISSTRING,
- MAKEINTRESOURCE(IDR_OP_NUMBER), FILTER_IS, HDFT_ISNUMBER,
- MAKEINTRESOURCE(IDR_OP_NUMBER), FILTER_IS, HDFT_ISNUMBER, // PROPERTY_ISBOOL
- };
- //
- // Help information for the frame and the control
- //
- static DWORD const aHelpIDs[] =
- {
- CQID_LOOKFORLABEL, IDH_FIND,
- CQID_LOOKFOR, IDH_FIND,
- CQID_LOOKINLABEL, IDH_IN,
- CQID_LOOKIN, IDH_IN,
- CQID_BROWSE, IDH_BROWSE,
- CQID_FINDNOW, IDH_FIND_NOW,
- CQID_STOP, IDH_STOP,
- CQID_CLEARALL, IDH_CLEAR_ALL,
- IDC_RESULTS, IDH_RESULTS,
- IDC_STATUS, IDH_NO_HELP,
- 0, 0,
- };
- //
- // Help information for the browse dialog that is shown for scopes
- //
- static DWORD const aBrowseHelpIDs[] =
- {
- DSBID_BANNER, (DWORD)-1,
- DSBID_CONTAINERLIST, IDH_BROWSE_CONTAINER,
- 0, 0,
- };
- //
- // path to DsFolder
- //
- #if DELEGATE
- WCHAR c_szDsMagicPath[] = L"::{208D2C60-3AEA-1069-A2D7-08002B30309D}";
- #else
- WCHAR c_szDsMagicPath[] = L"::{208D2C60-3AEA-1069-A2D7-08002B30309D}\EntireNetwork\::{fe1290f0-cfbd-11cf-a330-00aa00c16e65}";
- #endif
- /*-----------------------------------------------------------------------------
- / CDsQuery
- /----------------------------------------------------------------------------*/
- CDsQuery::CDsQuery() :
- _fNoSelection(TRUE),
- _iSortColumn(-1),
- _idViewMode(DSQH_VIEW_DETAILS)
- {
- TraceEnter(TRACE_HANDLER, "CDsQuery::CDsQuery");
- if ( CheckDsPolicy(NULL, c_szEnableFilter) )
- {
- TraceMsg("QuickFilter enabled in policy");
- _fFilter = TRUE;
- }
- TraceLeave();
- }
- CDsQuery::~CDsQuery()
- {
- TraceEnter(TRACE_HANDLER, "CDsQuery::~CDsQuery");
- // persist the column information if we need to
- if ( _hdsaColumns )
- {
- if ( _fColumnsModified )
- {
- _SaveColumnTable(_clsidForm, _hdsaColumns);
- _fColumnsModified = FALSE;
- }
- _SaveColumnTable();
- }
- // discard all the other random state we have
- LocalFreeStringW(&_pDefaultScope);
- LocalFreeStringW(&_pDefaultSaveLocation);
- LocalFreeString(&_pDefaultSaveName);
- LocalFreeStringW(&_pUserName);
- LocalFreeStringW(&_pPassword);
- LocalFreeStringW(&_pServer);
- if ( IsWindow(_hwnd) )
- DestroyWindow(_hwnd);
- if ( IsMenu(_hFileMenu) )
- DestroyMenu(_hFileMenu);
- if ( IsMenu(_hEditMenu) )
- DestroyMenu(_hEditMenu);
- if ( IsMenu(_hViewMenu) )
- DestroyMenu(_hViewMenu);
- if ( IsMenu(_hHelpMenu) )
- DestroyMenu(_hHelpMenu);
- // tell the thread its time to die
- if ( _hThread )
- {
- PostThreadMessage(_dwThreadId, RVTM_STOPQUERY, 0, 0);
- PostThreadMessage(_dwThreadId, WM_QUIT, 0, 0);
- CloseHandle(_hThread);
- }
- DoRelease(_pqf);
- DoRelease(_punkSite);
- DoRelease(_pcm);
- TraceLeave();
- }
- // IUnknown bits
- #undef CLASS_NAME
- #define CLASS_NAME CDsQuery
- #include "unknown.inc"
- STDMETHODIMP CDsQuery::QueryInterface(REFIID riid, void **ppvObject)
- {
- INTERFACES iface[] =
- {
- &IID_IQueryForm, (IQueryForm*)this,
- &IID_IQueryHandler, (IQueryHandler*)this,
- &IID_IObjectWithSite, (IObjectWithSite*)this,
- &IID_IDsQueryHandler, (IDsQueryHandler*)this,
- };
- return HandleQueryInterface(riid, ppvObject, iface, ARRAYSIZE(iface));
- }
- //
- // Handle creating an instance of CLSID_DsQuery
- //
- STDAPI CDsQuery_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk, LPCOBJECTINFO poi)
- {
- CDsQuery *pdq = new CDsQuery();
- if ( !pdq )
- return E_OUTOFMEMORY;
- HRESULT hres = pdq->QueryInterface(IID_IUnknown, (void **)ppunk);
- pdq->Release();
- return hres;
- }
- /*-----------------------------------------------------------------------------
- / IQueryForm methods
- /----------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::Initialize(THIS_ HKEY hkForm)
- {
- TraceEnter(TRACE_FORMS, "CDsQuery::Initialize");
- TraceLeaveResult(S_OK);
- }
- /*---------------------------------------------------------------------------*/
- struct
- {
- CLSID const * clsidForm;
- INT idsTitle;
- DWORD dwFlags;
- }
- forms[] =
- {
- &CLSID_DsFindPeople, IDS_FINDUSER, 0,
- &CLSID_DsFindComputer, IDS_FINDCOMPUTER, 0,
- &CLSID_DsFindPrinter, IDS_FINDPRINTERS, 0,
- &CLSID_DsFindVolume, IDS_FINDSHAREDFOLDERS, 0,
- &CLSID_DsFindContainer, IDS_FINDOU, 0,
- &CLSID_DsFindAdvanced, IDS_CUSTOMSEARCH, CQFF_NOGLOBALPAGES,
- &CLSID_DsFindDomainController, IDS_FINDDOMCTL, CQFF_ISNEVERLISTED|CQFF_NOGLOBALPAGES,
- &CLSID_DsFindFrsMembers, IDS_FINDFRSMEMBER, CQFF_ISNEVERLISTED|CQFF_NOGLOBALPAGES,
- };
- STDMETHODIMP CDsQuery::AddForms(THIS_ LPCQADDFORMSPROC pAddFormsProc, LPARAM lParam)
- {
- HRESULT hres;
- TCHAR szBuffer[MAX_PATH];
- INT i;
- TraceEnter(TRACE_FORMS, "CDsQuery::AddForms");
- if ( !pAddFormsProc )
- ExitGracefully(hres, E_INVALIDARG, "No AddFormsProc");
- for ( i = 0; i < ARRAYSIZE(forms); i++ )
- {
- CQFORM qf = { 0 };
- qf.cbStruct = SIZEOF(qf);
- qf.dwFlags = forms[i].dwFlags;
- qf.clsid = *forms[i].clsidForm;
- qf.pszTitle = szBuffer;
- LoadString(GLOBAL_HINSTANCE, forms[i].idsTitle, szBuffer, ARRAYSIZE(szBuffer));
- hres = (*pAddFormsProc)(lParam, &qf);
- FailGracefully(hres, "Failed to add form (calling pAddFormsFunc)");
- }
- hres = S_OK; // success
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- struct
- {
- CLSID const * clisdForm;
- LPCQPAGEPROC pPageProc;
- DLGPROC pDlgProc;
- INT idPageTemplate;
- INT idPageName;
- DWORD dwFlags;
- }
- pages[] =
- {
- //
- // Page list for the default forms that we add
- //
- &CLSID_DsFindPeople, PageProc_User, DlgProc_User, IDD_FINDUSER, IDS_FINDUSER, 0,
- &CLSID_DsFindComputer, PageProc_Computer, DlgProc_Computer, IDD_FINDCOMPUTER, IDS_FINDCOMPUTER, 0,
- &CLSID_DsFindPrinter, PageProc_Printers, DlgProc_Printers, IDD_FINDPRINT1, IDS_FINDPRINTERS, 0,
- &CLSID_DsFindPrinter, PageProc_PrintersMore, DlgProc_PrintersMore, IDD_FINDPRINT2, IDS_MORECHOICES, 0,
- &CLSID_DsFindVolume, PageProc_Volume, DlgProc_Volume, IDD_FINDVOLUME, IDS_FINDSHAREDFOLDERS, 0,
- &CLSID_DsFindContainer, PageProc_Container, DlgProc_Container, IDD_FINDCONTAINER, IDS_FINDOU, 0,
- &CLSID_DsFindAdvanced, PageProc_PropertyWell, DlgProc_PropertyWell, IDD_PROPERTYWELL, IDS_CUSTOMSEARCH, 0,
- &CLSID_DsFindAdvanced, PageProc_RawLDAP, DlgProc_RawLDAP, IDD_FINDUSINGLDAP, IDS_ADVANCED, 0,
- &CLSID_DsFindDomainController, PageProc_DomainController, DlgProc_DomainController, IDD_FINDDOMCTL, IDS_FINDDOMCTL, 0,
- &CLSID_DsFindFrsMembers, PageProc_FrsMember, DlgProc_FrsMember, IDD_FINDFRSMEMBER, IDS_FINDFRSMEMBER, 0,
- //
- // Make the property well available on all pages (using the magic CQPF_ADDTOALLFORMS bit)
- //
- &CLSID_DsFindAdvanced, PageProc_PropertyWell, DlgProc_PropertyWell, IDD_PROPERTYWELL, IDS_ADVANCED, CQPF_ISGLOBAL,
- };
- STDMETHODIMP CDsQuery::AddPages(THIS_ LPCQADDPAGESPROC pAddPagesProc, LPARAM lParam)
- {
- HRESULT hres;
- INT i;
- TraceEnter(TRACE_FORMS, "CDsQuery::AddPages");
- if ( !pAddPagesProc )
- ExitGracefully(hres, E_INVALIDARG, "No AddPagesProc");
- for ( i = 0 ; i < ARRAYSIZE(pages) ; i++ )
- {
- CQPAGE qp = { 0 };
- qp.cbStruct = SIZEOF(qp);
- qp.dwFlags = pages[i].dwFlags;
- qp.pPageProc = pages[i].pPageProc;
- qp.hInstance = GLOBAL_HINSTANCE;
- qp.idPageName = pages[i].idPageName;
- qp.idPageTemplate = pages[i].idPageTemplate;
- qp.pDlgProc = pages[i].pDlgProc;
- hres = (*pAddPagesProc)(lParam, *pages[i].clisdForm, &qp);
- FailGracefully(hres, "Failed to add page (calling pAddPagesFunc)");
- }
- hres = S_OK;
- exit_gracefully:
- TraceLeaveResult(S_OK);
- }
- /*-----------------------------------------------------------------------------
- / IQueryHandler methods
- /----------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::Initialize(THIS_ IQueryFrame* pQueryFrame, DWORD dwOQWFlags, LPVOID pParameters)
- {
- HRESULT hres;
- LPDSQUERYINITPARAMS pDsQueryInitParams = (LPDSQUERYINITPARAMS)pParameters;
- TCHAR szGUID[GUIDSTR_MAX];
- TCHAR szBuffer[MAX_PATH];
- HINSTANCE hInstanceComCtl32 = NULL;
- USES_CONVERSION;
- TraceEnter(TRACE_HANDLER, "CDsQuery::Initialize");
- // Keep the IQueryFrame interface, we need it for menu negotiation and other
- // view -> frame interactions.
- _pqf = pQueryFrame;
- _pqf->AddRef();
- _dwOQWFlags = dwOQWFlags;
- // If we have a parameter block then lets take copies of the interesting
- // fields from there.
- if ( pDsQueryInitParams )
- {
- _dwFlags = pDsQueryInitParams->dwFlags;
- // did the user specify a default scope?
- if ( pDsQueryInitParams->pDefaultScope && pDsQueryInitParams->pDefaultScope[0] )
- {
- Trace(TEXT("Default scope:"), W2T(pDsQueryInitParams->pDefaultScope));
- hres = LocalAllocStringW(&_pDefaultScope, pDsQueryInitParams->pDefaultScope);
- FailGracefully(hres, "Failed to cope default scope");
- }
- // default save location?
- if ( (_dwFlags & DSQPF_SAVELOCATION) && pDsQueryInitParams->pDefaultSaveLocation )
- {
- Trace(TEXT("Default save location:"), W2T(pDsQueryInitParams->pDefaultSaveLocation));
- hres = LocalAllocStringW(&_pDefaultSaveLocation, pDsQueryInitParams->pDefaultSaveLocation);
- FailGracefully(hres, "Failed to copy save location");
- }
- // do we have credential information?
- if ( _dwFlags & DSQPF_HASCREDENTIALS )
- {
- TraceMsg("Copying credential/server information from init params");
- if ( pDsQueryInitParams->pUserName )
- {
- hres = LocalAllocStringW(&_pUserName, pDsQueryInitParams->pUserName);
- FailGracefully(hres, "Failed to copy user name");
- }
- if ( pDsQueryInitParams->pPassword )
- {
- hres = LocalAllocStringW(&_pPassword, pDsQueryInitParams->pPassword);
- FailGracefully(hres, "Failed to copy password");
- }
- if ( pDsQueryInitParams->pServer )
- {
- hres = LocalAllocStringW(&_pServer, pDsQueryInitParams->pServer);
- FailGracefully(hres, "Failed to copy server");
- }
- Trace(TEXT("_pUserName : %s"), _pUserName ? W2T(_pUserName):TEXT("<not specified>"));
- Trace(TEXT("_pPassword : %s"), _pPassword ? W2T(_pPassword):TEXT("<not specified>"));
- Trace(TEXT("_pServer : %s"), _pServer ? W2T(_pServer):TEXT("<not specified>"));
- }
- }
- // Finally load the must structures that we are going to use, then modify them
- // based on the flags that the caller gave us.
- //
- // NB: removes the last two items from the file menu assumed to be the
- // "save" and its seperator
- _hFileMenu = LoadMenu(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDR_MENU_FILE));
- _hEditMenu = LoadMenu(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDR_MENU_EDIT));
- _hViewMenu = LoadMenu(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDR_MENU_VIEW));
- _hHelpMenu = LoadMenu(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDR_MENU_HELP));
- if ( !_hFileMenu || !_hEditMenu || !_hViewMenu || !_hHelpMenu )
- ExitGracefully(hres, E_FAIL, "Failed to load resources for menus");
- if ( _dwFlags & DSQPF_NOSAVE )
- {
- HMENU hFileMenu = GetSubMenu(_hFileMenu, 0);
- INT i = GetMenuItemCount(hFileMenu);
- DeleteMenu(hFileMenu, i-1, MF_BYPOSITION);
- DeleteMenu(hFileMenu, i-2, MF_BYPOSITION);
- }
- // Init ComCtl32, including checking to see if we can use the filter control or not,
- // the filter control was added to the WC_HEADER32 in IE5, so check the DLL version
- // to see which we are using.
- InitCommonControls();
- hInstanceComCtl32 = GetModuleHandle(TEXT("comctl32"));
- TraceAssert(hInstanceComCtl32);
- if ( hInstanceComCtl32 )
- {
- DLLVERSIONINFO dllVersionInfo = { 0 };
- DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hInstanceComCtl32, "DllGetVersion");
- TraceAssert(pfnDllGetVersion);
- dllVersionInfo.cbSize = SIZEOF(dllVersionInfo);
- if ( pfnDllGetVersion && SUCCEEDED(pfnDllGetVersion(&dllVersionInfo)) )
- {
- Trace(TEXT("DllGetVersion succeeded on ComCtl32, dwMajorVersion %08x"), dllVersionInfo.dwMajorVersion);
- _fFilterSupported = dllVersionInfo.dwMajorVersion >= 5;
- }
- }
- Trace(TEXT("_fFilterSupported is %d"), _fFilterSupported);
- hres = S_OK; // success
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::GetViewInfo(THIS_ LPCQVIEWINFO pViewInfo)
- {
- HICON hIcon;
- TraceEnter(TRACE_HANDLER, "CDsQuery::GetViewInfo");
- pViewInfo->dwFlags = 0;
- pViewInfo->hInstance = GLOBAL_HINSTANCE;
- pViewInfo->idLargeIcon = IDI_FIND;
- pViewInfo->idSmallIcon = IDI_FIND;
- pViewInfo->idTitle = IDS_WINDOWTITLE;
- pViewInfo->idAnimation = IDR_DSFINDANIMATION;
- TraceLeaveResult(S_OK);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::AddScopes(THIS)
- {
- HRESULT hres;
- DWORD dwThreadId;
- HANDLE hThread;
- LPSCOPETHREADDATA pstd = NULL;
- USES_CONVERSION;
- TraceEnter(TRACE_HANDLER, "CDsQuery::AddScopes");
- // Enumerate the rest of the scopes on a seperate thread to gather the
- // scopes we are interested in.
- pstd = (LPSCOPETHREADDATA)LocalAlloc(LPTR, SIZEOF(SCOPETHREADDATA));
- TraceAssert(pstd);
- if ( !pstd )
- ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate scope data structure");
- _pqf->GetWindow(&pstd->hwndFrame);
- // pstd->pDefaultScope = NULL;
- // pstd->pServer = NULL; // no credential stuff currently
- // pstd->pUserName = NULL;
- // pstd->pPassword = NULL;
- if ( _pDefaultScope )
- {
- hres = LocalAllocStringW(&pstd->pDefaultScope, _pDefaultScope);
- FailGracefully(hres, "Failed to copy the default scope");
- }
- hres = _CopyCredentials(&pstd->pUserName, &pstd->pPassword, &pstd->pServer);
- FailGracefully(hres, "Failed to copy credentails");
- InterlockedIncrement(&GLOBAL_REFCOUNT);
- hThread = CreateThread(NULL, 0, AddScopesThread, pstd, 0, &dwThreadId);
- TraceAssert(hThread);
- if ( !hThread )
- {
- InterlockedDecrement(&GLOBAL_REFCOUNT);
- ExitGracefully(hres, E_FAIL, "Failed to create background thread to enum scopes - BAD!");
- }
- CloseHandle(hThread);
- hres = S_OK;
- exit_gracefully:
- if ( FAILED(hres) && pstd )
- {
- LocalFreeStringW(&pstd->pDefaultScope);
- LocalFree((HLOCAL)pstd);
- }
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- typedef struct
- {
- IADsPathname *padp;
- WCHAR szGcPath[MAX_PATH];
- } BROWSEFORSCOPE;
- int CALLBACK _BrowseForScopeCB(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
- {
- HRESULT hres;
- INT iResult = 0;
- BROWSEFORSCOPE *pbfs = (BROWSEFORSCOPE*)lpData;
- LPTSTR pDirectoryName = NULL;
- USES_CONVERSION;
- TraceEnter(TRACE_HANDLER, "_BrowseForScopeCB");
- switch ( uMsg )
- {
- case DSBM_QUERYINSERT:
- {
- PDSBITEM pItem = (PDSBITEM)lParam;
- TraceAssert(pItem);
- // We are interested in modifying the root item of the tree, therefore
- // lets check for that being inserted, if it is then we change the
- // display name and the icon being shown.
- if ( pItem->dwState & DSBS_ROOT )
- {
- GetModuleFileName(GLOBAL_HINSTANCE, pItem->szIconLocation, ARRAYSIZE(pItem->szIconLocation));
- pItem->iIconResID = -IDI_GLOBALCATALOG;
- if ( SUCCEEDED(FormatDirectoryName(&pDirectoryName, GLOBAL_HINSTANCE, IDS_GLOBALCATALOG)) )
- {
- StrCpyN(pItem->szDisplayName, pDirectoryName, DSB_MAX_DISPLAYNAME_CHARS);
- LocalFreeString(&pDirectoryName);
- }
- pItem->dwMask |= DSBF_DISPLAYNAME|DSBF_ICONLOCATION;
- iResult = TRUE;
- }
- break;
- }
- case BFFM_SELCHANGED:
- {
- BOOL fEnableOK = TRUE;
- LPWSTR pszPath = (LPWSTR)lParam;
- LONG nElements = 0;
- // The user changes the selection in the browse dialog, therefore
- // lets see if we should be enabling the OK button. If the user
- // selects GC, but we don't have a GC then we disable it.
- if ( SUCCEEDED(pbfs->padp->Set(pszPath, ADS_SETTYPE_FULL)) )
- {
- pbfs->padp->GetNumElements(&nElements);
- Trace(TEXT("nElements on exit from GetNumElements %d"), nElements);
- }
- if ( !nElements && !pbfs->szGcPath[0] )
- {
- TraceMsg("'entire directory' selected with NO GC!");
- fEnableOK = FALSE;
- }
- SendMessage(hwnd, BFFM_ENABLEOK, (WPARAM)fEnableOK, 0L);
- break;
- }
- case DSBM_HELP:
- {
- WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
- DSQUERY_HELPFILE,
- HELP_WM_HELP,
- (DWORD_PTR)aBrowseHelpIDs);
- break;
- }
- case DSBM_CONTEXTMENU:
- {
- WinHelp((HWND)lParam,
- DSQUERY_HELPFILE,
- HELP_CONTEXTMENU,
- (DWORD_PTR)aBrowseHelpIDs);
- break;
- }
- }
- TraceLeaveValue(iResult);
- }
- STDMETHODIMP CDsQuery::BrowseForScope(THIS_ HWND hwndParent, LPCQSCOPE pCurrentScope, LPCQSCOPE* ppScope)
- {
- HRESULT hres;
- LPDSQUERYSCOPE pDsQueryScope = (LPDSQUERYSCOPE)pCurrentScope;
- BROWSEFORSCOPE bfs = { 0 };
- DSBROWSEINFO dsbi = { 0 };
- INT iResult;
- WCHAR szPath[2048];
- WCHAR szRoot[MAX_PATH+10]; // LDAP://
- WCHAR szObjectClass[64];
- LONG nElements;
- USES_CONVERSION;
- TraceEnter(TRACE_HANDLER, "CDsQuery::BrowseForScope");
- Trace(TEXT("hwndParent %08x, pCurrentScope %08x, ppScope %08x"), hwndParent, pCurrentScope, ppScope);
- *ppScope = NULL; // nothing yet!
- if ( SUCCEEDED(GetGlobalCatalogPath(_pServer, bfs.szGcPath, ARRAYSIZE(bfs.szGcPath))) )
- Trace(TEXT("GC path is: %s"), W2T(bfs.szGcPath));
- hres = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER, IID_IADsPathname, (void **)&bfs.padp);
- FailGracefully(hres, "Failed to get the IADsPathname interface");
- // Fill out the browse info structure to display the object picker, if we have
- // enabled admin features then lets make all objects visible, otherwise
- // just the standard features.
- dsbi.cbStruct = SIZEOF(dsbi);
- dsbi.hwndOwner = hwndParent;
- dsbi.pszRoot = szRoot;
- dsbi.pszPath = szPath;
- dsbi.cchPath = ARRAYSIZE(szPath);
- dsbi.dwFlags = (DSBI_RETURNOBJECTCLASS|DSBI_EXPANDONOPEN|DSBI_ENTIREDIRECTORY) & ~DSBI_NOROOT;
- dsbi.pfnCallback = _BrowseForScopeCB;
- dsbi.lParam = (LPARAM)&bfs;
- dsbi.pszObjectClass = szObjectClass;
- dsbi.cchObjectClass = ARRAYSIZE(szObjectClass);
- if ( _dwFlags & DSQPF_SHOWHIDDENOBJECTS )
- dsbi.dwFlags |= DSBI_INCLUDEHIDDEN;
- FormatMsgResource((LPTSTR*)&dsbi.pszTitle, GLOBAL_HINSTANCE, IDS_BROWSEPROMPT);
- StrCpyW(szRoot, c_szLDAP);
- if ( _pServer )
- {
- if ( lstrlenW(_pServer) > MAX_PATH )
- ExitGracefully(hres, E_INVALIDARG, "_pServer is too big");
- StrCatW(szRoot, L"//");
- StrCatW(szRoot, _pServer);
- }
- if ( pDsQueryScope )
- {
- StrCpyNW(szPath, OBJECT_NAME_FROM_SCOPE(pDsQueryScope), ARRAYSIZE(szPath));
- Trace(TEXT("pDsQueryScope: %s"), W2T(szPath));
- }
- // copy the credential information if needed
- if ( _dwFlags & DSQPF_HASCREDENTIALS )
- {
- TraceMsg("Setting credentails information");
- dsbi.pUserName = _pUserName;
- dsbi.pPassword = _pPassword;
- dsbi.dwFlags |= DSBI_HASCREDENTIALS;
- }
- iResult = DsBrowseForContainer(&dsbi);
- Trace(TEXT("DsBrowseForContainer returns %d"), iResult);
- // iResult == IDOK if something was selected (szPath),
- // if it is -VE if the call failed and we should error
- if ( iResult == IDOK )
- {
- LPWSTR pszScope = szPath;
- LPWSTR pszObjectClass = szObjectClass;
- LONG nElements = 0;
- Trace(TEXT("Path on exit from DsBrowseForContainer: %s"), W2T(szPath));
- // does this look like the GC? If so then default to it, as DsBrowseForContainer
- // will return us iffy looking information
- if ( SUCCEEDED(bfs.padp->Set(szPath, ADS_SETTYPE_FULL)) )
- {
- bfs.padp->GetNumElements(&nElements);
- Trace(TEXT("nElements on exit from GetNumElements %d"), nElements);
- }
- if ( !nElements )
- {
- TraceMsg("nElements = 0, so defaulting to GC");
- pszScope = bfs.szGcPath;
- pszObjectClass = GC_OBJECTCLASS;
- }
- Trace(TEXT("Scope selected is: %s, Object class: %s"), W2T(pszScope), W2T(pszObjectClass));
- hres = AllocScope(ppScope, 0, pszScope, pszObjectClass);
- FailGracefully(hres, "Failed converting the DS path to a scope");
- }
- else if ( iResult == IDCANCEL )
- {
- hres = S_FALSE; // nothing selected, returning S_FALSE;
- }
- else if ( iResult < 0 )
- {
- ExitGracefully(hres, E_FAIL, "DsBrowseForContainer failed");
- }
- exit_gracefully:
- LocalFreeString((LPTSTR*)&dsbi.pszTitle);
- Trace(TEXT("*ppScope == %08x"), *ppScope);
- DoRelease(bfs.padp);
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- //
- // WndProc for the banner window
- //
- LRESULT CALLBACK _BannerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- LRESULT lResult = 0;
- switch ( uMsg )
- {
- case WM_SIZE:
- InvalidateRect(hwnd, NULL, FALSE);
- break;
- case WM_ERASEBKGND:
- break;
- case WM_PAINT:
- {
- TCHAR szBuffer[MAX_PATH];
- HFONT hFont, hOldFont;
- SIZE szText;
- RECT rcClient;
- INT len;
- PAINTSTRUCT paint;
- COLORREF oldFgColor, oldBkColor;
- BeginPaint(hwnd, &paint);
- hFont = (HFONT)SendMessage(GetParent(hwnd), WM_GETFONT, 0, 0L);
- hOldFont = (HFONT)SelectObject(paint.hdc, hFont);
- if ( hOldFont )
- {
- oldFgColor = SetTextColor(paint.hdc, GetSysColor(COLOR_WINDOWTEXT));
- oldBkColor = SetBkColor(paint.hdc, ListView_GetBkColor(GetParent(hwnd)));
- len = GetWindowText(hwnd, szBuffer, ARRAYSIZE(szBuffer));
- GetTextExtentPoint32(paint.hdc, szBuffer, len, &szText);
- GetClientRect(GetParent(hwnd), &rcClient);
- ExtTextOut(paint.hdc,
- (rcClient.right - szText.cx) / 2,
- GetSystemMetrics(SM_CYBORDER)*4,
- ETO_CLIPPED|ETO_OPAQUE, &rcClient,
- szBuffer, len,
- NULL);
- SetTextColor(paint.hdc, oldFgColor);
- SetBkColor(paint.hdc, oldBkColor);
- SelectObject(paint.hdc, hOldFont);
- }
- EndPaint(hwnd, &paint);
- break;
- }
- case WM_SETTEXT:
- {
- InvalidateRect(hwnd, NULL, FALSE);
- //break; // deliberate drop through..
- }
- default:
- lResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
- break;
- }
- return lResult;
- }
- //
- // WndProc for the bg window (lives behind list view, used by rest of the world)
- //
- LRESULT CALLBACK _ResultViewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- LRESULT lResult = 0;
- CDsQuery* pDsQuery = NULL;
- if ( uMsg == WM_CREATE )
- {
- pDsQuery = (CDsQuery*)((LPCREATESTRUCT)lParam)->lpCreateParams;
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pDsQuery);
- }
- else
- {
- pDsQuery = (CDsQuery*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
- switch ( uMsg )
- {
- case WM_SIZE:
- pDsQuery->OnSize(LOWORD(lParam), HIWORD(lParam));
- return(0);
- case WM_DESTROY:
- pDsQuery->_hwndView = NULL; // view is gone!
- break;
- case WM_NOTIFY:
- return(pDsQuery->OnNotify(hwnd, wParam, lParam));
- case WM_SETFOCUS:
- SetFocus(pDsQuery->_hwndView);
- break;
- case WM_GETDLGCODE:
- return ((LRESULT)(DLGC_WANTARROWS | DLGC_WANTCHARS));
- case WM_CONTEXTMENU:
- pDsQuery->OnContextMenu(NULL, lParam);
- return TRUE;
- case DSQVM_ADDRESULTS:
- return SUCCEEDED(pDsQuery->OnAddResults((DWORD)wParam, (HDPA)lParam));
- case DSQVM_FINISHED:
- if ( (DWORD)wParam == pDsQuery->_dwQueryReference )
- {
- // the references match so lets finish the query, and display
- // the "too many results" prompt if the user did a really
- // big query and we chopped them off
- pDsQuery->StopQuery();
- if ( lParam ) // == 0 then we are OK!
- {
- HWND hwndFrame;
- pDsQuery->_pqf->GetWindow(&hwndFrame);
- FormatMsgBox(GetParent(hwndFrame),
- GLOBAL_HINSTANCE, IDS_WINDOWTITLE, IDS_ERR_MAXRESULT,
- MB_OK|MB_ICONERROR);
- }
- }
- SetFocus(pDsQuery->_hwndView);
- return(1);
- }
- }
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- STDMETHODIMP CDsQuery::CreateResultView(THIS_ HWND hwndParent, HWND* phWndView)
- {
- HRESULT hres;
- WNDCLASS wc;
- HWND hwndFilter, hwndFilterOld;
- HIMAGELIST himlSmall, himlLarge;
- DWORD dwLVStyle = LVS_AUTOARRANGE|LVS_SHAREIMAGELISTS|LVS_SHOWSELALWAYS|LVS_REPORT;
- RECT rc;
- TraceEnter(TRACE_HANDLER, "CDsQuery::CreateResultView");
- if ( IsWindow(_hwnd) )
- ExitGracefully(hres, E_FAIL, "Can only create one view at a time");
- // Create our result viewer, this is the parent window to the ListView
- // that we attach when we issue the query.
- ZeroMemory(&wc, SIZEOF(wc));
- wc.lpfnWndProc = _ResultViewWndProc;
- wc.hInstance = GLOBAL_HINSTANCE;
- wc.lpszClassName = VIEW_CLASS;
- RegisterClass(&wc);
- _hwnd = CreateWindow(VIEW_CLASS,
- NULL,
- WS_TABSTOP|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE,
- 0, 0, 0, 0,
- hwndParent,
- NULL,
- GLOBAL_HINSTANCE,
- this);
- if ( !_hwnd )
- ExitGracefully(hres, E_FAIL, "Failed to create view parent window");
- // Now register the window classes we are using.
- ZeroMemory(&wc, SIZEOF(wc));
- wc.lpfnWndProc = _BannerWndProc;
- wc.hInstance = GLOBAL_HINSTANCE;
- wc.lpszClassName = BANNER_CLASS;
- RegisterClass(&wc);
- if ( _dwOQWFlags & OQWF_SINGLESELECT )
- dwLVStyle |= LVS_SINGLESEL;
- GetClientRect(_hwnd, &rc);
- _hwndView = CreateWindowEx(WS_EX_CLIENTEDGE,
- WC_LISTVIEW,
- NULL,
- WS_TABSTOP|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE|dwLVStyle,
- 0, 0,
- rc.right, rc.bottom,
- _hwnd,
- (HMENU)IDC_RESULTS,
- GLOBAL_HINSTANCE,
- NULL);
- if ( !_hwndView )
- ExitGracefully(hres, E_FAIL, "Failed to create the view window");
- ListView_SetExtendedListViewStyle(_hwndView, LVS_EX_FULLROWSELECT|LVS_EX_LABELTIP);
- Shell_GetImageLists(&himlLarge, &himlSmall);
- ListView_SetImageList(_hwndView, himlLarge, LVSIL_NORMAL);
- ListView_SetImageList(_hwndView, himlSmall, LVSIL_SMALL);
- // Create the banner window, this is a child of the ListView, it is used to display
- // information about the query being issued
- _hwndBanner = CreateWindow(BANNER_CLASS, NULL,
- WS_CHILD,
- 0, 0, 0, 0, // nb: size fixed later
- _hwndView,
- (HMENU)IDC_STATUS,
- GLOBAL_HINSTANCE,
- NULL);
- if ( !_hwndBanner )
- ExitGracefully(hres, E_FAIL, "Failed to create the static banner window");
- _SetFilter(_fFilter);
- _SetViewMode(_idViewMode);
- _ShowBanner(SWP_SHOWWINDOW, IDS_INITALIZING);
- hres = S_OK; // success
- exit_gracefully:
- if ( SUCCEEDED(hres) )
- *phWndView = _hwnd;
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- #define MGW_EDIT 2
- STDMETHODIMP CDsQuery::ActivateView(THIS_ UINT uState, WPARAM wParam, LPARAM lParam)
- {
- HRESULT hres;
- HWND hwnd;
- INT i;
- TraceEnter(TRACE_HANDLER, "CDsQuery::ActivateView");
- switch ( uState )
- {
- case CQRVA_ACTIVATE:
- {
- HMENU hMenu;
- OLEMENUGROUPWIDTHS omgw = { 0, 0, 0, 0, 0, 0 };
- // Allow the cframe to merge its menus into our menu bar before we
- // add ours to it.
- if ( !(hMenu = CreateMenu()) )
- ExitGracefully(hres, E_FAIL, "Failed to create a base menu bar to be used");
- hres = _pqf->InsertMenus(hMenu, &omgw);
- FailGracefully(hres, "Failed when calling CQueryFrame::InsertMenus");
- Shell_MergeMenus(GetSubMenu(hMenu, 0), GetSubMenu(_hFileMenu, 0), 0x0, 0x0, 0x7fff, 0);
- MergeMenu(hMenu, _hEditMenu, omgw.width[0]);
- MergeMenu(hMenu, _hViewMenu, omgw.width[0]+1);
- MergeMenu(hMenu, _hHelpMenu, omgw.width[0]+MGW_EDIT+omgw.width[2]+omgw.width[4]);
- if ( _dwOQWFlags & OQWF_SINGLESELECT )
- {
- ENABLE_MENU_ITEM(hMenu, DSQH_EDIT_SELECTALL, FALSE);
- ENABLE_MENU_ITEM(hMenu, DSQH_EDIT_INVERTSELECTION, FALSE);
- }
- hres = _pqf->SetMenu(hMenu, NULL); // set the frames menu bar
- FailGracefully(hres, "Failed when calling CQueryFrame::SetMenu");
- break;
- }
- case CQRVA_INITMENUBAR:
- {
- // we recieve a CQRVA_INITMENUBAR before the popup so that we can store the
- // menu bar information, and invalidate an interface pointers we maybe holding
- // onto.
- Trace(TEXT("Received an CQRVA_INITMENUBAR, hMenu %08x"), wParam);
- _hFrameMenuBar = (HMENU)wParam;
- DoRelease(_pcm);
- break;
- }
- case CQRVA_INITMENUBARPOPUP:
- {
- HMENU hFileMenu;
- BOOL fDeleteItems = FALSE;
- TraceMsg("Received an CQRVA_INITMENUBARPOPUP");
- hFileMenu = GetSubMenu(_hFrameMenuBar, 0);
- // if we have a view then lets try and collect the selection from it,
- // having done that we can merge the verbs for that selection into the
- // views "File" menu.
- if ( (hFileMenu == (HMENU)wParam) && !_pcm )
- {
- _fNoSelection = TRUE; // no selection currenlty
- if ( IsWindow(_hwndView) )
- {
- for ( i = GetMenuItemCount(hFileMenu) - 1; i >= 0 ; i-- )
- {
- #if !DOWNLEVEL_SHELL
- if ( !fDeleteItems && (GetMenuItemID(hFileMenu, i) == DSQH_FILE_CREATESHORTCUT) )
- #else
- if ( !fDeleteItems && (GetMenuItemID(hFileMenu, i) == DSQH_FILE_PROPERTIES) )
- #endif
- {
- Trace(TEXT("Setting fDeleteItems true on index %d"), i);
- fDeleteItems = TRUE;
- }
- else
- {
- if ( fDeleteItems )
- DeleteMenu(hFileMenu, i, MF_BYPOSITION);
- }
- }
- // Collect the selection, and using that construct an IContextMenu interface, if that works
- // then we can merge in the verbs that relate to this object.
- hres = _GetIDLsAndViewObject(FALSE, IID_IContextMenu, (void **)&_pcm);
- FailGracefully(hres, "Failed when calling _GetIDLsAndViewObject");
- if ( ShortFromResult(hres) > 0 )
- {
- _GetContextMenuVerbs(_pcm, hFileMenu, CMF_VERBSONLY);
- _fNoSelection = FALSE;
- }
- }
- ENABLE_MENU_ITEM(hFileMenu, DSQH_FILE_CREATESHORTCUT, !_fNoSelection);
- ENABLE_MENU_ITEM(hFileMenu, DSQH_FILE_PROPERTIES, !_fNoSelection);
- }
- ENABLE_MENU_ITEM(_hFrameMenuBar, DSQH_VIEW_PICKCOLUMNS, _hdsaColumns);
- ENABLE_MENU_ITEM(_hFrameMenuBar, DSQH_VIEW_REFRESH, _dwThreadId);
- _InitViewMenuItems(_hFrameMenuBar);
- break;
- }
- case CQRVA_FORMCHANGED:
- {
- // we receieve a form change, we store the form name as we will use it
- // as the default name for saved queries authored by the user.
- Trace(TEXT("Form '%s' selected"), (LPTSTR)lParam);
- LocalFreeString(&_pDefaultSaveName);
- hres = LocalAllocString(&_pDefaultSaveName, (LPCTSTR)lParam);
- FailGracefully(hres, "Failed to set the default save name");
- break;
- }
- case CQRVA_STARTQUERY:
- {
- Trace(TEXT("Query is: %s"), wParam ? TEXT("starting"):TEXT("stopping"));
- break;
- }
- case CQRVA_HELP:
- {
- LPHELPINFO pHelpInfo = (LPHELPINFO)lParam;
- TraceAssert(pHelpInfo)
- TraceMsg("Invoking help on the objects in the windows");
- WinHelp((HWND)pHelpInfo->hItemHandle, DSQUERY_HELPFILE, HELP_WM_HELP, (DWORD_PTR)aHelpIDs);
- break;
- }
- case CQRVA_CONTEXTMENU:
- {
- HWND hwndForHelp = (HWND)wParam;
- Trace(TEXT("CQRVA_CONTEXTMENU recieved on the bg of the frame %d"), GetDlgCtrlID(hwndForHelp));
- WinHelp(hwndForHelp, DSQUERY_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)aHelpIDs);
- break;
- }
- }
- hres = S_OK;
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::InvokeCommand(THIS_ HWND hwndParent, UINT uID)
- {
- HRESULT hres;
- HWND hwndFrame;
- DECLAREWAITCURSOR;
- TraceEnter(TRACE_HANDLER, "CDsQuery::InvokeCommand");
- Trace(TEXT("hwndParent %08x, uID %d"), hwndParent, uID);
- SetWaitCursor();
- switch ( uID )
- {
- case DSQH_BG_SELECT:
- SendMessage(hwndParent, WM_COMMAND, IDOK, 0);
- break;
- case DSQH_FILE_PROPERTIES:
- hres = OnFileProperties();
- break;
- #if !DOWNLEVEL_SHELL
- case DSQH_FILE_CREATESHORTCUT:
- hres = OnFileCreateShortcut();
- break;
- #endif
- case DSQH_FILE_SAVEQUERY:
- hres = OnFileSaveQuery();
- break;
- case DSQH_EDIT_SELECTALL:
- hres = OnEditSelectAll();
- break;
- case DSQH_EDIT_INVERTSELECTION:
- hres = OnEditInvertSelection();
- break;
- case DSQH_VIEW_FILTER:
- _SetFilter(!_fFilter);
- break;
- case DSQH_VIEW_LARGEICONS:
- case DSQH_VIEW_SMALLICONS:
- case DSQH_VIEW_LIST:
- case DSQH_VIEW_DETAILS:
- _SetViewMode(uID);
- break;
- case DSQH_VIEW_REFRESH:
- {
- if ( IsWindow(_hwndView) && _dwThreadId )
- {
- _InitNewQuery(NULL, FALSE);
- PostThreadMessage(_dwThreadId, RVTM_REFRESH, _dwQueryReference, 0L);
- }
- break;
- }
- case DSQH_VIEW_PICKCOLUMNS:
- {
- TraceAssert(_hdsaColumns);
- OnPickColumns(hwndParent);
- break;
- }
- case DSQH_HELP_CONTENTS:
- {
- TraceMsg("Calling for to display help topics");
- _pqf->GetWindow(&hwndFrame);
- _pqf->CallForm(NULL, DSQPM_HELPTOPICS, 0, (LPARAM)hwndFrame);
- break;
- }
- case DSQH_HELP_WHATISTHIS:
- _pqf->GetWindow(&hwndFrame);
- SendMessage(hwndFrame, WM_SYSCOMMAND, SC_CONTEXTHELP, MAKELPARAM(0,0));
- break;
- default:
- {
- // if it looks like a sort request then lets handle it, otherwise attempt
- // to send to the context menu handler we may have at htis poiunt.
- if ( (uID >= DSQH_VIEW_ARRANGEFIRST) && (uID < DSQH_VIEW_ARRANGELAST) )
- {
- TraceAssert(_hdsaColumns);
- if ( _hdsaColumns )
- {
- Trace(TEXT("Calling _SortResults for column %d"), uID - DSQH_VIEW_ARRANGEFIRST);
- _SortResults(uID - DSQH_VIEW_ARRANGEFIRST);
- }
- }
- else if ( _pcm )
- {
- CMINVOKECOMMANDINFO ici;
- ici.cbSize = SIZEOF(ici);
- ici.fMask = 0;
- _pqf->GetWindow(&ici.hwnd);
- ici.lpVerb = (LPCSTR)(uID - DSQH_FILE_CONTEXT_FIRST);
- ici.lpParameters = NULL;
- ici.lpDirectory = NULL;
- ici.nShow = SW_NORMAL;
- ici.dwHotKey = 0;
- ici.hIcon = NULL;
- hres = _pcm->InvokeCommand(&ici);
- FailGracefully(hres, "Failed when calling IContextMenu::InvokeCommand");
- DoRelease(_pcm); // no longer needed
- }
- break;
- }
- }
- exit_gracefully:
- ResetWaitCursor();
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::GetCommandString(THIS_ UINT uID, DWORD dwFlags, LPTSTR pBuffer, INT cchBuffer)
- {
- HRESULT hres;
- TCHAR szBuffer[MAX_PATH];
- TraceEnter(TRACE_HANDLER, "CDsQuery::GetCommandString");
- Trace(TEXT("uID %08x, dwFlags %08x, pBuffer %08x, cchBuffer %d"), uID, dwFlags, pBuffer, cchBuffer);
- if ( (uID >= DSQH_FILE_CONTEXT_FIRST) && (uID < DSQH_FILE_CONTEXT_LAST) )
- {
- if ( _pcm )
- {
- TraceMsg("Trying the IContextMenu::GetCommandString");
- hres = _pcm->GetCommandString((uID - DSQH_FILE_CONTEXT_FIRST), GCS_HELPTEXT, NULL, (LPSTR)pBuffer, cchBuffer);
- #if UNICODE
- // we build UNICODE, therefore if we failed then try and pick up the ANSI string from
- // the handler, if that works then we convert the multi-byte string to UNICODE
- // and hand that back to the caller.
- if ( FAILED(hres) )
- {
- CHAR szBuffer[MAX_PATH];
- hres = _pcm->GetCommandString((uID - DSQH_FILE_CONTEXT_FIRST), GCS_HELPTEXTA, NULL, szBuffer, ARRAYSIZE(szBuffer));
- if ( SUCCEEDED(hres) )
- {
- TraceMsg("Handler provided an ANSI string");
- MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, pBuffer, cchBuffer);
- }
- }
- #endif
- FailGracefully(hres, "Failed when asking for help text from IContextMenu iface");
- }
- }
- else
- {
- if ( (uID >= DSQH_VIEW_ARRANGEFIRST) && (uID < DSQH_VIEW_ARRANGELAST) )
- {
- INT iColumn = uID-DSQH_VIEW_ARRANGEFIRST;
- TCHAR szFmt[MAX_PATH];
- Trace(TEXT("Get command text for column %d"), iColumn);
- if ( _hdsaColumns && (iColumn < DSA_GetItemCount(_hdsaColumns)) )
- {
- LPCOLUMN pColumn = (LPCOLUMN)DSA_GetItemPtr(_hdsaColumns, iColumn);
- TraceAssert(pColumn);
- LoadString(GLOBAL_HINSTANCE, IDS_ARRANGEBY_HELP, szFmt, ARRAYSIZE(szFmt));
- wsprintf(pBuffer, szFmt, pColumn->pHeading);
- Trace(TEXT("Resulting string is: %s"), pBuffer);
- }
- }
- else
- {
- if ( !LoadString(GLOBAL_HINSTANCE, uID, pBuffer, cchBuffer) )
- ExitGracefully(hres, E_FAIL, "Failed to load the command text for this verb");
- }
- }
- hres = S_OK;
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::IssueQuery(THIS_ LPCQPARAMS pQueryParams)
- {
- HRESULT hres;
- LPTHREADINITDATA ptid = NULL;
- LPDSQUERYSCOPE pDsQueryScope = (LPDSQUERYSCOPE)pQueryParams->pQueryScope;
- LPDSQUERYPARAMS pDsQueryParams = (LPDSQUERYPARAMS)pQueryParams->pQueryParameters;
- LPTSTR pBuffer = NULL;
- MSG msg;
- TraceEnter(TRACE_HANDLER, "CDsQuery::IssueQuery");
- Trace(TEXT("pQueryParams %08x, pDsQueryScope %08x, pDsQueryParams %08x"), pQueryParams, pDsQueryScope, pDsQueryParams);
- // Persist the existing column information if there was some, then
- // get the new column table initialized and the columns added to the
- // view
- if ( _hdsaColumns )
- {
- if ( _fColumnsModified )
- {
- _SaveColumnTable(_clsidForm, _hdsaColumns);
- _fColumnsModified = FALSE;
- }
- _SaveColumnTable();
- }
- // Initialize the view with items
- _clsidForm = pQueryParams->clsidForm; // keep the form ID (for persistance)
- hres = _InitNewQuery(pDsQueryParams, TRUE);
- FailGracefully(hres, "Failed to initialize the new query");
- // Now build the thread information needed to get the thread
- // up and running.
- ptid = (LPTHREADINITDATA)LocalAlloc(LPTR, SIZEOF(THREADINITDATA));
- TraceAssert(ptid);
- if ( !ptid )
- ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate THREADINITDATA");
- ptid->dwReference = _dwQueryReference;
- //ptid->hwndView = NULL;
- //ptid->pQuery = NULL;
- //ptid->pScope = NULL;
- //ptid->hdsaColumns = NULL;
- //ptid->fShowHidden = FALSE;
- //ptid->pServer = NULL;
- //ptid->pUserName = NULL;
- //ptid->pPassword = NULL;
- Trace(TEXT("_dwFlags %08x (& DSQPF_SHOWHIDDENOBJECTS)"), _dwFlags, _dwFlags & DSQPF_SHOWHIDDENOBJECTS);
- ptid->fShowHidden = (_dwFlags & DSQPF_SHOWHIDDENOBJECTS) ? 1:0;
- ptid->hwndView = _hwndView;
- hres = _GetColumnTable(_clsidForm, pDsQueryParams, &ptid->hdsaColumns, FALSE);
- FailGracefully(hres, "Failed to create column DSA");
- hres = LocalAllocStringW(&ptid->pQuery, (LPWSTR)ByteOffset(pDsQueryParams, pDsQueryParams->offsetQuery));
- FailGracefully(hres, "Failed to copy query filter string");
- hres = LocalAllocStringW(&ptid->pScope, OBJECT_NAME_FROM_SCOPE(pDsQueryScope));
- FailGracefully(hres, "Failed to copy scope to thread init data");
- hres = _CopyCredentials(&ptid->pUserName, &ptid->pPassword, &ptid->pServer);
- FailGracefully(hres, "Failed to copy credentails");
- // now create the thread that is going to perform the query, this includes
- // telling the previous one that it needs to close down
- if ( _hThread && _dwThreadId )
- {
- Trace(TEXT("Killing old query thread %08x, ID %d"), _hThread, _dwThreadId);
- PostThreadMessage(_dwThreadId, RVTM_STOPQUERY, 0, 0);
- PostThreadMessage(_dwThreadId, WM_QUIT, 0, 0);
- CloseHandle(_hThread);
- _hThread = NULL;
- _dwThreadId = 0;
- }
- InterlockedIncrement(&GLOBAL_REFCOUNT);
- _hThread = CreateThread(NULL, 0, QueryThread, ptid, 0, &_dwThreadId);
- TraceAssert(_hThread);
- if ( !_hThread )
- {
- InterlockedDecrement(&GLOBAL_REFCOUNT);
- ExitGracefully(hres, E_FAIL, "Failed to create background thread - BAD!");
- }
- hres = S_OK; // success
- exit_gracefully:
- if ( SUCCEEDED(hres) && IsWindow(_hwndView) )
- SetFocus(_hwndView);
- if ( FAILED(hres) )
- {
- QueryThread_FreeThreadInitData(&ptid);
- _pqf->StartQuery(FALSE);
- }
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::StopQuery(THIS)
- {
- HRESULT hres;
- INT cResults = _hdpaResults ? DPA_GetPtrCount(_hdpaResults):0;
- LPTSTR pBuffer;
- TraceEnter(TRACE_HANDLER, "CDsQuery::StopQuery");
- if ( !IsWindow(_hwndView) )
- ExitGracefully(hres, E_FAIL, "View not initalized yet");
- // we are stopping the query, we are going to tidy up the UI now
- // and we just want the thread to closedown cleanly, therefore lets
- // do so, increasing our query reference
- _pqf->StartQuery(FALSE);
- _dwQueryReference++;
- _PopulateView(-1, -1); // update status bar etc
- if ( _dwThreadId )
- PostThreadMessage(_dwThreadId, RVTM_STOPQUERY, 0, 0);
- hres = S_OK; // success
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- HRESULT _SetDataObjectData(IDataObject* pDataObject, UINT cf, LPVOID pData, DWORD cbSize)
- {
- HRESULT hres;
- FORMATETC fmte = {(CLIPFORMAT)cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- STGMEDIUM medium = { TYMED_NULL, NULL, NULL };
- LPVOID pAlloc;
- TraceEnter(TRACE_HANDLER, "_SetDataObjectData");
- hres = AllocStorageMedium(&fmte, &medium, cbSize, &pAlloc);
- FailGracefully(hres, "Failed to allocate STGMEDIUM for data");
- CopyMemory(pAlloc, pData, cbSize);
- hres = pDataObject->SetData(&fmte, &medium, TRUE);
- FailGracefully(hres, "Failed to pass the data to the IDataObject");
- hres = S_OK;
- exit_gracefully:
- ReleaseStgMedium(&medium);
- TraceLeaveResult(hres);
- }
- STDMETHODIMP CDsQuery::GetViewObject(THIS_ UINT uScope, REFIID riid, void **ppvOut)
- {
- HRESULT hres;
- IDataObject* pDataObject = NULL;
- LPDSQUERYPARAMS pDsQueryParams = NULL;
- LPDSQUERYSCOPE pDsQueryScope = NULL;
- UINT cfDsQueryParams = RegisterClipboardFormat(CFSTR_DSQUERYPARAMS);
- UINT cfDsQueryScope = RegisterClipboardFormat(CFSTR_DSQUERYSCOPE);
- BOOL fJustSelection = !(_dwFlags & DSQPF_RETURNALLRESULTS);
- TraceEnter(TRACE_HANDLER, "CDsQuery::GetViewObject");
- // We only support returning the selection as an IDataObject
- DECLAREWAITCURSOR;
- SetWaitCursor();
- if ( !ppvOut && ((uScope & CQRVS_MASK) != CQRVS_SELECTION) )
- ExitGracefully(hres, E_INVALIDARG, "Bad arguments to GetViewObject");
- if ( !IsEqualIID(riid, IID_IDataObject) )
- ExitGracefully(hres, E_NOINTERFACE, "Object IID supported");
- //
- // write the extra data we have into the IDataObject:
- //
- // - query parameters (filter)
- // - scope
- // - attribute prefix information
- //
- hres = _GetIDLsAndViewObject(fJustSelection, IID_IDataObject, (void **)&pDataObject);
- FailGracefully(hres, "Failed to get the IDataObject from the namespace");
- if ( SUCCEEDED(_pqf->CallForm(NULL, CQPM_GETPARAMETERS, 0, (LPARAM)&pDsQueryParams)) )
- {
- if ( pDsQueryParams )
- {
- hres = _SetDataObjectData(pDataObject, cfDsQueryParams, pDsQueryParams, pDsQueryParams->cbStruct);
- FailGracefully(hres, "Failed set the DSQUERYPARAMS into the data object");
- }
- }
- if ( SUCCEEDED(_pqf->GetScope((LPCQSCOPE*)&pDsQueryScope)) )
- {
- if ( pDsQueryScope )
- {
- LPWSTR pScope = OBJECT_NAME_FROM_SCOPE(pDsQueryScope);
- TraceAssert(pScope);
- hres = _SetDataObjectData(pDataObject, cfDsQueryScope, pScope, StringByteSizeW(pScope));
- FailGracefully(hres, "Failed set the DSQUERYSCOPE into the data object");
- }
- }
- // success, so lets pass out the IDataObject.
- pDataObject->AddRef();
- *ppvOut = (LPVOID)pDataObject;
- hres = S_OK;
- exit_gracefully:
- DoRelease(pDataObject);
- if ( pDsQueryParams )
- CoTaskMemFree(pDsQueryParams);
- if ( pDsQueryScope )
- CoTaskMemFree(pDsQueryScope);
- ResetWaitCursor();
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::LoadQuery(THIS_ IPersistQuery* pPersistQuery)
- {
- HRESULT hres;
- WCHAR szBuffer[MAX_PATH];
- IADs *pDsObject = NULL;
- BSTR bstrObjectClass = NULL;
- INT iFilter;
- LPCQSCOPE pScope = NULL;
- INT cbScope;
- USES_CONVERSION;
- TraceEnter(TRACE_HANDLER, "CDsQuery::LoadQuery");
- if ( !pPersistQuery )
- ExitGracefully(hres, E_INVALIDARG, "No IPersistQuery object");
- if ( SUCCEEDED(pPersistQuery->ReadInt(c_szDsQuery, c_szScopeSize, &cbScope)) &&
- (cbScope < SIZEOF(szBuffer)) &&
- SUCCEEDED(pPersistQuery->ReadStruct(c_szDsQuery, c_szScope, szBuffer, cbScope)) )
- {
- Trace(TEXT("Selected scope from file is %s"), W2T(szBuffer));
- // get the object class from the file - this should be written to the file
- hres = ADsOpenObject(szBuffer, _pUserName, _pPassword, ADS_SECURE_AUTHENTICATION, IID_IADs, (void **)&pDsObject);
- FailGracefully(hres, "Failed to bind to the specified object");
- hres = pDsObject->get_Class(&bstrObjectClass);
- FailGracefully(hres, "Failed to get the object class");
- // allocate a new scope
- if ( SUCCEEDED(AllocScope(&pScope, 0, szBuffer, bstrObjectClass)) )
- {
- hres = _pqf->AddScope(pScope, 0x0, TRUE);
- FailGracefully(hres, "Failed to add scope to list");
- }
- }
- // Read the remainder of the view state
- if ( SUCCEEDED(pPersistQuery->ReadInt(c_szDsQuery, c_szViewMode, &_idViewMode)) )
- {
- Trace(TEXT("View mode is: %0x8"), _idViewMode);
- _SetViewMode(_idViewMode);
- }
- if ( SUCCEEDED(pPersistQuery->ReadInt(c_szDsQuery, c_szEnableFilter, &iFilter)) )
- {
- Trace(TEXT("Filter mode set to %d"), _fFilter);
- _SetFilter(iFilter);
- }
- hres = S_OK;
- exit_gracefully:
- if ( pScope )
- CoTaskMemFree(pScope);
- DoRelease(pDsObject);
- SysFreeString(bstrObjectClass);
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::SaveQuery(THIS_ IPersistQuery* pPersistQuery, LPCQSCOPE pScope)
- {
- HRESULT hres;
- LPDSQUERYSCOPE pDsQueryScope = (LPDSQUERYSCOPE)pScope;
- LPWSTR pScopePath = OBJECT_NAME_FROM_SCOPE(pDsQueryScope);
- WCHAR szGcPath[MAX_PATH];
- TraceEnter(TRACE_HANDLER, "CDsQuery::SaveQuery");
- if ( !pPersistQuery || !pScope )
- ExitGracefully(hres, E_INVALIDARG, "No IPersistQuery/pScope object");
- if ( SUCCEEDED(GetGlobalCatalogPath(_pServer, szGcPath, ARRAYSIZE(szGcPath))) && StrCmpW(pScopePath, szGcPath) )
- {
- // if this is not the GC then persist
- TraceMsg("GC path differs from scope, so persisting");
- hres = pPersistQuery->WriteInt(c_szDsQuery, c_szScopeSize, StringByteSizeW(pScopePath));
- FailGracefully(hres, "Failed to write the scope size");
- hres = pPersistQuery->WriteStruct(c_szDsQuery, c_szScope, pScopePath, StringByteSizeW(pScopePath));
- FailGracefully(hres, "Failed to write scope");
- }
- hres = pPersistQuery->WriteInt(c_szDsQuery, c_szViewMode, _idViewMode);
- FailGracefully(hres, "Failed to write view mode");
- hres = pPersistQuery->WriteInt(c_szDsQuery, c_szEnableFilter, _fFilter);
- FailGracefully(hres, "Failed to write filter state");
- hres = S_OK;
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*----------------------------------------------------------------------------
- / IObjectWithSite
- /----------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::SetSite(IUnknown* punk)
- {
- HRESULT hres = S_OK;
- TraceEnter(TRACE_HANDLER, "CDsQuery::SetSite");
- DoRelease(_punkSite);
- if ( punk )
- {
- TraceMsg("QIing for IUnknown from the site object");
- hres = punk->QueryInterface(IID_IUnknown, (void **)&_punkSite);
- FailGracefully(hres, "Failed to get IUnknown from the site object");
- }
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*---------------------------------------------------------------------------*/
- STDMETHODIMP CDsQuery::GetSite(REFIID riid, void **ppv)
- {
- HRESULT hres;
- TraceEnter(TRACE_HANDLER, "CDsQuery::GetSite");
- if ( !_punkSite )
- ExitGracefully(hres, E_NOINTERFACE, "No site to QI from");
- hres = _punkSite->QueryInterface(riid, ppv);
- FailGracefully(hres, "QI failed on the site unknown object");
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*----------------------------------------------------------------------------
- / IDsQueryHandler
- /----------------------------------------------------------------------------*/
- VOID CDsQuery::_DeleteViewItems(LPDSOBJECTNAMES pdon)
- {
- INT iResult;
- DWORD iItem;
- USES_CONVERSION;
- TraceEnter(TRACE_HANDLER, "CDsQuery::_DeleteObjectNames");
- if ( pdon->cItems )
- {
- // walk through all the items in the view deleting as required.
- for ( iItem = 0 ; iItem != pdon->cItems ; iItem++ )
- {
- // do we have an item to delete?
- if ( pdon->aObjects[iItem].offsetName )
- {
- LPCWSTR pwszName = (LPCWSTR)ByteOffset(pdon, pdon->aObjects[iItem].offsetName);
- Trace(TEXT("pwszName to delete: %s"), W2CT(pwszName));
- // walk all the results in the view deleting them as we go.
- for ( iResult = 0 ; iResult < DPA_GetPtrCount(_hdpaResults); iResult++ )
- {
- LPQUERYRESULT pResult = (LPQUERYRESULT)DPA_GetPtr(_hdpaResults, iResult);
- TraceAssert(pResult);
- // if we match the item we want to delete then remove it, if the view
- // is not filtered then remove ite from the list, otherwise leave the
- // view update until we have finished deleting
- if ( !StrCmpW(pwszName, pResult->pPath) )
- {
- Trace(TEXT("Item maps to result %d in the list"), iResult);
- FreeQueryResult(pResult, DSA_GetItemCount(_hdsaColumns));
- DPA_DeletePtr(_hdpaResults, iResult);
- if ( !_fFilter )
- {
- TraceMsg("Deleting the item from the view");
- ListView_DeleteItem(_hwndView, iResult);
- }
- }
- }
- }
- }
- // the view was filtered, so lets repopulate with the items
- if ( _fFilter )
- {
- TraceMsg("View is filter, therefore just forcing a refresh");
- _FilterView(FALSE);
- }
- }
- TraceLeave();
- }
- STDMETHODIMP CDsQuery::UpdateView(DWORD dwType, LPDSOBJECTNAMES pdon)
- {
- HRESULT hres;
- TraceEnter(TRACE_HANDLER, "CDsQuery::UpdateView");
- switch ( dwType & DSQRVF_OPMASK )
- {
- case DSQRVF_ITEMSDELETED:
- {
- if ( !pdon )
- ExitGracefully(hres, E_INVALIDARG, "Invlaidate pdon specified for refresh");
- _DeleteViewItems(pdon);
- break;
- }
- default:
- ExitGracefully(hres, E_INVALIDARG, "Invalidate refresh type speciifed");
- }
- hres = S_OK;
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*-----------------------------------------------------------------------------
- / Message/Command Handlers
- /----------------------------------------------------------------------------*/
- /*-----------------------------------------------------------------------------
- / CDsQuery::OnSize
- / ----------------
- / Result viewer is being sized, so ensure that our children have their
- / sizes correctly addjusted.
- /
- / In:
- / cx, cy = new size of the parent window
- /
- / Out:
- / -
- /----------------------------------------------------------------------------*/
- LRESULT CDsQuery::OnSize(INT cx, INT cy)
- {
- TraceEnter(TRACE_VIEW, "CDsQuery::OnSize");
- SetWindowPos(_hwndView, NULL, 0, 0, cx, cy, SWP_NOZORDER|SWP_NOMOVE);
- _ShowBanner(0, 0);
- TraceLeaveValue(0);
- }
- /*-----------------------------------------------------------------------------
- / CDsQuery::OnNotify
- / ------------------
- / Notify message being recieved by the view, so try and handle it as best
- / we can.
- /
- / In:
- / hWnd = window handle of the notify
- / wParam, lParam = parameters for the notify event
- /
- / Out:
- / LRESULT
- /----------------------------------------------------------------------------*/
- LRESULT CDsQuery::OnNotify(HWND hWnd, WPARAM wParam, LPARAM lParam)
- {
- HRESULT hres;
- LRESULT lr = 0;
- DECLAREWAITCURSOR = GetCursor();
- USES_CONVERSION;
- TraceEnter(TRACE_VIEW, "CDsQuery::OnNotify");
- switch ( ((LPNMHDR)lParam)->code )
- {
- case HDN_FILTERCHANGE:
- _FilterView(TRUE);
- break;
- case HDN_FILTERBTNCLICK:
- {
- NMHDFILTERBTNCLICK* pNotify = (NMHDFILTERBTNCLICK*)lParam;
- HMENU hMenu;
- POINT pt;
- HD_ITEM hdi;
- UINT uID;
- if ( _hdsaColumns && (pNotify->iItem < DSA_GetItemCount(_hdsaColumns)) )
- {
- LPCOLUMN pColumn = (LPCOLUMN)DSA_GetItemPtr(_hdsaColumns, pNotify->iItem);
- TraceAssert(pColumn);
- hMenu = LoadMenu(GLOBAL_HINSTANCE, property_type_table[pColumn->iPropertyType].pMenuName);
- TraceAssert(hMenu);
- if ( hMenu )
- {
- pt.x = pNotify->rc.right;
- pt.y = pNotify->rc.bottom;
- MapWindowPoints(pNotify->hdr.hwndFrom, NULL, &pt, 1);
- CheckMenuRadioItem(GetSubMenu(hMenu, 0),
- FILTER_FIRST, FILTER_LAST, pColumn->idOperator,
- MF_BYCOMMAND);
- uID = TrackPopupMenu(GetSubMenu(hMenu, 0),
- TPM_RIGHTALIGN|TPM_RETURNCMD,
- pt.x, pt.y,
- 0, pNotify->hdr.hwndFrom, NULL);
- switch ( uID )
- {
- case DSQH_CLEARFILTER:
- Header_ClearFilter(ListView_GetHeader(_hwndView), pNotify->iItem);
- break;
- case DSQH_CLEARALLFILTERS:
- Header_ClearAllFilters(ListView_GetHeader(_hwndView));
- break;
- default:
- {
- if ( uID && (uID != pColumn->idOperator) )
- {
- // update the filter string based on the new operator
- pColumn->idOperator = uID;
- _GetFilterValue(pNotify->iItem, NULL);
- lr = TRUE;
- }
- break;
- }
- }
- DestroyMenu(hMenu);
- }
- }
- break;
- }
- case HDN_ITEMCHANGED:
- {
- HD_NOTIFY* pNotify = (HD_NOTIFY*)lParam;
- HD_ITEM* pitem = (HD_ITEM*)pNotify->pitem;
- if ( _hdsaColumns && (pNotify->iItem < DSA_GetItemCount(_hdsaColumns)) )
- {
- LPCOLUMN pColumn = (LPCOLUMN)DSA_GetItemPtr(_hdsaColumns, pNotify->iItem);
- TraceAssert(pColumn);
- // store the new column width information in the column structure and
- // mark the column table as dirty
- if ( pitem->mask & HDI_WIDTH )
- {
- Trace(TEXT("Column %d, cx %d (marking state as dirty)"), pNotify->iItem, pitem->cxy);
- pColumn->cx = pitem->cxy;
- _fColumnsModified = TRUE;
- }
- if ( pitem->mask & HDI_FILTER )
- {
- Trace(TEXT("Filter for column %d has been changed"), pNotify->iItem);
- _GetFilterValue(pNotify->iItem, pitem);
- }
- }
- break;
- }
- case LVN_GETDISPINFO:
- {
- LV_DISPINFO* pNotify = (LV_DISPINFO*)lParam;
- TraceAssert(pNotify);
- if ( pNotify && (pNotify->item.mask & LVIF_TEXT) && pNotify->item.lParam )
- {
- LPQUERYRESULT pResult = (LPQUERYRESULT)pNotify->item.lParam;
- INT iColumn = pNotify->item.iSubItem;
- pNotify->item.pszText[0] = TEXT(''); // nothing to display yet
- switch ( pResult->aColumn[iColumn].iPropertyType )
- {
- case PROPERTY_ISUNDEFINED:
- break;
- case PROPERTY_ISUNKNOWN:
- case PROPERTY_ISSTRING:
- {
- if ( pResult->aColumn[iColumn].pszText )
- StrCpyN(pNotify->item.pszText, pResult->aColumn[iColumn].pszText, pNotify->item.cchTextMax);
- break;
- }
- case PROPERTY_ISNUMBER:
- case PROPERTY_ISBOOL:
- wsprintf(pNotify->item.pszText, TEXT("%d"), pResult->aColumn[iColumn].iValue);
- break;
- }
- lr = TRUE; // we formatted a value
- }
- break;
- }
- case LVN_ITEMACTIVATE:
- {
- LPNMHDR pNotify = (LPNMHDR)lParam;
- DWORD dwFlags = CMF_NORMAL;
- HWND hwndFrame;
- HMENU hMenu;
- UINT uID;
- // convert the current selection to IDLITs and an IContextMenu interface
- // that we can then get the default verb from.
- SetWaitCursor();
- DoRelease(_pcm);
- hres = _GetIDLsAndViewObject(FALSE, IID_IContextMenu, (void **)&_pcm);
- FailGracefully(hres, "Failed when calling _GetIDLsAndViewObject");
- _fNoSelection = !ShortFromResult(hres);
- if ( !_fNoSelection )
- {
- // create a popup menu pickup the context menu for the current selection
- // and then pass it down to the invoke command handler.
- hMenu = CreatePopupMenu();
- TraceAssert(hMenu);
- if ( hMenu )
- {
- if ( GetKeyState(VK_SHIFT) < 0 )
- dwFlags |= CMF_EXPLORE; // SHIFT + dblclick does a Explore by default
- _GetContextMenuVerbs(_pcm, hMenu, dwFlags);
- uID = GetMenuDefaultItem(hMenu, MF_BYCOMMAND, 0);
- Trace(TEXT("Default uID after double click %08x"), uID);
- if ( uID != -1 )
- {
- _pqf->GetWindow(&hwndFrame);
- InvokeCommand(hwndFrame, uID);
- }
- DoRelease(_pcm); // no longer needed
- DestroyMenu(hMenu);
- }
- }
- break;
- }
- case LVN_COLUMNCLICK:
- {
- NM_LISTVIEW* pNotify = (NM_LISTVIEW*)lParam;
- TraceAssert(pNotify);
- _SortResults(pNotify->iSubItem);
- break;
- }
- default:
- lr = DefWindowProc(hWnd, WM_NOTIFY, wParam, lParam);
- break;
- }
- exit_gracefully:
- ResetWaitCursor();
- TraceLeaveValue(lr);
- }
- /*-----------------------------------------------------------------------------
- / CDsQuery::OnAddResults
- / ----------------------
- / The background thread has sent us some results, so lets add them to
- / the DPA of results, discarding the ones we don't add because we cannot
- / grow the DPA.
- /
- / dwQueryReference conatins the reference ID for this query, only add
- / results where these match.
- /
- / In:
- / dwQueryReference = reference that this block is for
- / hdpaResults = DPA containing the results to add
- /
- / Out:
- / HRESULT
- /----------------------------------------------------------------------------*/
- HRESULT CDsQuery::OnAddResults(DWORD dwQueryReference, HDPA hdpaResults)
- {
- HRESULT hres;
- INT i, iPopulateFrom;
- TraceEnter(TRACE_VIEW, "CDsQuery::OnAddResults");
- if ( (dwQueryReference != _dwQueryReference) || !hdpaResults )
- ExitGracefully(hres, E_FAIL, "Failed to add results, bad DPA/reference ID");
- // the caller gives us a DPA then we add them to our result DPA, we then
- // update the view populating from the first item we added.
- iPopulateFrom = DPA_GetPtrCount(_hdpaResults);
- for ( i = DPA_GetPtrCount(hdpaResults); --i >= 0 ; )
- {
- LPQUERYRESULT pResult = (LPQUERYRESULT)DPA_GetPtr(hdpaResults, i);
- TraceAssert(pResult);
- // add the result to the main DPA, if that fails then ensure we nuke
- // this result blob!
- if ( -1 == DPA_AppendPtr(_hdpaResults, pResult) )
- FreeQueryResult(pResult, DSA_GetItemCount(_hdsaColumns));
- DPA_DeletePtr(hdpaResults, i); // remove from result DPA
- }
- _PopulateView(iPopulateFrom, DPA_GetPtrCount(_hdpaResults));
- TraceAssert(DPA_GetPtrCount(hdpaResults) == 0);
- DPA_Destroy(hdpaResults);
- hres = S_OK;
- exit_gracefully:
- TraceLeaveResult(hres);
- }
- /*-----------------------------------------------------------------------------
- / CDsQuery::OnContextMenu
- / -----------------------
- / The user has right clicked in the result view, therefore we must attempt
- / to display the context menu for those objects
- /
- / In:
- / hwndMenu = window that that the user menued over
- / pt = point to show the context menu
- /
- / Out:
- / -
- /----------------------------------------------------------------------------*/
- LRESULT CDsQuery::OnContextMenu(HWND hwndMenu, LPARAM lParam)
- {
- HRESULT hres;
- HMENU hMenu = NULL;
- POINT pt = { 0, 0 };
- INT i;
- RECT rc;
- HWND hwndFrame;
- TraceEnter(TRACE_VIEW, "CDsQuery::OnContextMenu");
- // Collect the selection, obtaining a IContextMenu interface pointer, or a HR == S_FALSE
- // if there is no selection for us to be using.
- DoRelease(_pcm);
- hres = _GetIDLsAndViewObject(FALSE, IID_IContextMenu, (void **)&_pcm);
- FailGracefully(hres, "Failed when calling _GetIDLsAndViewObject");
- _fNoSelection = !ShortFromResult(hres);
- if ( !(hMenu = CreatePopupMenu()) )
- ExitGracefully(hres, E_FAIL, "Failed to create the popup menu");
- if ( !_fNoSelection )
- {
- // pick up the context menu that maps tot he current selection, including fixing
- // the "select" verb if we need one.
- _GetContextMenuVerbs(_pcm, hMenu, CMF_NORMAL);
- }
- else
- {
- // There is no selection so lets pick up the view bg menu, this contains
- // some useful helpers for modifying the view state.
- HMENU hBgMenu = LoadMenu(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDR_VIEWBACKGROUND));
- if ( !hBgMenu )
- ExitGracefully(hres, E_FAIL, "Failed to load pop-up menu for the background");
- Shell_MergeMenus(hMenu, GetSubMenu(hBgMenu, 0), 0, 0, CQID_MAXHANDLERMENUID, 0x0);
- DestroyMenu(hBgMenu);
- _InitViewMenuItems(hMenu);
- }
- // if lParam == -1 then we know that the user hit the "context menu" key
- // so lets set the co-ordinates of the item.
- if ( lParam == (DWORD)-1 )
- {
- i = ListView_GetNextItem(_hwndView, -1, LVNI_FOCUSED|LVNI_SELECTED);
- Trace(TEXT("Item with focus + selection: %d"), i);
- if ( i == -1 )
- {
- i = ListView_GetNextItem(_hwndView, -1, LVNI_SELECTED);
- Trace(TEXT("1st selected item: %D"), i);
- }
- if ( i != -1 )
- {
- TraceMsg("We have an item, so getting bounds of the icon for position");
- ListView_GetItemRect(_hwndView, i, &rc, LVIR_ICON);
- pt.x = (rc.left+rc.right)/2;
- pt.y = (rc.top+rc.bottom)/2;
- }
- MapWindowPoints(_hwndView, HWND_DESKTOP, &pt, 1); // they are in client co-ordinates
- }
- else
- {
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- }
- // we have the position so lets use it
- _pqf->GetWindow(&hwndFrame);
- TrackPopupMenu(hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hwndFrame, NULL);
- exit_gracefully:
- if ( hMenu )
- DestroyMenu(hMenu);
- TraceLeaveValue(0);
- }
- /*-----------------------------------------------------------------------------
- / CDsQuery::OnFileProperties
- / --------------------------
- / Show properties for the given selection. To do this we CoCreate
- / IDsFolderProperties on the IDsFolder implementation and that
- / we can invoke properties using.
- /
- / In:
- / Out:
- / HRESULT
- /----------------------------------------------------------------------------*/
- HRESULT CDsQuery::OnFileProperties(VOID)
- {
- HRESULT hres;
- IDataObject* pDataObject = NULL;
- IDsFolderProperties* pDsFolderProperties = NULL;
- TraceEnter(TRACE_VIEW, "CDsQuery::OnFileProperties");
- hres = GetViewObject(CQRVS_SELECTION, IID_IDataObject, (void **)&pDataObject);
- FailGracefully(hres, "Failed to get IDataObject for shortcut creation");
- hres = CoCreateInstance(CLSID_DsFolderProperties, NULL, CLSCTX_INPROC_SERVER, IID_IDsFolderProperties, (void **)&pDsFolderProperties);
- FailGracefully(hres, "Failed to get IDsFolderProperties for the desktop object");
- hres = pDsFolderProperties->ShowProperties(_hwnd, pDataObject);
- FailGracefully(hres, "Failed to invoke property UI for the given selection");
- // hres = S_OK; // success
- exit_gracefully:
- DoRelease(pDataObject);
- DoRelease(pDsFolderProperties);
- TraceLeaveResult(hres);
- }
- /*-----------------------------------------------------------------------------
- / CDsQuery::OnFileCreateShortcut
- / ------------------------------
- / Get the selection as a IDataObject then call the shell for it to
- / create shortucts to the objects. These shortcuts are placed onto
- / the desktop.
- /
- / In:
- / Out:
- / HRESULT
- /----------------------------------------------------------------------------*/
- #if !DOWNLEVEL_SHELL
- HRESULT CDsQuery::OnFileCreateShortcut(VOID)
- {
- HRESULT hres;
- IDataObject* pDataObject = NULL;
- TraceEnter(TRACE_VIEW, "CDsQuery::OnFileCreateShortcut");
- hres = GetViewObject(CQRVS_SELECTION, IID_IDataObject, (void **)&pDataObject);
- FailGracefully(hres, "Failed to get IDataObject for shortcut creation");
- hres = SHCreateLinks(_hwnd, NULL, pDataObject, SHCL_USETEMPLATE | SHCL_USEDESKTOP | SHCL_CONFIRM, NULL);
- FailGracefully(hres, "Failed when calling SHCreateLinks");
- // hres = S_OK; // success
- exit_gracefully:
- DoRelease(pDataObject);
- TraceLeaveResult(hres);
- }
- #endif
- /*-----------------------------------------------------------------------------
- / CDsQuery::OnFileSaveQuery
- / -------------------------
- / Allow the user to choose a location to save the query (initial directory
- / is nethood). Having done that we then start the save process by passing
- / the frame object a IQueryIO object that allows them to persist the
- / query into.
- /
- / In:
- / Out:
- / HRESULT
- /----------------------------------------------------------------------------*/
- HRESULT CDsQuery::OnFileSaveQuery(VOID)
- {
- HRESULT hres;
- OPENFILENAME ofn;
- TCHAR szFilename[MAX_PATH];
- TCHAR szDirectory[MAX_PATH];
- TCHAR szFilter[64];
- TCHAR szTitle[64];
- LPTSTR pFilter;
- CDsPersistQuery* pPersistQuery = NULL;
- USES_CONVERSION;
- TraceEnter(TRACE_VIEW, "CDsQuery::OnFileSaveQuery");
- // Load the default strings and fix up the filter string as it needs
- // NULL's seperating the various resource sections.
- LoadString(GLOBAL_HINSTANCE, IDS_SAVETITLE, szTitle, ARRAYSIZE(szTitle));
- StrCpy(szFilename, _pDefaultSaveName);
- LoadString(GLOBAL_HINSTANCE, IDS_SAVEFILTER, szFilter, ARRAYSIZE(szFilter));
- for ( pFilter = szFilter ; *pFilter ; pFilter++ )
- {
- if ( *pFilter == TEXT('n') )
- *pFilter = TEXT('');
- }
- // fix the open filename structure ready to do our save....
- ZeroMemory(&ofn, SIZEOF(ofn));
- ofn.lStructSize = SIZEOF(ofn);
- _pqf->GetWindow(&ofn.hwndOwner);
- ofn.hInstance = GLOBAL_HINSTANCE;
- ofn.lpstrFilter = szFilter;
- ofn.lpstrFile = szFilename;
- ofn.nMaxFile = ARRAYSIZE(szFilename);
- if ( _pDefaultSaveLocation )
- {
- Trace(TEXT("Saving into: %s"), W2T(_pDefaultSaveLocation));
- StrCpy(szDirectory, W2T(_pDefaultSaveLocation));
- ofn.lpstrInitialDir = szDirectory;
- }
- ofn.lpstrTitle = szTitle;
- ofn.Flags = OFN_EXPLORER|OFN_NOCHANGEDIR|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;
- ofn.lpstrDefExt = TEXT("dsq");
- // If we get a save filename then lets ensure that we delete the previous
- // query saved there (if there is one) and then we can create an IPersistQuery
- // object that will save to that location.
- if ( GetSaveFileName(&ofn) )
- {
- Trace(TEXT("Saving query as: %s"), szFilename);
- if ( !DeleteFile(szFilename) && (GetLastError() != ERROR_FILE_NOT_FOUND) )
- ExitGracefully(hres, E_FAIL, "Failed to delete previous query");
- pPersistQuery = new CDsPersistQuery(szFilename);
- if ( !pPersistQuery )
- ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate CDsPersistQuery");
- hres = _pqf->SaveQuery(pPersistQuery);
- FailGracefully(hres, "Failed when calling IQueryFrame::SaveSearch");
- }
- hres = S_OK;
- exit_gracefully:
- DoRelease(pPersistQuery);