|
|
#include "pch.h"
#include "uxtheme.h"
#pragma hdrstop
/*-----------------------------------------------------------------------------
/ Private data and helper functions /----------------------------------------------------------------------------*/
//
// ICommonQuery stuff
//
class CCommonQuery : public ICommonQuery, IObjectWithSite { private: LONG _cRef; IUnknown* _punkSite;
public: CCommonQuery(); ~CCommonQuery();
// IUnknown
STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObject); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)();
// ICommonQuery
STDMETHOD(OpenQueryWindow)(THIS_ HWND hwndParent, LPOPENQUERYWINDOW pOpenQueryWnd, IDataObject** ppDataObject);
// IObjectWithSite
STDMETHODIMP SetSite(IUnknown* punk); STDMETHODIMP GetSite(REFIID riid, void **ppv); };
//
// View layout constants used by our dialogs
//
#define VIEWER_DEFAULT_CY 200
#define COMBOEX_IMAGE_CX 16
#define COMBOEX_IMAGE_CY 16
typedef struct { HDSA hdsaPages; // DSA containing page entries
DWORD dwFlags; // flags
CLSID clsidForm; // CLSID identifier for this form
LPTSTR pTitle; // title used for drop down / title bar
HICON hIcon; // hIcon passed by caller
INT iImage; // image list index of icon
INT iForm; // visible index of form in control
INT iPage; // currently selected page on form
} QUERYFORM, * LPQUERYFORM;
typedef struct { CLSID clsidForm; // CLSID to associate this form with
LPCQPAGE pPage; // CQPAGE structures
LPCQPAGEPROC pPageProc; // PageProc's used by thunking layer
LPARAM lParam; // PAGEPROC lParam
HWND hwndPage; // hWnd of page dialog // = NULL if none
} QUERYFORMPAGE, * LPQUERYFORMPAGE;
typedef struct { LPCQSCOPE pScope; INT iImage; } QUERYSCOPE, * LPQUERYSCOPE;
class CQueryFrame : public IQueryFrame { friend INT QueryWnd_MessageProc(HWND hwnd, LPMSG pMsg); friend INT_PTR CALLBACK QueryWnd_DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public: CQueryFrame(IUnknown* punkSite, LPOPENQUERYWINDOW pOpenQueryWindow, IDataObject** ppDataObject); ~CQueryFrame();
// IUnknown
STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObject); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)();
// Internal helper functions
STDMETHOD(DoModal)(HWND hwndParent);
// IQueryFrame
STDMETHOD(AddScope)(THIS_ LPCQSCOPE pScope, INT i, BOOL fSelect); STDMETHOD(GetWindow)(THIS_ HWND* phWnd); STDMETHOD(InsertMenus)(THIS_ HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidth); STDMETHOD(RemoveMenus)(THIS_ HMENU hmenuShared); STDMETHOD(SetMenu)(THIS_ HMENU hmenuShared, HOLEMENU holereservedMenu); STDMETHOD(SetStatusText)(THIS_ LPCTSTR pszStatusText); STDMETHOD(StartQuery)(THIS_ BOOL fStarting); STDMETHOD(LoadQuery)(THIS_ IPersistQuery* pPersistQuery); STDMETHOD(SaveQuery)(THIS_ IPersistQuery* pPersistQuery); STDMETHOD(CallForm)(THIS_ LPCLSID pclsidForm, UINT uMsg, WPARAM wParam, LPARAM lParam); STDMETHOD(GetScope)(THIS_ LPCQSCOPE* ppScope); STDMETHOD(GetHandler)(THIS_ REFIID riid, void **ppv);
protected: // Helper functions
VOID CloseQueryFrame(HRESULT hres); INT FrameMessageBox(LPCTSTR pPrompt, UINT uType);
// Message handlers
HRESULT OnInitDialog(HWND hwnd); VOID DoEnableControls(VOID); LRESULT OnNotify(INT idCtrl, LPNMHDR pNotify); VOID OnSize(INT cx, INT cy); VOID OnGetMinMaxInfo(LPMINMAXINFO lpmmi); VOID OnCommand(WPARAM wParam, LPARAM lParam); VOID OnInitMenu(HMENU hMenu); VOID OnEnterMenuLoop(BOOL fEntering); VOID OnMenuSelect(HMENU hMenu, UINT uID); HRESULT OnFindNow(VOID); BOOL OnNewQuery(BOOL fAlwaysPrompt); HRESULT OnBrowse(VOID); HRESULT OnHelp(LPHELPINFO pHelpInfo); // Form/Scope helper fucntions
HRESULT InsertScopeIntoList(LPCQSCOPE pScope, INT i, BOOL fAddToControl); HRESULT AddScopeToControl(LPQUERYSCOPE pQueryScope, INT i); HRESULT PopulateScopeControl(VOID); HRESULT GetSelectedScope(LPQUERYSCOPE* ppQueryScope); HRESULT AddFromIQueryForm(IQueryForm* pQueryForm, HKEY hkeyForm); HRESULT GatherForms(VOID); HRESULT GetForms(HKEY hKeyForms, LPTSTR pName); HRESULT PopulateFormControl(BOOL fIncludeHidden); HRESULT SelectForm(REFCLSID clsidForm); VOID SelectFormPage(LPQUERYFORM pQueryForm, INT iPage); HRESULT CallFormPages(LPQUERYFORM pQueryForm, UINT uMsg, WPARAM wParam, LPARAM lParam); LPQUERYFORM FindQueryForm(REFCLSID clsidForm);
private: LONG _cRef; // reference count for the object
IUnknown* _punkSite; // site object we need to pass through
IQueryHandler* _pQueryHandler; // IQueryHandler object we need to interact with
LPOPENQUERYWINDOW _pOpenQueryWnd; // copy of initial parameters provided by caller
IDataObject** _ppDataObject; // receives the resulting data object from handler
DWORD _dwHandlerViewFlags; // flags from the handler
BOOL _fQueryRunning:1; // = 1 => query has been started, via IQueryFrame::StartQuery(TRUE)
BOOL _fExitModalLoop:1; // = 1 => must leave modal loop
BOOL _fScopesPopulated:1; // = 1 => scope control has been populated
BOOL _fTrackingMenuBar:1; // = 1 => then we are tracking the menu bar, therefore send activates etc
BOOL _fAddScopesNYI:1; // = 1 => did AddScopes return E_NOTIMPL
BOOL _fScopesAddedAsync:1; // = 1 => scopes added async by the handler
BOOL _fScopeImageListSet:1; // = 1 => scope image list has been set
BOOL _fFormFirstEnable:1; // = 1 => enabling controls for first item, so ensure we set focus
HRESULT _hResult; // result value stored by CloseQueryFrame
HKEY _hkHandler; // registry key for the handler
HWND _hwnd; // main window handle
HWND _hwndResults; // result viewer
HWND _hwndStatus; // status bar
HWND _hwndFrame; // Query Pages tab control
HWND _hwndLookForLabel; // "Find:"
HWND _hwndLookFor; // Form combo
HWND _hwndLookInLabel; // "In:"
HWND _hwndLookIn; // Scope combo
HWND _hwndBrowse; // "Browse"
HWND _hwndFindNow; // "Find now"
HWND _hwndStop; // "Stop"
HWND _hwndNewQuery; // "New Query"
HWND _hwndOK; // "OK"
HWND _hwndCancel; // "Cancel"
HWND _hwndFindAnimation; // Query issued animation
HICON _hiconSmall; // large/small app icons
HICON _hiconLarge;
HMENU _hmenuFile; // handle of the frames menu bar
HIMAGELIST _himlForms; // image list for query form objects
SIZE _szMinTrack; // minimum track size of the window
INT _dxFormAreaLeft; // offset to left edge of form area (from window left)
INT _dxFormAreaRight; // offset to right edge of form area (from window right)
INT _dxButtonsLeft; // offset to left edge of buttons (from window right)
INT _dxAnimationLeft; // offset to left edge of aniimation (from window right)
INT _dyResultsTop; // offset to top of results (from top of window)
INT _dyOKTop; // offset to top of "OK" buttom (from results top)
INT _dxGap; // gap between OK + Cancel / LookIn + Browse
INT _dyGap; // gap between bottom of OK,Cancel and the frame.
INT _cyStatus; // height of the status bar
HDSA _hdsaForms; // forms DSA
HDSA _hdsaPages; // pages DSA
SIZE _szForm; // size of the (current form we are displaying)
HDSA _hdsaScopes; // scopes DSA
INT _iDefaultScope; // index of the defualt scope to select (into DSA)
LPQUERYFORM _pCurrentForm; // == NULL if none / else -> form structure
LPQUERYFORMPAGE _pCurrentFormPage; // == NULL if none / else -> page structure
};
//
// Helper functions
//
INT_PTR CALLBACK QueryWnd_DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT QueryWnd_MessageProc(HWND hwnd, LPMSG pMsg);
HRESULT _CallScopeProc(LPQUERYSCOPE pQueryScope, UINT uMsg, LPVOID pVoid); INT _FreeScope(LPQUERYSCOPE pQueryScope); INT _FreeScopeCB(LPVOID pItem, LPVOID pData);
HRESULT _CallPageProc(LPQUERYFORMPAGE pQueryFormPage, UINT uMsg, WPARAM wParam, LPARAM lParam); INT _FreeQueryFormCB(LPVOID pItem, LPVOID pData); INT _FreeQueryForm(LPQUERYFORM pQueryForm); INT _FreeQueryFormPageCB(LPVOID pItem, LPVOID pData); INT _FreeQueryFormPage(LPQUERYFORMPAGE pQueryFormPage);
HRESULT _AddFormsProc(LPARAM lParam, LPCQFORM pForm); HRESULT _AddPagesProc(LPARAM lParam, REFCLSID clsidForm, LPCQPAGE pPage);
//
// Help stuff
//
#define HELP_FILE (NULL)
static DWORD const aHelpIDs[] = { 0, 0 };
//
// constant strings
//
TCHAR const c_szCLSID[] = TEXT("CLSID"); TCHAR const c_szForms[] = TEXT("Forms"); TCHAR const c_szFlags[] = TEXT("Flags");
TCHAR const c_szCommonQuery[] = TEXT("CommonQuery"); TCHAR const c_szHandlerIs[] = TEXT("Handler"); TCHAR const c_szFormIs[] = TEXT("Form"); TCHAR const c_szSearchPaneHidden[] = TEXT("SearchPaneHidden");
/*-----------------------------------------------------------------------------
/ CCommonQuery /----------------------------------------------------------------------------*/
CCommonQuery::CCommonQuery() : _punkSite(NULL), _cRef(1) { DllAddRef(); }
CCommonQuery::~CCommonQuery() { DoRelease(_punkSite); DllRelease(); }
// QI handling
ULONG CCommonQuery::AddRef() { return InterlockedIncrement(&_cRef); }
ULONG CCommonQuery::Release() { TraceAssert( 0 != _cRef ); ULONG cRef = InterlockedDecrement(&_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
HRESULT CCommonQuery::QueryInterface(REFIID riid, void **ppv) { static const QITAB qit[] = { QITABENT(CCommonQuery, ICommonQuery), // IID_ICommonQuery
QITABENT(CCommonQuery, IObjectWithSite), // IID_IObjectWithSite
{0, 0 }, }; return QISearch(this, qit, riid, ppv); }
STDAPI CCommonQuery_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk, LPCOBJECTINFO poi) { CCommonQuery *pcq = new CCommonQuery; if (!pcq) return E_OUTOFMEMORY;
HRESULT hres = pcq->QueryInterface(IID_IUnknown, (void **)ppunk); pcq->Release();
return hres; }
// ICommonQuery methods
STDMETHODIMP CCommonQuery::OpenQueryWindow(THIS_ HWND hwndParent, LPOPENQUERYWINDOW pOpenQueryWnd, IDataObject** ppDataObject) { HRESULT hres; CQueryFrame* pQueryFrame = NULL;
TraceEnter(TRACE_QUERY, "CCommonQuery::OpenQueryWindow");
if (!pOpenQueryWnd || (hwndParent && !IsWindow(hwndParent))) ExitGracefully(hres, E_INVALIDARG, "Bad parameters"); if (ppDataObject) *(ppDataObject) = NULL;
pQueryFrame = new CQueryFrame(_punkSite, pOpenQueryWnd, ppDataObject); TraceAssert(pQueryFrame);
if (!pQueryFrame) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to construct the query window object");
hres = pQueryFrame->DoModal(hwndParent); // don't bother fail gracefully etc
FailGracefully(hres, "Failed on calling DoModal");
exit_gracefully:
DoRelease(pQueryFrame);
TraceLeaveResult(hres); }
// IObjectWithSite
STDMETHODIMP CCommonQuery::SetSite(IUnknown* punk) { HRESULT hres = S_OK;
TraceEnter(TRACE_QUERY, "CCommonQuery::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 CCommonQuery::GetSite(REFIID riid, void **ppv) { HRESULT hres; TraceEnter(TRACE_QUERY, "CCommonQuery::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); }
// IQueryFrame stuff
CQueryFrame::CQueryFrame(IUnknown *punkSite, LPOPENQUERYWINDOW pOpenQueryWindow, IDataObject** ppDataObject) : _cRef(1), _punkSite(punkSite), _pOpenQueryWnd(pOpenQueryWindow), _ppDataObject(ppDataObject), _hiconLarge(NULL), _hiconSmall(NULL) { if (_punkSite) _punkSite->AddRef(); DllAddRef(); }
CQueryFrame::~CQueryFrame() { DoRelease(_punkSite);
if (_hiconLarge) DestroyIcon(_hiconLarge);
if (_hiconSmall) DestroyIcon(_hiconSmall);
if (_hkHandler) RegCloseKey(_hkHandler);
if (_hmenuFile) DestroyMenu(_hmenuFile);
if (_himlForms) ImageList_Destroy(_himlForms);
if (_hdsaForms) { Trace(TEXT("Destroying QUERYFORM DSA (%d)"), DSA_GetItemCount(_hdsaForms)); DSA_DestroyCallback(_hdsaForms, _FreeQueryFormCB, NULL); _hdsaForms = NULL; }
if (_hdsaPages) { Trace(TEXT("Destroying QUERYFORMPAGE DSA (%d)"), DSA_GetItemCount(_hdsaPages)); DSA_DestroyCallback(_hdsaPages, _FreeQueryFormPageCB, NULL); _hdsaPages = NULL; }
if (_hdsaScopes) { Trace(TEXT("Destroying QUERYSCOPE DSA (%d)"), DSA_GetItemCount(_hdsaScopes)); DSA_DestroyCallback(_hdsaScopes, _FreeScopeCB, NULL); _hdsaScopes = NULL; }
_pCurrentForm = NULL; _pCurrentFormPage = NULL;
// Now discard the handler and its window (if we have one), if
// we don't do this they will never kill their objects
if (_hwndResults) { DestroyWindow(_hwndResults); _hwndResults = NULL; }
DllRelease(); }
// QI handling
ULONG CQueryFrame::AddRef() { return InterlockedIncrement(&_cRef); }
ULONG CQueryFrame::Release() { TraceAssert( 0 != _cRef ); ULONG cRef = InterlockedDecrement(&_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
HRESULT CQueryFrame::QueryInterface(REFIID riid, void **ppv) { static const QITAB qit[] = { QITABENT(CQueryFrame, IQueryFrame), // IID_IQueryFrame
{0, 0 }, }; return QISearch(this, qit, riid, ppv); }
/*-----------------------------------------------------------------------------
/ IQueryFrame /----------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::DoModal(HWND hwndParent) { HRESULT hres; HWND hwndFrame = NULL; HWND hwndFocus = NULL; HWND hwndTopOwner = hwndParent; MSG msg; INITCOMMONCONTROLSEX iccex;
TraceEnter(TRACE_FRAME, "CQueryFrame::DoModal");
// initialize with the query handler we need
//REVIEWED-2002-02-25-lucios.
hres = CoCreateInstance(_pOpenQueryWnd->clsidHandler, NULL, CLSCTX_INPROC_SERVER, IID_IQueryHandler, (LPVOID*)&_pQueryHandler); FailGracefully(hres, "Failed to get IQueryHandler for the given CLSID");
hres = _pQueryHandler->Initialize(this, _pOpenQueryWnd->dwFlags, _pOpenQueryWnd->pHandlerParameters); FailGracefully(hres, "Failed to initialize the handler");
// mimic the behaviour of DialogBox by working out which control previously
// had focus, which window to disable and then running a message
// pump for our dialog. Having done this we can then restore the state
// back to something sensible.
_fExitModalLoop = FALSE; // can be changed from hear down
iccex.dwSize = SIZEOF(iccex); iccex.dwICC = ICC_USEREX_CLASSES; InitCommonControlsEx(&iccex);
if (_pOpenQueryWnd->dwFlags & OQWF_HIDESEARCHUI) { hwndFrame = CreateDialogParam(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDD_FILTER), hwndParent, QueryWnd_DlgProc, (LPARAM)this); } else { hwndFrame = CreateDialogParam(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDD_FIND), hwndParent, QueryWnd_DlgProc, (LPARAM)this); }
if (!hwndFrame) ExitGracefully(hres, E_FAIL, "Failed to create the dialog");
hwndFocus = GetFocus();
if (hwndTopOwner) { // walk up the window stack looking for the window to be disabled, this must
// be the top-most non-child window. If the resulting window is either
// the desktop or is already disabled then don't bother.
while (GetWindowLong(hwndTopOwner, GWL_STYLE) & WS_CHILD) hwndTopOwner = GetParent(hwndTopOwner);
TraceAssert(hwndTopOwner);
if ((hwndTopOwner == GetDesktopWindow()) || EnableWindow(hwndTopOwner, FALSE)) { TraceMsg("Parent is disabled or the desktop window, therefore setting to NULL"); hwndTopOwner = NULL; } }
ShowWindow(hwndFrame, SW_SHOW); // show the query window
while (!_fExitModalLoop && GetMessage(&msg, NULL, 0, 0) > 0) { if (!QueryWnd_MessageProc(hwndFrame, &msg) && !IsDialogMessage(hwndFrame, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
// Now tidy up, make the parent the active window, enable the top most
// window if there is one and restore focus as required.
if (hwndTopOwner) EnableWindow(hwndTopOwner, TRUE);
if (hwndParent && (GetActiveWindow() == hwndFrame)) { TraceMsg("Passing activation to parent"); SetActiveWindow(hwndParent); } if (IsWindow(hwndFocus)) SetFocus(hwndFocus);
DestroyWindow(hwndFrame); // discard the current frame window
exit_gracefully:
DoRelease(_pQueryHandler);
TraceLeaveResult(_hResult); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::AddScope(THIS_ LPCQSCOPE pScope, INT i, BOOL fSelect) { HRESULT hres;
TraceEnter(TRACE_FRAME, "CQueryFrame::AddScope");
if (!pScope) ExitGracefully(hres, E_INVALIDARG, "No scope to add to the list");
// Add the scope to the control and then ensure that we either have
// its index stored (for default selection) or we select the
// item.
if (!_hdsaScopes || !DSA_GetItemCount(_hdsaScopes)) { TraceMsg("First scope being added, thefore selecting"); fSelect = TRUE; }
hres = InsertScopeIntoList(pScope, i, _fScopesPopulated); FailGracefully(hres, "Failed to add scope to control");
if (fSelect) { if (!_fScopesPopulated) { Trace(TEXT("Storing default scope index %d"), ShortFromResult(hres)); _iDefaultScope = ShortFromResult(hres); } else { Trace(TEXT("Selecting scope index %d"), ShortFromResult(hres)); ComboBox_SetCurSel(_hwndLookIn, ShortFromResult(hres)); } }
// hres = S_OK;
exit_gracefully:
TraceLeaveResult(hres); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::GetWindow(THIS_ HWND* phWnd) { TraceEnter(TRACE_FRAME, "CQueryFrame::GetWindow");
TraceAssert(phWnd); *phWnd = _hwnd;
TraceLeaveResult(S_OK); }
/*---------------------------------------------------------------------------*/
// Add a menu group to the given menu bar, updating the width index accordingly
// so that other people can merge in accordingly
VOID _DoInsertMenu(HMENU hMenu, INT iIndexTo, HMENU hMenuToInsert, INT iIndexFrom) { TCHAR szBuffer[MAX_PATH]; HMENU hPopupMenu = NULL;
TraceEnter(TRACE_FRAME, "_DoInsertMenu"); hPopupMenu = CreatePopupMenu(); if (hPopupMenu) { Shell_MergeMenus(hPopupMenu, GetSubMenu(hMenuToInsert, iIndexFrom), 0x0, 0x0, 0x7fff, 0); //REVIEWED-2002-02-25-lucios.
GetMenuString(hMenuToInsert, iIndexFrom, szBuffer, ARRAYSIZE(szBuffer), MF_BYPOSITION); InsertMenu(hMenu, iIndexTo, MF_BYPOSITION|MF_POPUP, (UINT_PTR)hPopupMenu, szBuffer); }
TraceLeave(); }
VOID _AddMenuGroup(HMENU hMenuShared, HMENU hMenuGroup, LONG iInsertAt, LPLONG pWidth) { HRESULT hres; TCHAR szBuffer[MAX_PATH]; HMENU hMenu; INT i;
TraceEnter(TRACE_FRAME, "_AddMenuGroup");
TraceAssert(hMenuShared); TraceAssert(hMenuGroup); TraceAssert(pWidth);
for (i = 0 ; i < GetMenuItemCount(hMenuGroup) ; i++) { _DoInsertMenu(hMenuShared, iInsertAt+i, hMenuGroup, i); *pWidth += 1; }
TraceLeave(); }
STDMETHODIMP CQueryFrame::InsertMenus(THIS_ HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidth) { HRESULT hres;
TraceEnter(TRACE_FRAME, "CQueryFrame::InsertMenus");
if (!hmenuShared || !lpMenuWidth) ExitGracefully(hres, E_INVALIDARG, "Unable to insert menus");
// if we don't have the menu bar already loaded then lets load it,
// having done that we can then add our menu to the bar (we only
// provide entries for the file menu).
if (!_hmenuFile) { _hmenuFile = LoadMenu(GLOBAL_HINSTANCE, MAKEINTRESOURCE(IDR_FILEMENUGROUP));
if (!_hmenuFile) ExitGracefully(hres, E_FAIL, "Failed to load base menu defn"); }
_AddMenuGroup(hmenuShared, _hmenuFile, 0, &lpMenuWidth->width[0]);
hres = S_OK; // success
exit_gracefully:
TraceLeaveResult(hres); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::RemoveMenus(THIS_ HMENU hmenuShared) { TraceEnter(TRACE_FRAME, "CQueryFrame::RemoveMenus");
// We don't need to implement this as we copy or menus into the
// menu that the handler supplies - fix DSQUERY if this ever
// changes.
TraceLeaveResult(S_OK); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::SetMenu(THIS_ HMENU hmenuShared, HOLEMENU holereservedMenu) { TraceEnter(TRACE_FRAME, "CQueryFrame::SetMenu");
if (!(_pOpenQueryWnd->dwFlags & OQWF_HIDEMENUS)) { HMENU hmenuOld = ::GetMenu(_hwnd);
if (!hmenuShared) hmenuShared = _hmenuFile;
::SetMenu(_hwnd, hmenuShared); DoEnableControls(); // ensure the menu state is valid
::DrawMenuBar(_hwnd);
if (hmenuOld && (hmenuOld != _hmenuFile) && (hmenuOld != hmenuShared)) { TraceMsg("Destroying old menu"); DestroyMenu(hmenuOld); } }
TraceLeaveResult(S_OK); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::SetStatusText(THIS_ LPCTSTR pszStatusText) { TraceEnter(TRACE_FRAME, "CQueryFrame::SetStatusText"); Trace(TEXT("Setting status text to: %s"), pszStatusText);
if (_hwndStatus) SendMessage(_hwndStatus, SB_SETTEXT, 0, (LPARAM)pszStatusText);
TraceLeaveResult(S_OK); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::StartQuery(THIS_ BOOL fStarting) { TraceEnter(TRACE_FRAME, "CQueryFrame::StartQuery");
if (fStarting) { Animate_Play(_hwndFindAnimation, 0, -1, -1); } else { Animate_Stop(_hwndFindAnimation); Animate_Seek(_hwndFindAnimation, 0); // go to start
}
if (_pQueryHandler) _pQueryHandler->ActivateView(CQRVA_STARTQUERY, (WPARAM)fStarting, 0); // now set the controls into a sensble state
_fQueryRunning = fStarting; DoEnableControls();
TraceLeaveResult(S_OK); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::LoadQuery(THIS_ IPersistQuery* pPersistQuery) { HRESULT hres; TCHAR szGUID[GUIDSTR_MAX+1]; LPQUERYFORM pQueryForm = NULL; GUID guid;
TraceEnter(TRACE_FRAME, "CQueryFrame::LoadQuery");
_pQueryHandler->StopQuery(); // ensure that the handler stops its processing
// Attempt to read the handler GUID from the query stream, first try reading it as
// as string then parsing it into something that we can use, if that fails then
// try again, but this time read it as a structure.
//
// having aquired the GUID for the handler make sure that we have the correct handler
// selected.
if (FAILED(pPersistQuery->ReadString(c_szCommonQuery, c_szHandlerIs, szGUID, ARRAYSIZE(szGUID))) || !GetGUIDFromString(szGUID, &guid)) { TraceMsg("Trying new style handler GUID as struct");
hres = pPersistQuery->ReadStruct(c_szCommonQuery, c_szHandlerIs, &guid, SIZEOF(guid)); FailGracefully(hres, "Failed to read handler GUID as struct"); }
if (guid != _pOpenQueryWnd->clsidHandler) ExitGracefully(hres, E_FAIL, "Persisted handler GUID and specified handler GUID don't match");
hres = _pQueryHandler->LoadQuery(pPersistQuery); FailGracefully(hres, "Handler failed to load its query data");
// Get the form ID, then look up the form to see if we have one that matches,
// if not then we cannot load any thing else. If we do haved that form then
// ensure that we clear it and then load away.
if (FAILED(pPersistQuery->ReadString(c_szCommonQuery, c_szFormIs, szGUID, ARRAYSIZE(szGUID))) || !GetGUIDFromString(szGUID, &guid)) { TraceMsg("Trying new style form GUID as struct");
hres = pPersistQuery->ReadStruct(c_szCommonQuery, c_szFormIs, &guid, SIZEOF(guid)); FailGracefully(hres, "Failed to read handler GUID as struct"); }
hres = SelectForm(guid); FailGracefully(hres, "Failed to select the query form");
if (hres == S_FALSE) ExitGracefully(hres, E_FAIL, "Failed to select the query form to read the query info"); hres = CallFormPages(_pCurrentForm, CQPM_CLEARFORM, 0, 0); FailGracefully(hres, "Failed to clear form before loading");
// Load the persisted query from the stream, coping correctly with the
// UNICODE / ANSI issue. We will be passed an IPersistQuery object which
// we must then thunk accordingly if we are UNICODE for the pages we
// are going to talk to.
hres = CallFormPages(_pCurrentForm, CQPM_PERSIST, TRUE, (LPARAM)pPersistQuery); FailGracefully(hres, "Failed to load page data (UNICODE)");
hres = S_OK; // success
exit_gracefully:
if (SUCCEEDED(hres)) { TraceMsg("Query loaded successfully, select form query"); SelectForm(guid); }
TraceLeaveResult(hres); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::SaveQuery(THIS_ IPersistQuery* pPersistQuery) { HRESULT hres; LPQUERYSCOPE pQueryScope; TCHAR szBuffer[MAX_PATH]; TraceEnter(TRACE_FRAME, "CQueryFrame::SaveQuery");
if (!pPersistQuery) ExitGracefully(hres, E_INVALIDARG, "No pPersistQuery object to write into");
pPersistQuery->Clear(); // flush the contents
hres = pPersistQuery->WriteStruct(c_szCommonQuery, c_szHandlerIs, &_pOpenQueryWnd->clsidHandler, SIZEOF(_pOpenQueryWnd->clsidHandler)); FailGracefully(hres, "Failed to write handler GUID");
hres = pPersistQuery->WriteStruct(c_szCommonQuery, c_szFormIs, &_pCurrentForm->clsidForm, SIZEOF(_pCurrentForm->clsidForm)); FailGracefully(hres, "Failed to write form GUID");
// Allow the handler to persist itself into the the stream, this includes
// giving it the current scope to store.
hres = GetSelectedScope(&pQueryScope); FailGracefully(hres, "Failed to get the scope from the LookIn control");
hres = _pQueryHandler->SaveQuery(pPersistQuery, pQueryScope->pScope); FailGracefully(hres, "Failed when calling handler to persist itself");
// Save the query into the stream, coping correctly with the
// UNICODE / ANSI issue. We will be passed an IPersistQuery object which
// we must then thunk accordingly if we are UNICODE for the pages we
// are going to talk to.
hres = CallFormPages(_pCurrentForm, CQPM_PERSIST, FALSE, (LPARAM)pPersistQuery); FailGracefully(hres, "Failed to load page data (UNICODE)");
hres = S_OK;
exit_gracefully:
TraceLeaveResult(hres); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::CallForm(THIS_ LPCLSID pclsidForm, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hres; LPQUERYFORM pQueryForm = _pCurrentForm;
TraceEnter(TRACE_FRAME, "CQueryFrame::CallForm"); if (pclsidForm) { pQueryForm = FindQueryForm(*pclsidForm); TraceAssert(pQueryForm); }
if (!pQueryForm) ExitGracefully(hres, E_FAIL, "Failed to find query form for given CLSID");
hres = CallFormPages(pQueryForm, uMsg, wParam, lParam); FailGracefully(hres, "Failed when calling CallFormPages");
// hres = S_OK;
exit_gracefully:
TraceLeaveResult(hres); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::GetScope(THIS_ LPCQSCOPE* ppScope) { HRESULT hres; LPQUERYSCOPE pQueryScope;
TraceEnter(TRACE_FRAME, "CQueryFrame::GetScope");
if (!ppScope) ExitGracefully(hres, E_INVALIDARG, "ppScope == NULL, thats bad");
hres = GetSelectedScope(&pQueryScope); FailGracefully(hres, "Failed to get the current scope");
*ppScope = (LPCQSCOPE)CoTaskMemAlloc(pQueryScope->pScope->cbStruct); TraceAssert(*ppScope);
if (!*ppScope) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate the scope block"); //REVIEWED-2002-02-25-lucios.
memcpy(*ppScope, pQueryScope->pScope, pQueryScope->pScope->cbStruct);
hres = S_OK;
exit_gracefully:
TraceLeaveResult(hres); }
/*---------------------------------------------------------------------------*/
STDMETHODIMP CQueryFrame::GetHandler(THIS_ REFIID riid, void **ppv) { HRESULT hres;
TraceEnter(TRACE_FRAME, "CQueryFrame::GetHandler");
if (!_pQueryHandler) ExitGracefully(hres, E_UNEXPECTED, "_pQueryHandler is NULL");
hres = _pQueryHandler->QueryInterface(riid, ppv);
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ Dialog box handler functions (core guts) /----------------------------------------------------------------------------*/
#define REAL_WINDOW(hwnd) \
(hwnd && \ IsWindowVisible(hwnd) && \ IsWindowEnabled(hwnd) && \ (GetWindowLong(hwnd, GWL_STYLE) & WS_TABSTOP))
HWND _NextTabStop(HWND hwndSearch, BOOL fShift) { HWND hwnd;
Trace(TEXT("hwndSearch %08x, fShift %d"), hwndSearch, fShift);
// do we have a window to search into?
while (hwndSearch) { // if we have a window then lets check to see if it has any children?
hwnd = GetWindow(hwndSearch, GW_CHILD); Trace(TEXT("Child of %08x is %08x"), hwndSearch, hwnd);
if (hwnd) { // it has a child therefore lets to go its first/last
// and continue the search there for a window that
// matches the criteria we are looking for.
hwnd = GetWindow(hwnd, fShift ? GW_HWNDLAST:GW_HWNDFIRST);
if (!REAL_WINDOW(hwnd)) { Trace(TEXT("Trying to recurse into %08x"), hwnd); hwnd = _NextTabStop(hwnd, fShift); }
Trace(TEXT("Tabstop child of %08x is %08x"), hwndSearch, hwnd); }
// after all that is hwnd a valid window? if so then pass
// that back out to the caller.
if (REAL_WINDOW(hwnd)) { Trace(TEXT("Child tab stop was %08x"), hwnd); return hwnd; }
// do we have a sibling? if so then lets return that otherwise
// lets just continue to search until we either run out of windows
// or hit something interesting
hwndSearch = GetWindow(hwndSearch, fShift ? GW_HWNDPREV:GW_HWNDNEXT);
if (REAL_WINDOW(hwndSearch)) { Trace(TEXT("Next tab stop was %08x"), hwndSearch); return hwndSearch; } }
return hwndSearch; }
INT QueryWnd_MessageProc(HWND hwnd, LPMSG pMsg) { LRESULT lResult = 0; CQueryFrame* pQueryFrame = NULL; NMHDR nmhdr;
pQueryFrame = (CQueryFrame*)GetWindowLongPtr(hwnd, DWLP_USER);
if (!pQueryFrame) return 0;
if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB)) { BOOL fCtrl = GetAsyncKeyState(VK_CONTROL) < 0; BOOL fShift = GetAsyncKeyState(VK_SHIFT) < 0;
// ensure that the focus rectangles are shown
#if (_WIN32_WINNT >= 0x0500)
SendMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0); #endif
if (fCtrl) { // if this is a key press within the parent then lets ensure that we
// allow the tab control to change the page correctly. otherwise lets
// just hack around the problem of the result view not handling tabs
// properly.
INT iCur = TabCtrl_GetCurSel(pQueryFrame->_hwndFrame); INT nPages = TabCtrl_GetItemCount(pQueryFrame->_hwndFrame);
if (fShift) iCur += (nPages-1); else iCur++;
pQueryFrame->SelectFormPage(pQueryFrame->_pCurrentForm, iCur % nPages);
return 1; // we processed it
} else { // is the window that has the focus a child of the result view, if
// so then we must attempt to pass focus to its 1st child and hope
// that is can do the rest.
HWND hwndNext, hwndFocus = GetFocus(); Trace(TEXT("Current focus window %08x"), hwndFocus); while (hwndFocus && GetWindowLong(hwndFocus, GWL_STYLE) & WS_CHILD) { hwndNext = _NextTabStop(hwndFocus, fShift); Trace(TEXT("_NextTabStop yeilds %08x from %08x"), hwndNext, hwndFocus); if (hwndNext) { Trace(TEXT("SetFocus on child %08x"), hwndNext); SendMessage(GetParent(hwndNext),WM_NEXTDLGCTL,(WPARAM)hwndNext,TRUE); SetFocus(hwndNext); return 1; }
while (TRUE) { // look up the parent list trying to find a window that we can
// tab back into. We must watch that when we walk out of the
// child list we loop correctly at the top of the list.
hwndNext = GetParent(hwndFocus); Trace(TEXT("Parent hwnd %08x"), hwndNext);
if (GetWindowLong(hwndNext, GWL_STYLE) & WS_CHILD) { // the parent window is a child, therefore we can check
// to see if has any siblings.
Trace(TEXT("hwndNext is a child, therefore hwndNext of it is %08x"), GetWindow(hwndNext, fShift ? GW_HWNDPREV:GW_HWNDNEXT)); if (GetWindow(hwndNext, fShift ? GW_HWNDPREV:GW_HWNDNEXT)) { hwndFocus = GetWindow(hwndNext, fShift ? GW_HWNDPREV:GW_HWNDNEXT); Trace(TEXT("Silbing window found %08x"), hwndFocus); break; } else { TraceMsg("There was no sibling, therefore continuing parent loop"); hwndFocus = hwndNext; } } else { // we have hit the parent window of it all (the overlapped one)
// therefore we must attempt to go to its first child. Walk forward
// in the stack looking for a window that matches the
// "REAL_WINDOW" conditions.
hwndFocus = GetWindow(hwndFocus, fShift ? GW_HWNDLAST:GW_HWNDFIRST); Trace(TEXT("First child is %08x"), hwndFocus); break; // continue the sibling search etc
} }
if (REAL_WINDOW(hwndFocus)) { SendMessage(GetParent(hwndFocus),WM_NEXTDLGCTL,(WPARAM)hwndFocus,TRUE); SetFocus(hwndFocus); return 1; } } } }
return 0; }
//
// Main DLGPROC
//
INT_PTR CALLBACK QueryWnd_DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CQueryFrame* pQueryFrame;
if (uMsg == WM_INITDIALOG) { HRESULT hres; pQueryFrame = (CQueryFrame*)lParam; SetWindowLongPtr(hwnd, DWLP_USER, (LRESULT)pQueryFrame);
hres = pQueryFrame->OnInitDialog(hwnd); Trace(TEXT("OnInitDialog returns %08x"), hres); if (FAILED(hres)) { TraceMsg("Failed to initialize the dialog, Destroying the window"); pQueryFrame->CloseQueryFrame(hres); DestroyWindow(hwnd); } } else { pQueryFrame = (CQueryFrame*)GetWindowLongPtr(hwnd, DWLP_USER);
if (!pQueryFrame) goto exit_gracefully;
switch (uMsg) { case WM_ERASEBKGND: { HDC hdc = (HDC)wParam; RECT rc;
// if we have a DC then lets fill it, and if we have a
// query form then lets paint the divider between the menu bar and
// this area.
if (hdc) { GetClientRect(hwnd, &rc); FillRect(hdc, &rc, (HBRUSH)(COLOR_3DFACE+1));
if (!(pQueryFrame->_pOpenQueryWnd->dwFlags & OQWF_HIDEMENUS)) DrawEdge(hdc, &rc, EDGE_ETCHED, BF_TOP);
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 1L); } return 1; }
case WM_NOTIFY: return pQueryFrame->OnNotify((int)wParam, (LPNMHDR)lParam);
case WM_SIZE: pQueryFrame->OnSize(LOWORD(lParam), HIWORD(lParam)); return(1);
case WM_GETMINMAXINFO: pQueryFrame->OnGetMinMaxInfo((LPMINMAXINFO)lParam); return(1);
case WM_COMMAND: pQueryFrame->OnCommand(wParam, lParam); return(1);
case WM_ACTIVATE: pQueryFrame->_pQueryHandler->ActivateView(wParam ? CQRVA_ACTIVATE : CQRVA_DEACTIVATE, 0, 0); // NTRAID#NTBUG9-411693-2001/10/24-lucios
// We return 0 so that we don't call DefWndProc and therefore the
// focus is not set to the first child control
return(0); case WM_INITMENU: pQueryFrame->OnInitMenu((HMENU)wParam); return(1);
case WM_SETCURSOR: { // do we have any scopes? if not then let us display the wait
// cursor for the user. if we have a query running then lets
// display the app start cursor.
if (!pQueryFrame->_fAddScopesNYI && !ComboBox_GetCount(pQueryFrame->_hwndLookIn)) { if (LOWORD(lParam) == HTCLIENT) { SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT))); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 1L); return 1; } }
break; }
case WM_INITMENUPOPUP: { // only send sub-menu activates if the menu bar is being tracked, this is
// handled within OnInitMenu, if we are not tracking the menu then we
// assume that the client has already primed the menu and that they are
// using some kind of popup menu.
if (pQueryFrame->_fTrackingMenuBar) pQueryFrame->_pQueryHandler->ActivateView(CQRVA_INITMENUBARPOPUP, wParam, lParam);
return(1); } case WM_ENTERMENULOOP: pQueryFrame->OnEnterMenuLoop(TRUE); return(1);
case WM_EXITMENULOOP: pQueryFrame->OnEnterMenuLoop(FALSE); return(1);
case WM_MENUSELECT: { UINT uID = LOWORD(wParam); UINT uFlags = HIWORD(wParam); HMENU hMenu = (HMENU)lParam; // the command opens a popup menu the the uID is actually
// the index into the menu, so lets ensure that we pick
// up the correct ID by calling GetMenuItemInfo, note that
// GetMenuItemID returns -1 in this case which is totally
// useless.
if (uFlags & MF_POPUP) { MENUITEMINFO mii;
ZeroMemory(&mii, SIZEOF(mii)); mii.cbSize = SIZEOF(mii); mii.fMask = MIIM_ID;
if (GetMenuItemInfo(hMenu, uID, TRUE, &mii)) uID = mii.wID; }
pQueryFrame->OnMenuSelect(hMenu, uID); return(1); }
case WM_SYSCOMMAND: if (wParam == SC_CLOSE) { pQueryFrame->CloseQueryFrame(S_FALSE); return(1); } break;
case WM_CONTEXTMENU: { // there are a couple of controls we don't care about for the
// frame, so lets ignore those when passing the CQRVA_CONTEXTMENU
// through to the handler.
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; ScreenToClient((HWND)wParam, &pt); switch (GetDlgCtrlID(ChildWindowFromPoint((HWND)wParam, pt))) { case IDC_FORMAREA: case IDC_FINDANIMATION: case IDC_STATUS: return TRUE; // handled
default: pQueryFrame->_pQueryHandler->ActivateView(CQRVA_CONTEXTMENU, wParam, lParam); return TRUE; }
return FALSE; } case WM_HELP: { LPHELPINFO phi = (LPHELPINFO)lParam;
// filter out those controls we are not interested in (they make no sense)
// to bother the user with
switch (GetDlgCtrlID((HWND)phi->hItemHandle)) { case IDC_FORMAREA: case IDC_FINDANIMATION: case IDC_STATUS: return TRUE;
default: pQueryFrame->OnHelp(phi); return TRUE; }
return FALSE; }
case CQFWM_ADDSCOPE: { LPCQSCOPE pScope = (LPCQSCOPE)wParam; BOOL fSelect = LOWORD(lParam); INT iIndex = HIWORD(lParam);
if (SUCCEEDED(pQueryFrame->AddScope(pScope, iIndex, fSelect))) SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 1L);
return 1; }
case CQFWM_GETFRAME: { IQueryFrame** ppQueryFrame = (IQueryFrame**)lParam;
if (ppQueryFrame) { pQueryFrame->AddRef(); *ppQueryFrame = pQueryFrame; SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 1L); }
return 1; }
case CQFWM_ALLSCOPESADDED: { // there is an async scope collector, it has added all the scopes
// so we must now attempt to issue the query if the we are in the
// holding pattern waiting for the scopes to be collected.
pQueryFrame->_fScopesAddedAsync = FALSE; // all scopes have been added
if (pQueryFrame->_pOpenQueryWnd->dwFlags & OQWF_ISSUEONOPEN) PostMessage(pQueryFrame->_hwnd, CQFWM_STARTQUERY, 0, 0);
return 1; }
case CQFWM_STARTQUERY: pQueryFrame->OnFindNow(); return 1;
case CQFWM_SETDEFAULTFOCUS: { HWND hwndNextTab = _NextTabStop(pQueryFrame->_pCurrentFormPage->hwndPage, FALSE); SendMessage(pQueryFrame->_pCurrentFormPage->hwndPage, WM_NEXTDLGCTL, (WPARAM)hwndNextTab, 1); break; }
default: break; } }
exit_gracefully:
return(0); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::CloseQueryFrame / ---------------------------- / Close the query window passing back the data object if required, and ensuring / that our result code indicates what is going on. / / In: / hResult = result code to pass to the caller / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::CloseQueryFrame(HRESULT hres) { TraceEnter(TRACE_FRAME, "CQueryFrame::CloseQueryFrame"); Trace(TEXT("hResult %08x"), hres);
// If we succeeded then attempt to collect the IDataObject and pass it
// back to the caller.
if (hres == S_OK) { if (_ppDataObject) { hres = _pQueryHandler->GetViewObject(CQRVS_SELECTION, IID_IDataObject, (LPVOID*)_ppDataObject); FailGracefully(hres, "Failed when collecting the data object"); }
if ((_pOpenQueryWnd->dwFlags & OQWF_SAVEQUERYONOK) && _pOpenQueryWnd->pPersistQuery) { hres = SaveQuery(_pOpenQueryWnd->pPersistQuery); FailGracefully(hres, "Failed when persisting query to IPersistQuery blob"); }
hres = S_OK; // success
}
exit_gracefully:
_hResult = hres; _fExitModalLoop = TRUE; // bomb out of the modal loop
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::FrameMessageBox / ---------------------------- / Our message box for putting up prompts that relate to the current / query. We handle getting the view information and displaying / the prompt, returning the result from MessageBox. / / In: / pPrompt = text displayed as a prompt / uType = message box type / / Out: / INT /----------------------------------------------------------------------------*/ INT CQueryFrame::FrameMessageBox(LPCTSTR pPrompt, UINT uType) { TCHAR szTitle[MAX_PATH]; CQVIEWINFO vi;
TraceEnter(TRACE_FRAME, "CQueryFrame::FrameMessageBox");
ZeroMemory(&vi, SIZEOF(vi)); //vi. dwFlags = 0; // display attributes
if (SUCCEEDED(_pQueryHandler->GetViewInfo(&vi)) && vi.hInstance && vi.idTitle) LoadString(vi.hInstance, vi.idTitle, szTitle, ARRAYSIZE(szTitle)); else GetWindowText(_hwnd, szTitle, ARRAYSIZE(szTitle));
TraceLeaveValue(MessageBox(_hwnd, pPrompt, szTitle, uType)); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnInitDlg / ---------------------- / Handle a WM_INITDAILOG message, this is sent as the first thing the / dialog receives, therefore we must handle our initialization that / was not handled in the constructor. / / In: / hwnd = handle of dialog we are initializing / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::OnInitDialog(HWND hwnd) { HRESULT hres; HICON hIcon = NULL; TCHAR szGUID[GUIDSTR_MAX+1]; TCHAR szBuffer[MAX_PATH]; CQVIEWINFO vi; INT dyControls = 0; RECT rect, rect2; SIZE size; TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnInitDialog");
// get the HKEY for the handler we are using
hres = GetKeyForCLSID(_pOpenQueryWnd->clsidHandler, NULL, &_hkHandler); FailGracefully(hres, "Failed to open handlers HKEY");
// pick up the control handles and store them, saves picking them up later
_hwnd = hwnd; _hwndFrame = GetDlgItem(hwnd, IDC_FORMAREA); _hwndLookForLabel = GetDlgItem(hwnd, CQID_LOOKFORLABEL); _hwndLookFor = GetDlgItem(hwnd, CQID_LOOKFOR); _hwndLookInLabel = GetDlgItem(hwnd, CQID_LOOKINLABEL); _hwndLookIn = GetDlgItem(hwnd, CQID_LOOKIN); _hwndBrowse = GetDlgItem(hwnd, CQID_BROWSE); _hwndFindNow = GetDlgItem(hwnd, CQID_FINDNOW); _hwndStop = GetDlgItem(hwnd, CQID_STOP); _hwndNewQuery = GetDlgItem(hwnd, CQID_CLEARALL); _hwndFindAnimation = GetDlgItem(hwnd, IDC_FINDANIMATION); _hwndOK = GetDlgItem(hwnd, IDOK); _hwndCancel = GetDlgItem(hwnd, IDCANCEL);
// when enable is called this will be the first
_fFormFirstEnable = TRUE;
// call the IQueryHandler interface and get its display attributes,
// then reflect these into the dialog we are about to display to the
// outside world.
vi.dwFlags = 0; vi.hInstance = NULL; vi.idLargeIcon = 0; vi.idSmallIcon = 0; vi.idTitle = 0; vi.idAnimation = 0;
hres = _pQueryHandler->GetViewInfo(&vi); FailGracefully(hres, "Failed when getting the view info from the handler");
_dwHandlerViewFlags = vi.dwFlags;
if (vi.hInstance) { HICON hiTemp = NULL;
if (vi.idLargeIcon) { _hiconLarge = (HICON)LoadImage(vi.hInstance, MAKEINTRESOURCE(vi.idLargeIcon), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR|LR_DEFAULTSIZE); if (_hiconLarge) SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)_hiconLarge); }
if (vi.idSmallIcon) { _hiconSmall = (HICON)LoadImage(vi.hInstance, MAKEINTRESOURCE(vi.idLargeIcon), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); if (_hiconSmall) SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)_hiconSmall); }
if (vi.idTitle) { LoadString(vi.hInstance, vi.idTitle, szBuffer, ARRAYSIZE(szBuffer)); SetWindowText(hwnd, szBuffer); } }
if (vi.hInstance && vi.idAnimation) { SetWindowLongPtr(_hwndFindAnimation, GWLP_HINSTANCE, (LRESULT)vi.hInstance); Animate_Open(_hwndFindAnimation, MAKEINTRESOURCE(vi.idAnimation)); } else { Animate_Open(_hwndFindAnimation, MAKEINTRESOURCE(IDR_FINDANIMATION)); }
// now adjust the positions and hide the controls we are not interested in
if (_pOpenQueryWnd->dwFlags & OQWF_REMOVEFORMS) { // NTRAID#NTBUG9-619016-2002/05/21-lucios
EnableWindow(_hwndLookForLabel,FALSE); ShowWindow(_hwndLookForLabel, SW_HIDE); ShowWindow(_hwndLookFor, SW_HIDE); }
if (_pOpenQueryWnd->dwFlags & OQWF_REMOVESCOPES) { // NTRAID#NTBUG9-619016-2002/05/21-lucios
EnableWindow(_hwndLookInLabel,FALSE); ShowWindow(_hwndLookInLabel, SW_HIDE); ShowWindow(_hwndLookIn, SW_HIDE); ShowWindow(_hwndBrowse, SW_HIDE); }
// hiding both the scopes and the forms control causes us to
// move all the controls up by so many units.
if ((_pOpenQueryWnd->dwFlags & (OQWF_REMOVEFORMS|OQWF_REMOVESCOPES)) == (OQWF_REMOVEFORMS|OQWF_REMOVESCOPES)) { GetRealWindowInfo(_hwndLookForLabel, &rect, NULL); GetRealWindowInfo(_hwndFrame, &rect2, NULL);
dyControls += rect2.top - rect.top; Trace(TEXT("Moving all controls up by %d units"), dyControls);
OffsetWindow(_hwndFrame, 0, -dyControls); OffsetWindow(_hwndFindNow, 0, -dyControls); OffsetWindow(_hwndStop, 0, -dyControls); OffsetWindow(_hwndNewQuery, 0, -dyControls); OffsetWindow(_hwndFindAnimation, 0, -dyControls); OffsetWindow(_hwndOK, 0, -dyControls);
if (_hwndCancel) OffsetWindow(_hwndCancel, 0, -dyControls); }
// hiding OK/Cancel so lets adjust the size here to include the
// OK/Cancel buttons disappearing, note that we update dyControls
// to include this delta
if (!(_pOpenQueryWnd->dwFlags & OQWF_OKCANCEL)) { ShowWindow(_hwndOK, SW_HIDE);
if (_hwndCancel) ShowWindow(_hwndCancel, SW_HIDE);
// if this is the filter dialog then lets ensure that
// we trim the OK/Cancel buttons from the size by adjusting the
// dyControls further.
GetRealWindowInfo(_hwndOK, &rect, NULL); GetRealWindowInfo(_hwndFrame, &rect2, NULL); dyControls += rect.bottom - rect2.bottom; }
// having performed that extra bit of initialization lets cache the
// positions of the various controls, to make sizing more fun...
GetClientRect(hwnd, &rect2); rect2.bottom -= dyControls;
_dyResultsTop = rect2.bottom;
GetRealWindowInfo(hwnd, NULL, &size); GetRealWindowInfo(_hwndFrame, &rect, &_szForm);
Trace(TEXT("dyControls %d"), dyControls); size.cy -= dyControls;
_dxFormAreaLeft = rect.left; _dxFormAreaRight = rect2.right - rect.right; _szMinTrack.cx = size.cx - _szForm.cx; _szMinTrack.cy = size.cy - _szForm.cy;
if (!(_pOpenQueryWnd->dwFlags & OQWF_HIDEMENUS)) { TraceMsg("Adjusting _szMinTrack.cy to account for menu bar"); _szMinTrack.cy += GetSystemMetrics(SM_CYMENU); } GetRealWindowInfo(_hwndBrowse, &rect, NULL); _dxButtonsLeft = rect2.right - rect.left;
GetRealWindowInfo(_hwndLookIn, &rect, NULL); _dxGap = (rect2.right - rect.right) - _dxButtonsLeft;
GetRealWindowInfo(_hwndFindAnimation, &rect, NULL); _dxAnimationLeft = rect2.right - rect.left;
GetRealWindowInfo(_hwndOK, &rect, NULL); _dyOKTop = rect2.bottom - rect.top; _dyGap = size.cy - rect.bottom;
// Now collect the forms and pages, then walk them building the size
// information that we need.
hres = GatherForms(); FailGracefully(hres, "Failed to init form list");
_szMinTrack.cx += _szForm.cx; _szMinTrack.cy += _szForm.cy;
// Populate the scope control by querying the handler for them,
// if there are none then we display a suitable message box and
// let the user know that something went wrong.
hres = PopulateScopeControl(); FailGracefully(hres, "Failed to init scope list");
_fScopesPopulated = TRUE; // scope control now populated
// perform final fix up of the window, ensure that we size it so that
// the entire form and buttons are visible. Then set ourselves into the
// no query state and reset the animation.
SetWindowPos(hwnd, NULL, 0, 0, _szMinTrack.cx, _szMinTrack.cy, SWP_NOMOVE|SWP_NOZORDER);
if (_pOpenQueryWnd->dwFlags & OQWF_HIDEMENUS) ::SetMenu(hwnd, NULL);
hres = PopulateFormControl(_pOpenQueryWnd->dwFlags & OQWF_SHOWOPTIONAL); FailGracefully(hres, "Failed to populate form control");
// Now load the query which inturn selects the form that we should be using,
// if there is no query to load then either use the default form or
// the first in the list.
if ((_pOpenQueryWnd->dwFlags & OQWF_LOADQUERY) && _pOpenQueryWnd->pPersistQuery) { // NTRAID#NTBUG9-627056-2002/06/11-artm
// If unable to load query, still show the window but w/out values filled in.
HRESULT hResLoad = LoadQuery(_pOpenQueryWnd->pPersistQuery); if (FAILED(hResLoad)) { Trace(TEXT("Failed when trying to load query from supplied IPersistQuery with error %x"), hResLoad); } } else { if (_pOpenQueryWnd->dwFlags & OQWF_DEFAULTFORM) { SelectForm(_pOpenQueryWnd->clsidDefaultForm);
if (!_pCurrentForm) ExitGracefully(hres, E_FAIL, "Failed to select the query form"); } else { INT iForm = (int)ComboBox_GetItemData(_hwndLookFor, 0); LPQUERYFORM pQueryForm = (LPQUERYFORM)DSA_GetItemPtr(_hdsaForms, iForm); TraceAssert(pQueryForm);
SelectForm(pQueryForm->clsidForm); } }
StartQuery(FALSE); // issue on open, therefore lets get the query going, if there is async
// scope collection then the query will be issued by the bg thread.
if (_pOpenQueryWnd->dwFlags & OQWF_ISSUEONOPEN) PostMessage(_hwnd, CQFWM_STARTQUERY, 0, 0);
SetForegroundWindow(hwnd);
hres = S_OK; // success
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::EnableControls / --------------------------- / Set the controls into their enabled/disabled state based on the / state of the dialog. / / In: / - / / Out: / HRESULT /----------------------------------------------------------------------------*/ VOID CQueryFrame::DoEnableControls(VOID) { BOOL fScopes = (_fAddScopesNYI || ComboBox_GetCount(_hwndLookIn)); BOOL fEnable = fScopes; UINT uEnable = fScopes ? MF_ENABLED:MF_GRAYED; HMENU hMenu = GetMenu(_hwnd); INT i;
TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::DoEnableControls");
EnableWindow(_hwndFindNow, !_fQueryRunning && fEnable); EnableWindow(_hwndStop, _fQueryRunning && fEnable); EnableWindow(_hwndNewQuery, fEnable);
EnableWindow(_hwndLookFor, !_fQueryRunning && fEnable); EnableWindow(_hwndLookIn, !_fQueryRunning && fEnable); EnableWindow(_hwndBrowse, !_fQueryRunning && fEnable);
if (_pCurrentForm) { CallFormPages(_pCurrentForm, CQPM_ENABLE, (BOOL)(!_fQueryRunning && fEnable), 0);
if (_fFormFirstEnable) { PostMessage(_hwnd, CQFWM_SETDEFAULTFOCUS, 0, 0); _fFormFirstEnable = FALSE; } }
if (_hwndOK) EnableWindow(_hwndOK, !_fQueryRunning && fEnable); if (_hwndCancel) EnableWindow(_hwndCancel, !_fQueryRunning && fEnable);
for (i = 0 ; i < GetMenuItemCount(hMenu) ; i++) EnableMenuItem(hMenu, i, MF_BYPOSITION|uEnable);
DrawMenuBar(_hwnd);
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnNotify / --------------------- / Notify event received, decode it and handle accordingly / / In: / idCtrl = ID of control issuing notify / pNotify -> LPNMHDR structure / / Out: / LRESULT /----------------------------------------------------------------------------*/ LRESULT CQueryFrame::OnNotify(INT idCtrl, LPNMHDR pNotify) { LRESULT lr = 0;
TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnNotify");
// TCN_SELCHANGE used to indicate that the currently active
// tab has been changed
if (pNotify->code == TCN_SELCHANGE) { INT iPage = TabCtrl_GetCurSel(_hwndFrame); TraceAssert(iPage >= 0);
if (iPage >= 0) { SelectFormPage(_pCurrentForm, iPage); lr = 0; } }
TraceLeaveResult((HRESULT)lr); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnSize / ------------------- / The window is being sized and we received a WM_SIZE, therefore move / the content of the window about. / / In: / cx = new width / cy = new height / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::OnSize(INT cx, INT cy) { HDWP hdwp; RECT rect, rect2; SIZE sz, sz2; INT x, cxForm, cyForm; INT dyResultsTop = 0; INT frameBottom = 0;
TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnSize");
// do as much as we can within a DefWindowPos to aVOID too
// much flicker.
hdwp = BeginDeferWindowPos(16);
if (hdwp) { { // adjust the look for controls, if there is no scope then
// stretch the look for control over the entire client area
// of the window.
if (!(_pOpenQueryWnd->dwFlags & OQWF_REMOVEFORMS)) { if (_pOpenQueryWnd->dwFlags & OQWF_REMOVESCOPES) { GetRealWindowInfo(_hwndLookFor, &rect, &sz); if (hdwp) { hdwp = DeferWindowPos(hdwp, _hwndLookFor, NULL, 0, 0, (cx - _dxFormAreaRight) - rect.left, sz.cy, SWP_NOZORDER|SWP_NOMOVE); } } }
// adjust the "look in" controls, if there is a form control
// then stretch across the remaining space, otherwise move the
// label and stretch the scope over the remaining space.
if (!(_pOpenQueryWnd->dwFlags & OQWF_REMOVESCOPES)) { INT xScopeRight;
GetRealWindowInfo(_hwndLookIn, &rect, &sz); xScopeRight = cx - _dxFormAreaRight - _dxGap; if (_pOpenQueryWnd->dwFlags & OQWF_HIDESEARCHUI) { //
// when hiding the search UI, then adjust the button position to account for the
// right edge of the dialog not having buttons.
//
xScopeRight -= (_dxButtonsLeft - _dxFormAreaRight) + _dxGap; } if (_pOpenQueryWnd->dwFlags & OQWF_REMOVEFORMS) { GetRealWindowInfo(_hwndLookInLabel, &rect2, &sz2); if (hdwp) { hdwp = DeferWindowPos(hdwp, _hwndLookInLabel, NULL, _dxFormAreaLeft, rect2.top, 0, 0, SWP_NOSIZE|SWP_NOZORDER); } if(hdwp) {
hdwp = DeferWindowPos(hdwp, _hwndLookIn, NULL, _dxFormAreaLeft+sz2.cx, rect.top, xScopeRight - (_dxFormAreaLeft + sz2.cx), sz.cy, SWP_NOZORDER); } } else { if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndLookIn, NULL, 0, 0, xScopeRight - rect.left, sz.cy, SWP_NOZORDER|SWP_NOMOVE); } }
// browse control is displayed always if we are showing the
// scopes.
GetRealWindowInfo(_hwndBrowse, &rect, NULL); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndBrowse, NULL, xScopeRight+_dxGap, rect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE); } } // all the buttons have a fixed offset from the right edege
// of the dialog, so just handle that as we can.
if (!(_pOpenQueryWnd->dwFlags & OQWF_HIDESEARCHUI)) { GetRealWindowInfo(_hwndFindNow, &rect, NULL); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndFindNow, NULL, (cx - _dxButtonsLeft), rect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE); }
GetRealWindowInfo(_hwndStop, &rect, &sz); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndStop, NULL, (cx - _dxButtonsLeft), rect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE); }
GetRealWindowInfo(_hwndNewQuery, &rect, NULL); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndNewQuery, NULL, (cx - _dxButtonsLeft), rect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE); } GetRealWindowInfo(_hwndFindAnimation, &rect2, &sz2); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndFindAnimation, NULL, (cx - _dxAnimationLeft), rect2.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE); } }
// position the form "frame" control
GetRealWindowInfo(_hwndFrame, &rect, &sz); cxForm = (cx - _dxFormAreaRight) - rect.left;
if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndFrame, NULL, 0, 0, cxForm, _szForm.cy, SWP_NOZORDER|SWP_NOMOVE); }
dyResultsTop = _dyResultsTop;
// NOTICE-NTRAID#NTBUG9-577850-2002/05/21-artm
// Layout did not give enough vertical room to the result label.
// In FE localized builds it was clipped when the window was
// repainted. _dyResultsTop does not take into account space
// needed between frame bottom and the top of the result label.
// Store the bottom of the frame for later calculation.
frameBottom = rect.bottom; // when we have a cancel button then ensure that it is to the right
// of the OK button.
if (_hwndCancel) { GetRealWindowInfo(_hwndCancel, &rect, &sz); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndCancel, NULL, (cx - _dxButtonsLeft), dyResultsTop - _dyOKTop, 0, 0, SWP_NOZORDER|SWP_NOSIZE); }
GetRealWindowInfo(_hwndOK, &rect, &sz); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndOK, NULL, (cx - _dxButtonsLeft - _dxGap - sz.cx), dyResultsTop - _dyOKTop, 0, 0, SWP_NOZORDER|SWP_NOSIZE); } } else { GetRealWindowInfo(_hwndOK, &rect, &sz); if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndOK, NULL, (cx - _dxButtonsLeft), dyResultsTop - _dyOKTop, 0, 0, SWP_NOZORDER|SWP_NOSIZE); } } }
// move the results and status bar as required
if (_hwndResults) { if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndStatus, NULL, 0, cy - _cyStatus, cx, _cyStatus, SWP_SHOWWINDOW|SWP_NOZORDER); }
// NTRAID#NTBUG9-406927-2001/10/24-lucios
HWND resultsLabel=GetDlgItem(_hwnd,CQID_RESULTSLABEL); if(resultsLabel) { // NOTICE-NTRAID#NTBUG9-577850-2002/05/15-artm Label showing on FE builds.
// Make sure that the label is enabled now that we want to show it.
EnableWindow(resultsLabel, TRUE);
RECT rec; GetClientRect(resultsLabel,&rec); INT height=rect.bottom-rect.top;
// Include blank space above label proportional to height of label.
dyResultsTop = frameBottom + (height / 4); if(hdwp) { hdwp = DeferWindowPos(hdwp, resultsLabel, NULL, 0, dyResultsTop, cx, height, SWP_SHOWWINDOW|SWP_NOZORDER); } dyResultsTop+=height; } if(hdwp) { hdwp = DeferWindowPos(hdwp, _hwndResults, NULL, 0, dyResultsTop, cx, max(0, cy - (dyResultsTop + _cyStatus)), SWP_SHOWWINDOW|SWP_NOZORDER); } }
// NTRAID#NTBUG9-670595-2002/08/08-artm
// Need to call EndDeferWindowPos() whether or not results and status bar moved.
if(hdwp) { EndDeferWindowPos(hdwp); }
// here is the strange bit, by this point we have moved & sized all the
// controls on the dialog except the current page, as this is a child window
// and not a control which in turn has controls doing this would break
// the DefWindowPos path, therefore having updated everybody, lets update
// the page.
if (_pCurrentFormPage && _pCurrentFormPage->hwndPage) { GetRealWindowInfo(_hwndFrame, &rect, NULL); TabCtrl_AdjustRect(_hwndFrame, FALSE, &rect);
cxForm = rect.right - rect.left; cyForm = rect.bottom - rect.top;
SetWindowPos(_pCurrentFormPage->hwndPage, NULL, rect.left, rect.top, cxForm, cyForm, SWP_NOZORDER); } }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnGetMinMaxInfo / ---------------------------- / The window is being sized and we received a WM_SIZE, therefore move / the content of the window about. / / In: / lpmmin -> MINMAXINFO structure / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::OnGetMinMaxInfo(LPMINMAXINFO lpmmi) { RECT rect = {0, 0, 0, 0};
TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnGetMinMaxInfo");
#if 0
if (!_fHideSearchPane) #endif
{ lpmmi->ptMinTrackSize.x = _szMinTrack.cx; lpmmi->ptMinTrackSize.y = _szMinTrack.cy;
if (!_hwndResults) { lpmmi->ptMaxSize.y = lpmmi->ptMinTrackSize.y; lpmmi->ptMaxTrackSize.y = lpmmi->ptMinTrackSize.y; } } #if 0
else { AdjustWindowRect(&rect, GetWindowLong(_hwnd, GWL_STYLE), (NULL != GetMenu(_hwnd))); lpmmi->ptMinTrackSize.y = rect.bottom - rect.top; } #endif
if (_hwndResults && _hwndStatus) lpmmi->ptMinTrackSize.y += _cyStatus;
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnCommand / ---------------------- / We have recieved a WM_COMMAND so process it accordingly. / / In: / wParam, lParam = parameters from the message / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::OnCommand(WPARAM wParam, LPARAM lParam) { HRESULT hres; UINT uID = LOWORD(wParam); UINT uNotify = HIWORD(wParam); HWND hwndControl = (HWND)lParam; INT i; TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnCommand"); Trace(TEXT("uID %08x, uNotify %d, hwndControl %08x"), uID, uNotify, hwndControl);
switch (uID) { case IDOK: TraceMsg("IDOK received"); CloseQueryFrame(S_OK); break;
case IDCANCEL: TraceMsg("IDCANCEL received"); CloseQueryFrame(S_FALSE); break;
case CQID_LOOKFOR: { if (uNotify == CBN_SELCHANGE) { INT iSel = ComboBox_GetCurSel(_hwndLookFor); INT iForm = (int)ComboBox_GetItemData(_hwndLookFor, iSel); LPQUERYFORM pQueryForm = (LPQUERYFORM)DSA_GetItemPtr(_hdsaForms, iForm); TraceAssert(pQueryForm);
if (S_FALSE == SelectForm(pQueryForm->clsidForm)) { TraceMsg("SelectForm return S_FALSE, so the user doesn't want the new form"); PostMessage(_hwndLookFor, CB_SETCURSEL, (WPARAM)_pCurrentForm->iForm, 0); } }
break; }
case CQID_BROWSE: OnBrowse(); break;
case CQID_FINDNOW: OnFindNow(); break;
case CQID_STOP: { LONG style;
_pQueryHandler->StopQuery(); // For some reason, the standard method of getting the old
// def button used in SetDefButton() below isn't working,
// so we have to forcibly remove the BS_DEFPUSHBUTTON style
// from the CQID_STOP button.
style = GetWindowLong(_hwndStop, GWL_STYLE) & ~BS_DEFPUSHBUTTON; SendMessage(_hwndStop, BM_SETSTYLE, MAKEWPARAM(style, 0), MAKELPARAM(TRUE, 0)); SetDefButton(_hwnd, CQID_FINDNOW); SendMessage(GetParent(_hwndFindNow),WM_NEXTDLGCTL,(WPARAM)_hwndFindNow,TRUE); SetFocus(_hwndFindNow); break; }
case CQID_CLEARALL: OnNewQuery(TRUE); // discard the current query
break;
case CQID_FILE_CLOSE: TraceMsg("CQID_FILE_CLOSE received"); CloseQueryFrame(S_FALSE); break;
default: _pQueryHandler->InvokeCommand(_hwnd, uID); break; }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnInitMenu / ----------------------- / Handle telling the handler that the menu is being initialised, however / this should only happen if the menu being activated is the / menu bar, otherwise we assume that the caller is tracking a popup / menu and has performed the required initalization. / / In: / wParam, lParam = parameters from the WM_INITMENU / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::OnInitMenu(HMENU hMenu) { TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnInitMenu");
_fTrackingMenuBar = (GetMenu(_hwnd) == hMenu);
if (_fTrackingMenuBar) { TraceMsg("Tracking the menu bar, sending activate");
_pQueryHandler->ActivateView(CQRVA_INITMENUBAR, (WPARAM)hMenu, 0L);
// NTRAID#NTBUG9-630248-2002/06/12-artm
// Only enable View menu if the results list box is displayed.
EnableMenuItem( hMenu, CQID_VIEW_SEARCHPANE, MF_BYCOMMAND| ((_hwndResults != NULL) ? MF_ENABLED:MF_GRAYED) ); } TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnEnterMenuLoop / ---------------------------- / When the user displays a menu we must reflect this into the status bar / so that we can give the user help text relating to the commands they / select. / / In: / fEntering = entering the menu loop, or leaving. / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::OnEnterMenuLoop(BOOL fEntering) { TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnEnterMenuLoop");
if (_hwndStatus) { if (fEntering) { SendMessage(_hwndStatus, SB_SIMPLE, (WPARAM)TRUE, 0L); SendMessage(_hwndStatus, SB_SETTEXT, (WPARAM)SBT_NOBORDERS|255, 0L); } else { SendMessage(_hwndStatus, SB_SIMPLE, (WPARAM)FALSE, 0L); } }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnMenuSelect / ------------------------- / Get the status text for this menu item and display it to the user, / if this doesn't map to any particular command then NULL out / the string. At this point we also trap our commands. / / In: / hMenu = menu the user is on / uID = command ID for that item / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::OnMenuSelect(HMENU hMenu, UINT uID) { TCHAR szBuffer[MAX_PATH] = { TEXT('\0') };
TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnMenuSelect"); Trace(TEXT("hMenu %08x, uID %08x"), hMenu, uID); if (_hwndStatus) { switch (uID) { case CQID_FILE_CLOSE: case CQID_VIEW_SEARCHPANE: LoadString(GLOBAL_HINSTANCE, uID, szBuffer, ARRAYSIZE(szBuffer)); break;
default: _pQueryHandler->GetCommandString(uID, 0x0, szBuffer, ARRAYSIZE(szBuffer)); break; }
Trace(TEXT("Setting status bar to: %s"), szBuffer); SendMessage(_hwndStatus, SB_SETTEXT, (WPARAM)SBT_NOBORDERS|255, (LPARAM)szBuffer); }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnFindNow / ---------------------- // Issue the query, resulting in a view window being created and then issuing
// the parameter block to the query client.
/ / In: / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::OnFindNow(VOID) { HRESULT hres; CQPARAMS qp = { 0 }; LPQUERYSCOPE pQueryScope = NULL; TCHAR szBuffer[MAX_PATH]; BOOL fFixSize = TRUE; RECT rc; DECLAREWAITCURSOR; BOOL fSetCursor = FALSE;
TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnFindNow"); TraceAssert(_pCurrentForm != NULL);
if (_fQueryRunning) ExitGracefully(hres, E_FAIL, "Quyery is already running");
SetWaitCursor();
fSetCursor = TRUE;
// If we have not created the viewer before now lets do so, also at the
// same time we attempt to fix the window size to ensure that enough
// of the view is visible.
if (!_hwndResults) { if (!_hwndStatus) { _hwndStatus = CreateStatusWindow(WS_CHILD, NULL, _hwnd, IDC_STATUS); GetClientRect(_hwndStatus, &rc); _cyStatus = rc.bottom - rc.top; }
// Now construct the result viewer for us to use
hres = _pQueryHandler->CreateResultView(_hwnd, &_hwndResults); FailGracefully(hres, "Failed when creating the view object"); GetWindowRect(_hwnd, &rc); SetWindowPos(_hwnd, NULL, 0, 0, rc.right - rc.left, _szMinTrack.cy + VIEWER_DEFAULT_CY, SWP_NOZORDER|SWP_NOMOVE); }
// are we still collecting the scopes async? If so then lets wait until
// they have all arrived before we set the UI running.
if (_hdsaScopes && DSA_GetItemCount(_hdsaScopes)) { // Collect the parameters ready for starting the query, if this fails then
// there is no point us continuing.
ZeroMemory(&qp, SIZEOF(qp)); qp.cbStruct = SIZEOF(qp); //qp.dwFlags = 0x0;
qp.clsidForm = _pCurrentForm->clsidForm; // new NT5 beta 2
hres = GetSelectedScope(&pQueryScope); FailGracefully(hres, "Failed to get the scope from the LookIn control");
if (pQueryScope) { Trace(TEXT("pQueryScope %08x"), pQueryScope); qp.pQueryScope = pQueryScope->pScope; }
hres = CallFormPages(_pCurrentForm, CQPM_GETPARAMETERS, 0, (LPARAM)&qp.pQueryParameters); FailGracefully(hres, "Failed when collecting parameters from form");
if (!qp.pQueryParameters) { LoadString(GLOBAL_HINSTANCE, IDS_ERR_NOPARAMS, szBuffer, ARRAYSIZE(szBuffer)); FrameMessageBox(szBuffer, MB_ICONERROR|MB_OK); ExitGracefully(hres, E_FAIL, "Failed to issue the query, no parameters"); }
// We either already had a view, or have just created one. Either way
// we must now prepare the query for sending.
Trace(TEXT("qp.cbStruct %08x"), qp.cbStruct); Trace(TEXT("qp.dwFlags %08x"), qp.dwFlags); Trace(TEXT("qp.pQueryScope %08x"), qp.pQueryScope); Trace(TEXT("qp.pQueryParameters %08x"), qp.pQueryParameters); TraceGUID("qp.clsidForm: ", qp.clsidForm);
hres = _pQueryHandler->IssueQuery(&qp); FailGracefully(hres, "Failed in IssueQuery"); } else { // set the status text to reflect that we are initializng, otherwise it is
// left empty and looks like we have crashed.
if (LoadString(GLOBAL_HINSTANCE, IDS_INITIALIZING, szBuffer, ARRAYSIZE(szBuffer))) { SetStatusText(szBuffer); } }
hres = S_OK; // success
exit_gracefully:
if (qp.pQueryParameters) CoTaskMemFree(qp.pQueryParameters);
if (fSetCursor) ResetWaitCursor();
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnNewQuery / ----------------------- / Discard the current query, prompting the user as requierd. / / In: / fAlwaysPrompt = TRUE if we force prompting of the user / / Out: / BOOL /----------------------------------------------------------------------------*/ BOOL CQueryFrame::OnNewQuery(BOOL fAlwaysPrompt) { BOOL fQueryCleared = TRUE; TCHAR szBuffer[MAX_PATH]; RECT rc;
TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnNewQuery");
if (_hwndResults || fAlwaysPrompt) { LoadString(GLOBAL_HINSTANCE, IDS_CLEARCURRENT, szBuffer, ARRAYSIZE(szBuffer)); if (IDOK != FrameMessageBox(szBuffer, MB_ICONINFORMATION|MB_OKCANCEL)) ExitGracefully(fQueryCleared, FALSE, "Used cancled new query");
if (_pQueryHandler) _pQueryHandler->StopQuery();
CallFormPages(_pCurrentForm, CQPM_CLEARFORM, 0, 0);
if (_hwndResults) { DestroyWindow(_hwndResults); // no result view now
_hwndResults = NULL;
// NOTICE-NTRAID#NTBUG9-577850-2002/05/15-artm Label showing in FE builds.
// Hide the label so there is no chance of seeing it when result view not
// visible.
HWND resultsLabel = GetDlgItem(_hwnd, CQID_RESULTSLABEL); if (resultsLabel) { EnableWindow(resultsLabel, FALSE); ShowWindow(resultsLabel, SW_HIDE); }
DestroyWindow(_hwndStatus); // no status bar
_hwndStatus = NULL;
GetWindowRect(_hwnd, &rc); // shrink the window
SetWindowPos(_hwnd, NULL, 0, 0, rc.right - rc.left, _szMinTrack.cy, SWP_NOZORDER|SWP_NOMOVE); } }
exit_gracefully:
TraceLeaveValue(fQueryCleared); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnBrowse / --------------------- / Browse for a new scope, adding it to the list if not already present, / or selecting the previous scope. / / In: / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::OnBrowse(VOID) { HRESULT hres; LPQUERYSCOPE pQueryScope = NULL; LPCQSCOPE pScope = NULL; TraceEnter(TRACE_FRAMEDLG, "CQueryFrame::OnBrowse");
// Call the handler and get a scope allocation back, then add it to the list
// of scopes to be displayed.
hres = GetSelectedScope(&pQueryScope); FailGracefully(hres, "Failed to get the scope from the LookIn control");
Trace(TEXT("Calling BrowseForScope _hwnd %08x, pQueryScope %08x (%08x)"), _hwnd, pQueryScope, pQueryScope->pScope);
hres = _pQueryHandler->BrowseForScope(_hwnd, pQueryScope ? pQueryScope->pScope:NULL, &pScope); FailGracefully(hres, "Failed when calling BrowseForScope");
if ((hres != S_FALSE) && pScope) { hres = InsertScopeIntoList(pScope, DA_LAST, TRUE); FailGracefully(hres, "Failed when adding the scope to the control");
ComboBox_SetCurSel(_hwndLookIn, ShortFromResult(hres)); }
hres = S_OK;
exit_gracefully:
if (pScope) CoTaskMemFree(pScope);
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::OnHelp / ------------------- / Invoke the context sensitive help for the window, catch the / handler specific and page specific stuff and pass those help / requests down to the relevant objects. / / In: / pHelpInfo -> help info structure / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::OnHelp(LPHELPINFO pHelpInfo) { HRESULT hres; RECT rc; HWND hwnd = (HWND)pHelpInfo->hItemHandle;
TraceEnter(TRACE_FRAME, "CQueryFrame::OnHelp");
// We are invoking help, theroefore we need ot check to see where element
// of the window we are being invoked for. If it is the
// result view then route the message to that, if its the form then
// likewise.
//
// If we don't hit any of the extension controls then lets pass the
// help onto WinHelp and get it to display the topics we have.
if (pHelpInfo->iContextType != HELPINFO_WINDOW) ExitGracefully(hres, E_FAIL, "WM_HELP handler only copes with WINDOW objects");
if (_pCurrentFormPage->hwndPage && IsChild(_pCurrentFormPage->hwndPage, hwnd)) { // it was on the query form page, therefore let it go there, that way
// they can provide topics specific to them
TraceMsg("Invoking help on the form pane");
hres = _CallPageProc(_pCurrentFormPage, CQPM_HELP, 0, (LPARAM)pHelpInfo); FailGracefully(hres, "Failed when calling page proc to get help"); } else { // pass the help information through to the handler as an activation,
// this should really just be a new method, but this works.
TraceMsg("Invoking help on the results pane"); TraceAssert(_pQueryHandler);
hres = _pQueryHandler->ActivateView(CQRVA_HELP, 0, (LPARAM)pHelpInfo); FailGracefully(hres, "Handler WndProc returned FALSE"); }
hres = S_OK;
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ Scope helper functions /----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
/ _CallScopeProc / -------------- / Releae the given scope object, freeing the object that is referenced / and passing a CQSM_RELEASE message to it. / / In: / pQueryScope -> scope object to be called / uMsg, pVoid -> parameters for the scope / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT _CallScopeProc(LPQUERYSCOPE pQueryScope, UINT uMsg, LPVOID pVoid) { HRESULT hres;
TraceEnter(TRACE_SCOPES, "_CallScopeProc"); Trace(TEXT("pQueryScope %08x, uMsg %d, pVoid %08x"), pQueryScope, uMsg, pVoid); Trace(TEXT("(cbStruct %d, pScopeProc %08x, lParam %08x)"), pQueryScope->pScope->cbStruct, pQueryScope->pScope->pScopeProc, pQueryScope->pScope->lParam);
if (!pQueryScope) ExitGracefully(hres, S_OK, "pQueryScope == NULL");
hres = (pQueryScope->pScope->pScopeProc)(pQueryScope->pScope, uMsg, pVoid); FailGracefully(hres, "Failed calling ScopeProc");
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ _FreeScope / ---------- / Releae the given scope object, freeing the object that is referenced / and passing a CQSM_RELEASE message to it. / / In: / pQueryScope -> scope object to be released / / Out: / INT == 1 always /----------------------------------------------------------------------------*/
INT _FreeScopeCB(LPVOID pItem, LPVOID pData) { return _FreeScope((LPQUERYSCOPE)pItem); }
INT _FreeScope(LPQUERYSCOPE pQueryScope) { TraceEnter(TRACE_SCOPES, "_FreeScope"); Trace(TEXT("pQueryScope %08x, pQueryScope->pScope %08x"), pQueryScope, pQueryScope->pScope); if (pQueryScope) { _CallScopeProc(pQueryScope, CQSM_RELEASE, NULL);
if (pQueryScope->pScope) { LocalFree((HLOCAL)pQueryScope->pScope); pQueryScope->pScope = NULL; } }
TraceLeaveValue(TRUE); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::InsertScopeIntoList / -------------------------------- / Adds the given scope to the scope picker. / / In: / pQueryScope -> zcope object to be added to the view / i = index to insert the scope at / fAddToControl = add the scope the picker control / ppQueryScope -> recieves the new query scope object / = NULL / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::InsertScopeIntoList(LPCQSCOPE pScope, INT i, BOOL fAddToControl) { HRESULT hres; QUERYSCOPE qs; INT iScope;
TraceEnter(TRACE_SCOPES, "CQueryFrame::InsertScopeIntoList"); Trace(TEXT("pScope %08x, i %d, fAddToControl %d"), pScope, i, fAddToControl); if (!pScope) ExitGracefully(hres, E_INVALIDARG, "pScope == NULL, not allowed");
// if we don't have any scopes then allocate the DSA
if (!_hdsaScopes) { _hdsaScopes = DSA_Create(SIZEOF(QUERYSCOPE), 4); TraceAssert(_hdsaScopes);
if (!_hdsaScopes) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate the scope DPA"); }
// Walk the list of scopes checking to see if this one is already in
// there, if not then we can add it.
for (iScope = 0 ; iScope < DSA_GetItemCount(_hdsaScopes) ; iScope++) { LPQUERYSCOPE pQueryScope = (LPQUERYSCOPE)DSA_GetItemPtr(_hdsaScopes, iScope); TraceAssert(pQueryScope);
if (S_OK == _CallScopeProc(pQueryScope, CQSM_SCOPEEQUAL, pScope)) { hres = ResultFromShort(iScope); goto exit_gracefully; } }
// Take a copy of the scope blob passed by the caller. We copy the entire
// structure who's size is defined by cbStruct into a LocalAlloc block,
// once we have this we can then build the QUERYSCOPE structure that references
// it.
Trace(TEXT("pScope->cbStruct == %d"), pScope->cbStruct); qs.pScope = (LPCQSCOPE)LocalAlloc(LPTR, pScope->cbStruct); if (!qs.pScope) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate query scope");
Trace(TEXT("Copying structure qs.pScope %08x, pScope %08x"), qs.pScope, pScope); //REVIEWED-2002-02-25-lucios.
CopyMemory(qs.pScope, pScope, pScope->cbStruct);
//qs.pScope = NULL;
qs.iImage = -1; // no image
// We have a QUERYSCOPE, so initialize it, if that works then append it to the
// DSA before either setting the return value or appending it to the control.
_CallScopeProc(&qs, CQSM_INITIALIZE, NULL); iScope = DSA_InsertItem(_hdsaScopes, i, &qs); Trace(TEXT("iScope = %d"), iScope);
if (iScope == -1) { _FreeScope(&qs); ExitGracefully(hres, E_OUTOFMEMORY, "Failed to add scope to DSA"); }
if (fAddToControl) { LPQUERYSCOPE pQueryScope = (LPQUERYSCOPE)DSA_GetItemPtr(_hdsaScopes, iScope); TraceAssert(pQueryScope);
Trace(TEXT("Calling AddScopeToControl with %08x (%d)"), pQueryScope, iScope); hres = AddScopeToControl(pQueryScope, iScope); } else { hres = ResultFromShort(iScope); }
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::AddScopeToControl / ------------------------------ / Adds the given scope to the scope picker. / / In: / pQueryScope -> zcope object to be added to the view / i = index into view where to insert the scope / / Out: / HRESULT (== index of item added) /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::AddScopeToControl(LPQUERYSCOPE pQueryScope, INT i) { HRESULT hres; CQSCOPEDISPLAYINFO cqsdi; COMBOBOXEXITEM cbi; TCHAR szBuffer[MAX_PATH]; TCHAR szIconLocation[MAX_PATH] = { 0 }; INT item;
TraceEnter(TRACE_SCOPES, "CQueryFrame::AddScopeToControl");
if (!pQueryScope) ExitGracefully(hres, E_INVALIDARG, "No scope specified");
// Call the scope to get the display information about this
// scope before we attempt to add it.
cqsdi.cbStruct = SIZEOF(cqsdi); cqsdi.dwFlags = 0; cqsdi.pDisplayName = szBuffer; cqsdi.cchDisplayName = ARRAYSIZE(szBuffer); cqsdi.pIconLocation = szIconLocation; cqsdi.cchIconLocation = ARRAYSIZE(szIconLocation); cqsdi.iIconResID = 0; cqsdi.iIndent = 0; hres = _CallScopeProc(pQueryScope, CQSM_GETDISPLAYINFO, &cqsdi); FailGracefully(hres, "Failed to get display info for the scope");
// Now add the item to the control, if they gave as an image then
// add that to the image list (and tweak the INSERTITEM structure
// accordingly).
cbi.mask = CBEIF_TEXT|CBEIF_INDENT; cbi.iItem = i; cbi.pszText = cqsdi.pDisplayName; cbi.iIndent = cqsdi.iIndent;
Trace(TEXT("Indent is %d"), cqsdi.iIndent);
if (szIconLocation[0] && cqsdi.iIconResID) { INT iImage;
if (!_fScopeImageListSet) { HIMAGELIST himlSmall;
Shell_GetImageLists(NULL, &himlSmall); SendMessage(_hwndLookIn, CBEM_SETIMAGELIST, 0, (LPARAM)himlSmall);
_fScopeImageListSet = TRUE; }
cbi.mask |= CBEIF_IMAGE|CBEIF_SELECTEDIMAGE; cbi.iImage = Shell_GetCachedImageIndex(szIconLocation, cqsdi.iIconResID, 0x0);; cbi.iSelectedImage = cbi.iImage;
Trace(TEXT("Image index set to: %d"), cbi.iImage); }
item = (INT)SendMessage(_hwndLookIn, CBEM_INSERTITEM, 0, (LPARAM)&cbi);
if (item == -1) ExitGracefully(hres, E_FAIL, "Failed when inserting the scope to the list");
DoEnableControls(); // reflect button changes into UI
hres = ResultFromShort(item);
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::PopulateScopeControl / --------------------------------- / Collect the scopes that we want to display in the scope control and / then populate it. If the handler doesn't return any scopes then / we remove the control and assume that know what to do when they / don't receive a scope pointer. / / In: / - / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::PopulateScopeControl(VOID) { HRESULT hres; LPQUERYSCOPE pQueryScope; INT i; TraceEnter(TRACE_SCOPES, "CQueryFrame::PopulateScopeControl");
// Collect the scopes that we should be showing in the view, if we don't
// get any back then we disable the scope control, if we do get some then
// populate the scope control with them.
hres = _pQueryHandler->AddScopes(); _fAddScopesNYI = (hres == E_NOTIMPL);
if (hres != E_NOTIMPL) FailGracefully(hres, "Failed when calling handler to add scopes");
if (_hdsaScopes) { // We have some scopes, so now we create the image list that we can use
// for icons with scopes. Then walk through the DPA getting the scope
// to give us some display information about itself that we can
// add to the combo box.
ComboBox_SetExtendedUI(_hwndLookIn, TRUE);
for (i = 0 ; i < DSA_GetItemCount(_hdsaScopes); i++) { pQueryScope = (LPQUERYSCOPE)DSA_GetItemPtr(_hdsaScopes, i); TraceAssert(pQueryScope);
AddScopeToControl(pQueryScope, i); } } else { // we don't have any scopes after calling AddScopes, this is either
// because the ::AddScopes method is not implemented, or the
// scopes are being added async. If IssueQuery returned a success
// we assume they are coming in async and flag as such in our
// state.
if (!_fAddScopesNYI) { TraceMsg("Handler adding scopes async, so marking so"); _fScopesAddedAsync = TRUE; } }
hres = S_OK; // success
exit_gracefully:
Trace(TEXT("Default scope is index %d"), _iDefaultScope); ComboBox_SetCurSel(_hwndLookIn, _iDefaultScope);
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::GetSelectedScope / ----------------------------- / Get the selected from the the scope ComboBox, this is a reference into the / scope DSA. / / In: / ppQueryScope = receives a pointer to the new scope / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::GetSelectedScope(LPQUERYSCOPE* ppQueryScope) { HRESULT hres; COMBOBOXEXITEM cbi; INT iScope;
TraceEnter(TRACE_SCOPES, "CQueryFrame::GetSelectedScope");
*ppQueryScope = NULL;
if (_hdsaScopes) { // Get the index for the current scope, if it doesn't give a real
// index to a item in our view then barf! Otherwise look up the
// associated scope.
iScope = ComboBox_GetCurSel(_hwndLookIn); Trace(TEXT("iScope %d"), iScope);
if (iScope == -1) ExitGracefully(hres, E_FAIL, "User entered scopes not supported yet");
*ppQueryScope = (LPQUERYSCOPE)DSA_GetItemPtr(_hdsaScopes, iScope); TraceAssert(*ppQueryScope); }
hres = *ppQueryScope ? S_OK : E_FAIL;
exit_gracefully:
Trace(TEXT("Returning LPQUERYSCOPE %08x"), *ppQueryScope);
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ Form handling functions /----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
/ _FreeQueryForm / --------------- / Destroy the QUERYFORM allocation being used to describe the form in / our DPA. We ensure that we issue a CQPM_RELEASE before doing anything / / In: / pQueryForm -> query form to be destroyed / / Out: / INT == 1 always /----------------------------------------------------------------------------*/
INT _FreeQueryFormCB(LPVOID pItem, LPVOID pData) { return _FreeQueryForm((LPQUERYFORM)pItem); }
INT _FreeQueryForm(LPQUERYFORM pQueryForm) { TraceEnter(TRACE_FORMS, "_FreeQueryForm"); if (pQueryForm) { if (pQueryForm->hdsaPages) { DSA_DestroyCallback(pQueryForm->hdsaPages, _FreeQueryFormPageCB, NULL); pQueryForm->hdsaPages = NULL; }
Str_SetPtr(&pQueryForm->pTitle, NULL); if (pQueryForm->hIcon) { DestroyIcon(pQueryForm->hIcon); } }
TraceLeaveValue(TRUE); }
/*-----------------------------------------------------------------------------
/ _FreeQueryFormPage / ------------------ / Given a pointer to a query form page structure release the members that // are of interest, including calling the PAGEPROC to releasee the underlying
/ object. / / In: / pQueryFormPage -> page to be removed / / Out: / INT == 1 always /----------------------------------------------------------------------------*/
INT _FreeQueryFormPageCB(LPVOID pItem, LPVOID pData) { return _FreeQueryFormPage((LPQUERYFORMPAGE)pItem); }
INT _FreeQueryFormPage(LPQUERYFORMPAGE pQueryFormPage) { TraceEnter(TRACE_FORMS, "_FreeQueryFormPage");
if (pQueryFormPage) { _CallPageProc(pQueryFormPage, CQPM_RELEASE, 0, 0); // NB: ignore return code
if (pQueryFormPage->hwndPage) { EnableThemeDialogTexture(pQueryFormPage->hwndPage, ETDT_DISABLE);
DestroyWindow(pQueryFormPage->hwndPage); pQueryFormPage->hwndPage = NULL; }
if (pQueryFormPage->pPage) { LocalFree(pQueryFormPage->pPage); pQueryFormPage->pPage = NULL; } }
TraceLeaveValue(TRUE); }
/*-----------------------------------------------------------------------------
/ _CallPageProc / ------------- / Call the given page object thunking the arguments as required if the / page object is non-UNICODE (only if building UNICODE). / / In: / pQueryFormPage -> page object to be called / uMsg, wParam, lParam = parameters for message / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT _CallPageProc(LPQUERYFORMPAGE pQueryFormPage, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hres;
TraceEnter(TRACE_FORMS, "_CallPageProc"); Trace(TEXT("pQueryFormPage %08x, pPage %08x, uMsg %d, wParam %08x, lParam %08x"), pQueryFormPage, pQueryFormPage->pPage, uMsg, wParam, lParam);
if (!pQueryFormPage) ExitGracefully(hres, S_OK, "pQueryFormPage == NULL"); hres = (pQueryFormPage->pPage->pPageProc)(pQueryFormPage->pPage, pQueryFormPage->hwndPage, uMsg, wParam, lParam); FailGracefully(hres, "Failed calling PageProc");
// hres = S_OK;
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ Functions for adding query forms/pages /----------------------------------------------------------------------------*/
// CB to add forms to the form DSA.
HRESULT _AddFormsProc(LPARAM lParam, LPCQFORM pForm) { HRESULT hres; QUERYFORM qf = {0}; HDSA hdsaForms = (HDSA)lParam;
TraceEnter(TRACE_FORMS, "_AddFormsProc");
if (!pForm || !hdsaForms) ExitGracefully(hres, E_INVALIDARG, "Failed to add page pForm == NULL");
// Allocate and thunk as required
qf.hdsaPages = NULL; // DSA of pages
qf.dwFlags = pForm->dwFlags; // flags
qf.clsidForm = pForm->clsid; // CLSID identifier for this form
qf.pTitle = NULL; // title used for drop down / title bar
qf.hIcon = pForm->hIcon; // hIcon passed by caller
qf.iImage = -1; // image list index of icon
qf.iForm = 0; // visible index of form in control
qf.iPage = 0; // currently selected page on form
if (!Str_SetPtr(&qf.pTitle, pForm->pszTitle)) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to copy form title string");
// Allocate the DSA if one doesn't exist yet, then add in the form
// structure as required.
if (-1 == DSA_AppendItem(hdsaForms, &qf)) ExitGracefully(hres, E_FAIL, "Failed to add form to the form DSA");
hres = S_OK; // success
exit_gracefully:
if (FAILED(hres)) _FreeQueryForm(&qf);
TraceLeaveResult(hres); }
// CB to add pages to the page DSA.
HRESULT _AddPagesProc(LPARAM lParam, REFCLSID clsidForm, LPCQPAGE pPage) { HRESULT hres; QUERYFORMPAGE qfp = {0}; HDSA hdsaPages = (HDSA)lParam;
TraceEnter(TRACE_FORMS, "_AddPagesProc");
if (!pPage || !hdsaPages) ExitGracefully(hres, E_INVALIDARG, "Failed to add page pPage == NULL");
// copy the pPage structure for us to pass to the PAGEPROC later, nb: we
// use the cbStruct field to indicate the size of blob we must copy.
Trace(TEXT("pPage->cbStruct == %d"), pPage->cbStruct); qfp.pPage = (LPCQPAGE)LocalAlloc(LPTR, pPage->cbStruct); if (!qfp.pPage) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate copy of page structure");
Trace(TEXT("Copying structure qfp.pPage %08x, pPage %08x"), qfp.pPage, pPage); //REVIEWED-2002-02-25-lucios.
CopyMemory(qfp.pPage, pPage, pPage->cbStruct); // copy the page structure
//qfp.pPage = NULL;
qfp.clsidForm = clsidForm; qfp.pPageProc = pPage->pPageProc; qfp.lParam = pPage->lParam; qfp.hwndPage = NULL;
_CallPageProc(&qfp, CQPM_INITIALIZE, 0, 0); if (-1 == DSA_AppendItem(hdsaPages, &qfp)) ExitGracefully(hres, E_FAIL, "Failed to add the form to the DSA");
hres = S_OK; // succcess
exit_gracefully:
if (FAILED(hres)) _FreeQueryFormPage(&qfp);
TraceLeaveResult(hres); }
// Add forms/pages from a UNICODE IQueryForm iface
HRESULT CQueryFrame::AddFromIQueryForm(IQueryForm* pQueryForm, HKEY hKeyForm) { HRESULT hres;
TraceEnter(TRACE_FORMS, "CQueryFrame::AddFromIQueryForm");
if (!pQueryForm) ExitGracefully(hres, E_FAIL, "pQueryForm == NULL, failing");
hres = pQueryForm->Initialize(hKeyForm); FailGracefully(hres, "Failed in IQueryFormW::Initialize");
// Call the form object to add its form and then its pages
hres = pQueryForm->AddForms(_AddFormsProc, (LPARAM)_hdsaForms); if (SUCCEEDED(hres) || (hres == E_NOTIMPL)) { hres = pQueryForm->AddPages(_AddPagesProc, (LPARAM)_hdsaPages); FailGracefully(hres, "Failed in IQueryForm::AddPages"); } else { FailGracefully(hres, "Failed when calling IQueryForm::AddForms"); }
hres = S_OK; // success
exit_gracefully:
TraceLeaveResult(hres); }
#ifdef UNICODE
#define ADD_FROM_IQUERYFORM AddFromIQueryFormW
#else
#define ADD_FROM_IQUERYFORM AddFromIQueryFormA
#endif
/*-----------------------------------------------------------------------------
/ CQueryFrame::GatherForms / ------------------------ / Enumerate all the query forms for the given query handler and build / the DPA containing the list of them. Once we have done this we / can then populate the control at some more convientent moment. / / When gathering we first hit the "handler", then the "Forms" sub-key / trying to load all the InProc servers that provide forms. We build / list of hidden, never shown etc. / / In: / - / Out: / HRESULT /----------------------------------------------------------------------------*/
HRESULT _AddPageToForm(LPQUERYFORM pQueryForm, LPQUERYFORMPAGE pQueryFormPage, BOOL fClone) { HRESULT hres; QUERYFORMPAGE qfp;
TraceEnter(TRACE_FORMS, "_AddPageToForm"); TraceAssert(pQueryForm); TraceAssert(pQueryFormPage);
// ensure that we have a page DSA for this form object
if (!pQueryForm->hdsaPages) { TraceMsg("Creating a new page DSA for form"); pQueryForm->hdsaPages = DSA_Create(SIZEOF(QUERYFORMPAGE), 4);
if (!pQueryForm->hdsaPages) ExitGracefully(hres, E_OUTOFMEMORY, "*** No page DSA on form object ***"); }
if (!fClone) { // Moving this page structure to the one associated with the query form,
// therefore just ensure that the form has a DSA for pages and just
// insert an item at the header (yes, we add the pages in reverse).
Trace(TEXT("Adding page %08x to form %s"), pQueryFormPage, pQueryForm->pTitle);
if (-1 == DSA_InsertItem(pQueryForm->hdsaPages, 0, pQueryFormPage)) ExitGracefully(hres, E_FAIL, "Failed to copy page to form page DSA"); } else { LPCQPAGE pPage = pQueryFormPage->pPage;
// Copying the page structure (it must be global), therefore clone
// the QUERYFORMPAGE strucutre and the CQPAGE into a new allocation
// and insert that into the page DSA.
Trace(TEXT("Cloning page %08x to form %s"), pQueryFormPage, pQueryForm->pTitle);
CopyMemory(&qfp, pQueryFormPage, SIZEOF(QUERYFORMPAGE)); qfp.pPage = (LPCQPAGE)LocalAlloc(LPTR, pPage->cbStruct);
if (!qfp.pPage) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to allocate copy of page structure");
Trace(TEXT("Copying structure qfp.pPage %08x, pPage %08x"), qfp.pPage, pPage); //REVIEWED-2002-02-25-lucios.
CopyMemory(qfp.pPage, pPage, pPage->cbStruct); // copy the page structure
_CallPageProc(&qfp, CQPM_INITIALIZE, 0, 0); if (-1 == DSA_AppendItem(pQueryForm->hdsaPages, &qfp)) { _FreeQueryFormPage(&qfp); ExitGracefully(hres, E_FAIL, "Failed to copy page to form DSA"); } }
hres = S_OK; // success
exit_gracefully:
TraceLeaveResult(hres); }
HRESULT CQueryFrame::GatherForms(VOID) { HRESULT hres; IQueryForm* pQueryFormA = NULL; HKEY hKeyForms = NULL; TCHAR szBuffer[MAX_PATH]; INT i, iPage, iForm; RECT rect; TC_ITEM tci;
TraceEnter(TRACE_FORMS, "CQueryFrame::GatherForms");
// Construct DSA's so we can store the forms and pages as required.
_hdsaForms = DSA_Create(SIZEOF(QUERYFORM), 4); _hdsaPages = DSA_Create(SIZEOF(QUERYFORMPAGE), 4);
if (!_hdsaForms || !_hdsaPages) ExitGracefully(hres, E_OUTOFMEMORY, "Failed to create DSA's for storing pages/forms");
// First check the IQueryHandler to see if it supports IQueryForm, if it does
// then call it to add its objects. Note that we don't bother with ANSI/UNICODE
// at this point as the handler is assumed to be built the same the
// the query framework.
if (SUCCEEDED(_pQueryHandler->QueryInterface(IID_IQueryForm, (LPVOID*)&pQueryFormA))) { hres = AddFromIQueryForm(pQueryFormA, NULL); FailGracefully(hres, "Failed when calling AddFromIQueryForm on handlers IQueryForm iface)"); }
// now attempt to build the list of forms and pages from the registered form
// extensions. These are declared under the handlers CLSID in the registry,
// under the sub-key "Forms".
if (ERROR_SUCCESS != RegOpenKeyEx(_hkHandler, c_szForms, NULL, KEY_READ, &hKeyForms)) { TraceMsg("No 'Forms' sub-key found, therefore skipping"); } else { // Enumerate all the keys in the "Forms" key, these are assumed to be a list of
// the form handlers.
for (i = 0 ; TRUE ; i++) { DWORD cchStruct = ARRAYSIZE(szBuffer); if (ERROR_SUCCESS != RegEnumKeyEx(hKeyForms, i, szBuffer, &cchStruct, NULL, NULL, NULL, NULL)) { TraceMsg("RegEnumKeyEx return's false, therefore stopping eunmeration"); break; }
GetForms(hKeyForms, szBuffer); } }
// Now tally the form/page information together and remove duplicates and attach the pages
// to forms, take special note of the global pages. As all forms will now be in the
// DSA we can check for a zero count and we don't have to worry about the order
// in which the the forms and pages were added.
if (!DSA_GetItemCount(_hdsaForms) || !DSA_GetItemCount(_hdsaPages)) ExitGracefully(hres, E_FAIL, "Either the forms or pages DSA is empty"); for (iPage = DSA_GetItemCount(_hdsaPages) ; --iPage >= 0 ;) { LPQUERYFORMPAGE pQueryFormPage = (LPQUERYFORMPAGE)DSA_GetItemPtr(_hdsaPages, iPage); TraceAssert(pQueryFormPage);
Trace(TEXT("iPage %d (of %d)"), iPage, DSA_GetItemCount(_hdsaPages));
if (!(pQueryFormPage->pPage->dwFlags & CQPF_ISGLOBAL)) { LPQUERYFORM pQueryFormB = FindQueryForm(pQueryFormPage->clsidForm); TraceAssert(pQueryFormB);
TraceGUID("Adding page to form:", pQueryFormPage->clsidForm);
if (pQueryFormB) { hres = _AddPageToForm(pQueryFormB, pQueryFormPage, FALSE); FailGracefully(hres, "Failed when adding page to form");
if (!DSA_DeleteItem(_hdsaPages, iPage)) TraceMsg("**** Failed to remove page from global DSA ****"); } } }
for (iPage = DSA_GetItemCount(_hdsaPages) ; --iPage >= 0 ;) { LPQUERYFORMPAGE pQueryFormPage = (LPQUERYFORMPAGE)DSA_GetItemPtr(_hdsaPages, iPage); TraceAssert(pQueryFormPage);
if ((pQueryFormPage->pPage->dwFlags & CQPF_ISGLOBAL)) { Trace(TEXT("Adding global page to %d forms"), DSA_GetItemCount(_hdsaForms));
for (iForm = 0 ; iForm < DSA_GetItemCount(_hdsaForms); iForm++) { LPQUERYFORM pQueryFormC = (LPQUERYFORM)DSA_GetItemPtr(_hdsaForms, iForm); TraceAssert(pQueryFormC);
if (!(pQueryFormC->dwFlags & CQFF_NOGLOBALPAGES)) { hres = _AddPageToForm(pQueryFormC, pQueryFormPage, TRUE); FailGracefully(hres, "Failed when adding global page to form"); } }
_FreeQueryFormPage(pQueryFormPage); if (!DSA_DeleteItem(_hdsaPages, iPage)) TraceMsg("**** Failed to remove page from global DSA ****"); } }
// Walk the list of forms, rmeoving the ones which have no pages assocaited with
// them, we don't need these around confusing the world around us. Note that
// we walk backwards through the list removing.
//
// Also remove the optional forms we don't want to ehw orld to see
for (iForm = DSA_GetItemCount(_hdsaForms) ; --iForm >= 0 ;) { LPQUERYFORM pQueryFormD = (LPQUERYFORM)DSA_GetItemPtr(_hdsaForms, iForm); TraceAssert(pQueryFormD);
Trace(TEXT("pQueryForm %08x (%s), pQueryFormD->hdsaPages %08x (%d)"), pQueryFormD, pQueryFormD->pTitle, pQueryFormD->hdsaPages, pQueryFormD->hdsaPages ? DSA_GetItemCount(pQueryFormD->hdsaPages):0);
if (!pQueryFormD->hdsaPages || !DSA_GetItemCount(pQueryFormD->hdsaPages) || ((pQueryFormD->dwFlags & CQFF_ISOPTIONAL) && !(_pOpenQueryWnd->dwFlags & OQWF_SHOWOPTIONAL))) { TraceGUID("Removing form: ", pQueryFormD->clsidForm); _FreeQueryForm(pQueryFormD); DSA_DeleteItem(_hdsaForms, iForm); } }
if (!DSA_GetItemCount(_hdsaForms)) ExitGracefully(hres, E_FAIL, "!!!!! No forms registered after page/form fix ups !!!!!");
// The pages have been attached to the forms so we can now attempt to create the
// form/page objects.
_szForm.cx = 0; _szForm.cy = 0;
tci.mask = TCIF_TEXT; tci.pszText = TEXT(""); tci.cchTextMax = 0; TabCtrl_InsertItem(_hwndFrame, 0, &tci); // tabctrl needs at least one item so we can compute sizes
for (iForm = 0 ; iForm < DSA_GetItemCount(_hdsaForms); iForm++) { LPQUERYFORM pQueryFormE = (LPQUERYFORM)DSA_GetItemPtr(_hdsaForms, iForm); TraceAssert(pQueryFormE);
// Create each of the modeless page dialoges that we show to allow the user
// to edit the search criteria. We also grab the size and modify the
// form informaiton we have so that the default size of the dialog can be
// correctly computed.
for (iPage = 0 ; iPage < DSA_GetItemCount(pQueryFormE->hdsaPages); iPage++) { LPQUERYFORMPAGE pQueryFormPage = (LPQUERYFORMPAGE)DSA_GetItemPtr(pQueryFormE->hdsaPages, iPage); TraceAssert(pQueryFormPage);
pQueryFormPage->hwndPage = CreateDialogParam(pQueryFormPage->pPage->hInstance, MAKEINTRESOURCE(pQueryFormPage->pPage->idPageTemplate), _hwnd, pQueryFormPage->pPage->pDlgProc, (LPARAM)pQueryFormPage->pPage); if (!pQueryFormPage->hwndPage) ExitGracefully(hres, E_FAIL, "Failed to create query form page");
EnableThemeDialogTexture(pQueryFormPage->hwndPage, ETDT_ENABLETAB);
GetRealWindowInfo(pQueryFormPage->hwndPage, &rect, NULL); TabCtrl_AdjustRect(_hwndFrame, TRUE, &rect);
_szForm.cx = max(rect.right-rect.left, _szForm.cx); _szForm.cy = max(rect.bottom-rect.top, _szForm.cy);
// flush the form parameters
_CallPageProc(pQueryFormPage, CQPM_CLEARFORM, 0, 0);
// Call the page with CQPM_SETDEFAULTPARAMETERS with the
// OPENQUERYWINDOW structure. wParam is TRUE/FALSE indiciating if
// the form is the default one, and therefore if the pFormParam is
// valid.
_CallPageProc(pQueryFormPage, CQPM_SETDEFAULTPARAMETERS, (WPARAM)((_pOpenQueryWnd->dwFlags & OQWF_DEFAULTFORM) && IsEqualCLSID(_pOpenQueryWnd->clsidDefaultForm, pQueryFormPage->clsidForm)), (LPARAM)_pOpenQueryWnd); }
// If the form has an hIcon then lets ensure that we add that to the form image
// list, any failure here is non-fatal, in that we will just skip that forms
// icon in the list (rather than barfing)
if (pQueryFormE->hIcon) { if (!_himlForms) _himlForms = ImageList_Create(COMBOEX_IMAGE_CX, COMBOEX_IMAGE_CY, 0, 4, 1); if (_himlForms) { pQueryFormE->iImage = ImageList_AddIcon(_himlForms, pQueryFormE->hIcon); TraceAssert(pQueryFormE->iImage >= 0); }
DestroyIcon(pQueryFormE->hIcon); pQueryFormE->hIcon = NULL; } }
hres = S_OK; // success
exit_gracefully:
DoRelease(pQueryFormA);
if (hKeyForms) RegCloseKey(hKeyForms);
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::GetForms / --------------------- / Given a HKEY to the forms list and the value name for the form we want / to add, query for the form information add add the form objects / to the master list. / / In: / hKeyForms = HKEY for the {CLSID provider}\Forms key / pName -> key value to query for / / Out: / VOID /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::GetForms(HKEY hKeyForms, LPTSTR pName) { HRESULT hres; HKEY hKeyForm = NULL; TCHAR szQueryFormCLSID[GUIDSTR_MAX+1]; DWORD dwFlags; DWORD dwSize; IUnknown* pUnknown = NULL; IQueryForm* pQueryForm = NULL; CLSID clsidForm; BOOL fIncludeForms = FALSE;
TraceEnter(TRACE_FORMS, "CQueryFrame::_GetForms"); Trace(TEXT("pName %s"), pName);
if (ERROR_SUCCESS != RegOpenKeyEx(hKeyForms, pName, NULL, KEY_READ, &hKeyForm)) ExitGracefully(hres, E_UNEXPECTED, "Failed to open the form key");
// Read the flags and try to determine if we should invoke this form object.
dwSize = SIZEOF(dwFlags); if (ERROR_SUCCESS != RegQueryValueEx(hKeyForm, c_szFlags, NULL, NULL, (LPBYTE)&dwFlags, &dwSize)) { TraceMsg("No flags, defaulting to something sensible"); dwFlags = QUERYFORM_CHANGESFORMLIST; }
Trace(TEXT("Forms flag is %08x"), dwFlags);
// should be invoke this form object?
//
// - if dwFlags has QUERYFORM_CHANGESFORMSLIST, or
// - if dwFlags has QUERYFORM_CHANGESOPTFORMLIST and we are showing optional forms, or
// - neither set and the form object supports the requested form
if (!(dwFlags & QUERYFORM_CHANGESFORMLIST)) { if ((dwFlags & QUERYFORM_CHANGESOPTFORMLIST) && (_pOpenQueryWnd->dwFlags & OQWF_SHOWOPTIONAL)) { TraceMsg("Form is optional, are we are showing optional forms"); fIncludeForms = TRUE; } else { // OK, so it either didn't update the form list, or wasn't marked as optional,
// so lets check to see if it supports the form the user has requested, if not
// then don't bother loading this guy.
if (_pOpenQueryWnd->dwFlags & OQWF_DEFAULTFORM) { TCHAR szBuffer[GUIDSTR_MAX+32]; HKEY hkFormsSupported;
TraceMsg("Checking for supported form");
if (ERROR_SUCCESS == RegOpenKeyEx(hKeyForm, TEXT("Forms Supported"), NULL, KEY_READ, &hkFormsSupported)) { TraceMsg("Form has a 'Supported Forms' sub-key");
GetStringFromGUID(_pOpenQueryWnd->clsidDefaultForm, szQueryFormCLSID, ARRAYSIZE(szQueryFormCLSID)); Trace(TEXT("Checking for: %s"), szQueryFormCLSID);
if (ERROR_SUCCESS == RegQueryValueEx(hkFormsSupported, szQueryFormCLSID, NULL, NULL, NULL, NULL)) { TraceMsg("Query form is in supported list"); fIncludeForms = TRUE; }
RegCloseKey(hkFormsSupported); } else { TraceMsg("No forms supported sub-key, so loading form object anyway"); fIncludeForms = TRUE; } } } } else { TraceMsg("Form updates form list"); fIncludeForms = TRUE; }
// if fIncludeForms is TRUE, then the checks above succeeded and we are including forms
// from this object (identified by pName), so we must now get the CLSID of the object
// we are invoking and use its IQueryForm interface to add the forms that we want.
if (fIncludeForms) { // get the form object CLSID, having parse it, then CoCreate it adding the forms.
dwSize = SIZEOF(szQueryFormCLSID); if (ERROR_SUCCESS != RegQueryValueEx(hKeyForm, c_szCLSID, NULL, NULL, (LPBYTE)szQueryFormCLSID, &dwSize)) ExitGracefully(hres, E_UNEXPECTED, "Failed to read the CLSID of the form");
Trace(TEXT("szQueryFormCLSID: %s"), szQueryFormCLSID);
if (!GetGUIDFromString(szQueryFormCLSID, &clsidForm)) ExitGracefully(hres, E_UNEXPECTED, "Fialed to parse the string as a GUID");
// we now have the CLISD of the form object, so we must attempt to CoCreate it, we try for
// the current build type (eg UNICODE) and then fall back to ANSI if thats not supported,
// so we can support ANSI query form objects on a UNICODE platform.
hres = CoCreateInstance(clsidForm, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown); FailGracefully(hres, "Failed to CoCreate the form object");
if (SUCCEEDED(pUnknown->QueryInterface(IID_IQueryForm, (LPVOID*)&pQueryForm))) { hres = AddFromIQueryForm(pQueryForm, hKeyForm); FailGracefully(hres, "Failed when adding forms from specified IQueryForm iface"); } else { ExitGracefully(hres, E_UNEXPECTED, "Form object doesn't support IQueryForm(A/W)"); } }
hres = S_OK;
exit_gracefully:
if (hKeyForm) RegCloseKey(hKeyForm);
DoRelease(pUnknown); DoRelease(pQueryForm);
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::PopulateFormControl / --------------------------------- / Enumerate all the query forms for the given query handler and build / the DPA containing the list of them. Once we have done this we / can then populate the control at some more convientent moment. / / When gathering we first hit the "handler", then the "Forms" sub-key / trying to load all the InProc servers that provide forms. We build / list of hidden, never shown etc. / / In: / fIncludeHidden = list forms marked as hidden in control / / Out: / VOID /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::PopulateFormControl(BOOL fIncludeHidden) { HRESULT hres; COMBOBOXEXITEM cbi; INT i, iForm;
TraceEnter(TRACE_FORMS, "CQueryFrame::PopulateFormControl"); Trace(TEXT("fIncludeHidden: %d"), fIncludeHidden);
// list which forms within the control
if (!_hdsaForms) ExitGracefully(hres, E_FAIL, "No forms to list"); ComboBox_ResetContent(_hwndLookFor); // remove all items from that control
for (i = 0, iForm = 0 ; iForm < DSA_GetItemCount(_hdsaForms); iForm++) { LPQUERYFORM pQueryForm = (LPQUERYFORM)DSA_GetItemPtr(_hdsaForms, iForm); TraceAssert(pQueryForm);
// filter out those forms that are not of interest to this instance of the
// dialog.
if (((pQueryForm->dwFlags & CQFF_ISOPTIONAL) && !fIncludeHidden) || (pQueryForm->dwFlags & CQFF_ISNEVERLISTED)) { Trace(TEXT("Hiding form: %s"), pQueryForm->pTitle); continue; }
// now add the form to the control, including the image if there is an image
// specified.
cbi.mask = CBEIF_TEXT|CBEIF_LPARAM; cbi.iItem = i++; cbi.pszText = pQueryForm->pTitle; cbi.cchTextMax = lstrlen(pQueryForm->pTitle); cbi.lParam = iForm;
if (pQueryForm->iImage >= 0) { Trace(TEXT("Form has an image %d"), pQueryForm->iImage);
cbi.mask |= CBEIF_IMAGE|CBEIF_SELECTEDIMAGE; cbi.iImage = pQueryForm->iImage; cbi.iSelectedImage = pQueryForm->iImage; }
pQueryForm->iForm = (int)SendMessage(_hwndLookFor, CBEM_INSERTITEM, 0, (LPARAM)&cbi);
if (pQueryForm->iForm < 0) { Trace(TEXT("Form name: %s"), pQueryForm->pTitle); ExitGracefully(hres, E_FAIL, "Failed to add the entry to the combo box"); } }
hres = S_OK;
exit_gracefully:
TraceLeaveValue(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::SelectForm / ----------------------- / Changes the current form to the one specified as an into the DPA. / / In: / iForm = form to be selected / / Out: / - /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::SelectForm(REFCLSID clsidForm) { HRESULT hres; LPQUERYFORM pQueryForm, pOldQueryForm; LPQUERYFORMPAGE pQueryFormPage; LPCQPAGE pPage; INT nCmdShow = SW_SHOW; TCHAR szBuffer[64], szTitle[MAX_PATH];; TC_ITEM tci; INT i; TraceEnter(TRACE_FORMS, "CQueryFrame::SelectForm"); pQueryForm = FindQueryForm(clsidForm); TraceAssert(pQueryForm);
if (!pQueryForm) ExitGracefully(hres, S_FALSE, "Failed to find the requested form");
// Change the currently displayed form and change the displayed
// tabs to correctly indicate this
if ((pQueryForm != _pCurrentForm)) { if (!OnNewQuery(FALSE)) // prompt the user
ExitGracefully(hres, S_FALSE, "Failed to select the new form");
TabCtrl_DeleteAllItems(_hwndFrame);
for (i = 0 ; i < DSA_GetItemCount(pQueryForm->hdsaPages) ; i++) { pQueryFormPage = (LPQUERYFORMPAGE)DSA_GetItemPtr(pQueryForm->hdsaPages, i); pPage = pQueryFormPage->pPage;
tci.mask = TCIF_TEXT; tci.pszText = pQueryForm->pTitle; tci.cchTextMax = MAX_PATH;
if (pPage->idPageName && LoadString(pPage->hInstance, pPage->idPageName, szBuffer, ARRAYSIZE(szBuffer))) { Trace(TEXT("Loaded page title string %s"), szBuffer); tci.pszText = szBuffer; }
TabCtrl_InsertItem(_hwndFrame, i, &tci); }
ComboBox_SetCurSel(_hwndLookFor, pQueryForm->iForm); _pCurrentForm = pQueryForm;
SelectFormPage(pQueryForm, pQueryForm->iPage); // Change the dialog title to reflect the new form
if (LoadString(GLOBAL_HINSTANCE, IDS_FRAMETITLE, szBuffer, ARRAYSIZE(szBuffer))) { // NTRAID#NTBUG9-554458-2002/02/20-lucios. Pending fix.
wsprintf(szTitle, szBuffer, pQueryForm->pTitle); SetWindowText(_hwnd, szTitle); }
// Tell the handler that we have changed the form, they can then use this
// new form name to modify their UI.
_pQueryHandler->ActivateView(CQRVA_FORMCHANGED, (WPARAM)lstrlen(pQueryForm->pTitle), (LPARAM)pQueryForm->pTitle); }
hres = S_OK;
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::SelectFormPage / --------------------------- / Change the currently active page of a query form to the one specified / by the index. / / In: / pQueryForm = query form to be changed / iForm = form to be selected / / Out: / - /----------------------------------------------------------------------------*/ VOID CQueryFrame::SelectFormPage(LPQUERYFORM pQueryForm, INT iPage) { LPQUERYFORMPAGE pQueryFormPage; RECT rect;
TraceEnter(TRACE_FORMS, "CQueryFrame::SelectFormPage");
pQueryFormPage = (LPQUERYFORMPAGE)DSA_GetItemPtr(pQueryForm->hdsaPages, iPage); // Have we changed the query form page? If so then display the now dialog
// hiding the previous one. We call the TabCtrl to find out where we should
// be placing this new control.
if (pQueryFormPage != _pCurrentFormPage) { // Reflect the change into the tab control
TabCtrl_SetCurSel(_hwndFrame, iPage); pQueryForm->iPage = iPage;
// Fix the size and visability of the new form
if (_pCurrentFormPage) ShowWindow(_pCurrentFormPage->hwndPage, SW_HIDE); GetRealWindowInfo(_hwndFrame, &rect, NULL); TabCtrl_AdjustRect(_hwndFrame, FALSE, &rect);
SetWindowPos(pQueryFormPage->hwndPage, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW);
_pCurrentFormPage = pQueryFormPage; }
TraceLeave(); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::CallFormPages / -------------------------- / Given a query form traverse the array of pages calling each of them / with the given message information. If any of the pages return / an error code (other than E_NOTIMPL) we bail. / / In: / pQueryForm = query form to call / uMsg, wParam, lParam = parameters for the page / / Out: / HRESULT /----------------------------------------------------------------------------*/ HRESULT CQueryFrame::CallFormPages(LPQUERYFORM pQueryForm, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hres = S_OK; INT iPage;
TraceEnter(TRACE_FORMS, "CQueryFrame::CallFormPages");
if (!pQueryForm || !pQueryForm->hdsaPages) ExitGracefully(hres, E_FAIL, "No pQueryForm || pQueryForm->hdsaPages == NULL");
Trace(TEXT("pQueryForm %08x"), pQueryForm); Trace(TEXT("uMsg %08x, wParam %08x, lParam %08x"), uMsg, wParam, lParam); Trace(TEXT("%d pages to call"), DSA_GetItemCount(pQueryForm->hdsaPages));
// Call each page in turn if it matches the filter we have been given for calling
// down. If a page returns S_FALSE or a FAILURE then we exit the loop. If the
// failure however is E_NOTIMPL then we ignore.
for (iPage = 0 ; iPage < DSA_GetItemCount(pQueryForm->hdsaPages); iPage++) { LPQUERYFORMPAGE pQueryFormPage = (LPQUERYFORMPAGE)DSA_GetItemPtr(pQueryForm->hdsaPages, iPage); TraceAssert(pQueryFormPage);
hres = _CallPageProc(pQueryFormPage, uMsg, wParam, lParam); if (FAILED(hres) && (hres != E_NOTIMPL)) { TraceMsg("PageProc returned a FAILURE"); break; } else if (hres == S_FALSE) { TraceMsg("PageProc returned S_FALSE, exiting loop"); break; } }
exit_gracefully:
TraceLeaveResult(hres); }
/*-----------------------------------------------------------------------------
/ CQueryFrame::FindQueryForm / -------------------------- / Given the CLSID for the form return a pointer to its LPQUERYFORM structure, / or NULL if not found. / / In: / clsidForm = ID of the form / / Out: / LPQUERYFORM /----------------------------------------------------------------------------*/ LPQUERYFORM CQueryFrame::FindQueryForm(REFCLSID clsidForm) { LPQUERYFORM pQueryForm = NULL; INT i;
TraceEnter(TRACE_FORMS, "CQueryFrame::FindQueryForm"); TraceGUID("Form ID", clsidForm);
for (i = 0 ; _hdsaForms && (i < DSA_GetItemCount(_hdsaForms)) ; i++) { pQueryForm = (LPQUERYFORM)DSA_GetItemPtr(_hdsaForms, i); TraceAssert(pQueryForm);
if (IsEqualCLSID(clsidForm, pQueryForm->clsidForm)) { Trace(TEXT("Form is index %d (%08x)"), i, pQueryForm); break; } }
if (!_hdsaForms || (i >= DSA_GetItemCount(_hdsaForms))) pQueryForm = NULL;
TraceLeaveValue(pQueryForm); }
|