Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

886 lines
34 KiB

  1. // finddlg.h : Declaration of the file search band dialog classes
  2. #ifndef __FSEARCH_DLGS_H__
  3. #define __FSEARCH_DLGS_H__
  4. #pragma warning(disable:4127) // conditional expression is constant
  5. #include "resource.h" // main symbols
  6. #include <shdispid.h>
  7. #include "atldisp.h"
  8. #include "ids.h"
  9. class CFileSearchBand; // top-level (band/OC) window
  10. class CBandDlg; // base class for top-level dialogs
  11. class CSearchCmdDlg; // base class for band dlgs that employ an ISearchCmdExt interface
  12. class CFindFilesDlg; // top level file system search dialog
  13. class CFindComputersDlg; // top level net search dialog
  14. class CFindPrintersDlg; // top level printer search dialog
  15. class CSubDlg; // base class for subordinate dialogs
  16. class CDateDlg; // file date subordinate dialog
  17. class CTypeDlg; // file type subordinate dialog
  18. class CSizeDlg; // file size subordinate dialog
  19. class CAdvancedDlg; // advanced options subordinate dialog
  20. interface IStringMru;
  21. // private messages posted to subdialogs
  22. #define WMU_COMBOPOPULATIONCOMPLETE (WM_USER+0x200) // (wParam: HWND of combo).
  23. #define WMU_STATECHANGE (WM_USER+0x201) //
  24. #define WMU_UPDATELAYOUT (WM_USER+0x202) // (wParam: Band layout flags (BLF_)).
  25. #define WMU_RESTORESEARCH (WM_USER+0x203) // (wParam: n/a, lParam: n/a, ret: n/a).
  26. #define WMU_BANDINFOUPDATE (WM_USER+0x204) // (wParam: NULL).
  27. #define WMU_NAMESPACERECONCILE (WM_USER+0x205) // (wParam: n/a, LPARAM: n/a).
  28. #define WMU_BANDFINISHEDDISPLAYING (WM_USER+0x306) // (wParam: NULL).
  29. // async state data
  30. typedef struct tagFSEARCHTHREADSTATE
  31. {
  32. HWND hwndCtl;
  33. int cItems;
  34. void* pvParam;
  35. ULONG Reserved;
  36. BOOL fComplete;
  37. BOOL fCancel;
  38. IUnknown* punkBand;
  39. // constructor:
  40. tagFSEARCHTHREADSTATE()
  41. : hwndCtl(NULL),
  42. cItems(0),
  43. pvParam(NULL),
  44. Reserved(0),
  45. fComplete(FALSE),
  46. fCancel(FALSE),
  47. punkBand(NULL)
  48. {}
  49. ~tagFSEARCHTHREADSTATE() { ATOMICRELEASE(punkBand); }
  50. } FSEARCHTHREADSTATE;
  51. class CSubDlg // base class for subordinate dialogs
  52. {
  53. public:
  54. CSubDlg(CFileSearchBand* pfsb) : _pfsb(pfsb), _hwnd(NULL), _pBandDlg(NULL) {}
  55. virtual ~CSubDlg() {}
  56. HWND Hwnd() const { return _hwnd; }
  57. void SetBandDlg(CBandDlg* pBandDlg) { _pBandDlg = pBandDlg; }
  58. CBandDlg* BandDlg() const { return _pBandDlg; }
  59. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd) PURE;
  60. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue) PURE;
  61. STDMETHOD (TranslateAccelerator)(MSG *pmsg);
  62. virtual int GetIdealDeskbandWidth() const { return -1;}
  63. virtual BOOL Validate() { return TRUE; }
  64. virtual void Clear() PURE;
  65. virtual void LoadSaveUIState(UINT nIDCtl, BOOL bSave) {}
  66. virtual void OnWinIniChange() {}
  67. virtual void DoDelayedInit() {} // Called after search band displayed.
  68. protected:
  69. BEGIN_MSG_MAP(CSubDlg)
  70. MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcsize)
  71. MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
  72. MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
  73. MESSAGE_HANDLER(WM_PAINT, OnPaint)
  74. MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor)
  75. MESSAGE_HANDLER(WM_SIZE, OnSize)
  76. COMMAND_CODE_HANDLER(BN_SETFOCUS, OnChildSetFocusCmd)
  77. COMMAND_CODE_HANDLER(EN_SETFOCUS, OnChildSetFocusCmd)
  78. COMMAND_CODE_HANDLER(CBN_SETFOCUS, OnChildSetFocusCmd)
  79. NOTIFY_CODE_HANDLER(NM_SETFOCUS, OnChildSetFocusNotify)
  80. COMMAND_CODE_HANDLER(BN_KILLFOCUS, OnChildKillFocusCmd)
  81. COMMAND_CODE_HANDLER(EN_KILLFOCUS, OnChildKillFocusCmd)
  82. COMMAND_CODE_HANDLER(CBN_KILLFOCUS, OnChildKillFocusCmd)
  83. NOTIFY_CODE_HANDLER(NM_KILLFOCUS, OnChildKillFocusNotify)
  84. NOTIFY_CODE_HANDLER(CBEN_ENDEDIT, OnComboExEndEdit)
  85. END_MSG_MAP()
  86. LRESULT OnNcCalcsize(UINT, WPARAM, LPARAM, BOOL&);
  87. LRESULT OnNcPaint(UINT, WPARAM, LPARAM, BOOL&);
  88. LRESULT OnEraseBkgnd(UINT, WPARAM, LPARAM, BOOL&);
  89. LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL&);
  90. LRESULT OnCtlColor(UINT, WPARAM, LPARAM, BOOL&);
  91. LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL&);
  92. LRESULT OnChildSetFocusCmd(WORD, WORD, HWND, BOOL&);
  93. LRESULT OnChildSetFocusNotify(int, LPNMHDR, BOOL&);
  94. LRESULT OnChildKillFocusCmd(WORD, WORD, HWND, BOOL&);
  95. LRESULT OnChildKillFocusNotify(int, LPNMHDR, BOOL&);
  96. LRESULT OnComboExEndEdit(int, LPNMHDR, BOOL&);
  97. void _Attach(HWND hwnd) { _hwnd = hwnd; }
  98. CFileSearchBand* _pfsb;
  99. CBandDlg* _pBandDlg;
  100. private:
  101. HWND _hwnd;
  102. };
  103. // file date subordinate dialog
  104. class CDateDlg : public CDialogImpl<CDateDlg>,
  105. public CSubDlg
  106. {
  107. public:
  108. CDateDlg(CFileSearchBand* pfsb) : CSubDlg(pfsb) {}
  109. ~CDateDlg() {}
  110. enum { IDD = DLG_FSEARCH_DATE };
  111. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd);
  112. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue);
  113. virtual BOOL Validate();
  114. virtual void Clear();
  115. protected:
  116. BEGIN_MSG_MAP(CDateDlg)
  117. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  118. MESSAGE_HANDLER(WM_SIZE, OnSize)
  119. NOTIFY_CODE_HANDLER(UDN_DELTAPOS, OnMonthDaySpin)
  120. COMMAND_CODE_HANDLER(BN_CLICKED, OnBtnClick)
  121. COMMAND_HANDLER(IDC_RECENT_MONTHS, EN_KILLFOCUS, OnMonthsKillFocus)
  122. COMMAND_HANDLER(IDC_RECENT_DAYS, EN_KILLFOCUS, OnDaysKillFocus)
  123. CHAIN_MSG_MAP(CSubDlg)
  124. END_MSG_MAP()
  125. // message handlers
  126. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  127. LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL&);
  128. LRESULT OnBtnClick(WORD,WORD,HWND,BOOL&);
  129. LRESULT OnMonthsKillFocus(WORD,WORD,HWND,BOOL&);
  130. LRESULT OnDaysKillFocus(WORD,WORD,HWND,BOOL&);
  131. LRESULT OnMonthDaySpin(int, LPNMHDR, BOOL&);
  132. // utility methods
  133. void EnableControls();
  134. };
  135. // file size subordinate dialog
  136. class CSizeDlg : public CDialogImpl<CSizeDlg>,
  137. public CSubDlg
  138. {
  139. public:
  140. CSizeDlg(CFileSearchBand* pfsb) : CSubDlg(pfsb) {}
  141. ~CSizeDlg() {}
  142. enum { IDD = DLG_FSEARCH_SIZE };
  143. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd);
  144. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue);
  145. virtual void Clear();
  146. protected:
  147. BEGIN_MSG_MAP(CSizeDlg)
  148. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  149. NOTIFY_HANDLER(IDC_FILESIZE_SPIN, UDN_DELTAPOS, OnSizeSpin)
  150. COMMAND_HANDLER(IDC_FILESIZE, EN_KILLFOCUS, OnSizeKillFocus)
  151. CHAIN_MSG_MAP(CSubDlg)
  152. END_MSG_MAP()
  153. // message handlers
  154. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  155. LRESULT OnSizeSpin(int, LPNMHDR, BOOL&);
  156. LRESULT OnSizeKillFocus(WORD,WORD,HWND,BOOL&);
  157. };
  158. // CTypeDlg - file type subordinate dialog
  159. class CTypeDlg : public CDialogImpl<CTypeDlg>,
  160. public CSubDlg
  161. {
  162. public:
  163. CTypeDlg(CFileSearchBand* pfsb);
  164. ~CTypeDlg();
  165. enum { IDD = DLG_FSEARCH_TYPE };
  166. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd);
  167. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue);
  168. virtual void Clear();
  169. virtual void OnWinIniChange();
  170. virtual void DoDelayedInit(); // Called after search band displayed.
  171. protected:
  172. BEGIN_MSG_MAP(CTypeDlg)
  173. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  174. MESSAGE_HANDLER(WM_SIZE, OnSize)
  175. MESSAGE_HANDLER(WMU_COMBOPOPULATIONCOMPLETE, OnComboPopulationComplete)
  176. MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  177. NOTIFY_HANDLER(IDC_FILE_TYPE, CBEN_DELETEITEM, OnFileTypeDeleteItem)
  178. CHAIN_MSG_MAP(CSubDlg)
  179. END_MSG_MAP()
  180. // message handlers
  181. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  182. LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL&);
  183. LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&);
  184. LRESULT OnFileTypeDeleteItem(int, LPNMHDR, BOOL&);
  185. LRESULT OnComboPopulationComplete(UINT, WPARAM, LPARAM, BOOL&);
  186. // utility methods
  187. static HRESULT AddItemNotify(ULONG, PCBXITEM, LPARAM);
  188. static DWORD FileAssocThreadProc(void* pv);
  189. static INT_PTR _FindExtension(HWND hwndCombo, TCHAR* pszExt);
  190. // data
  191. FSEARCHTHREADSTATE _threadState;
  192. TCHAR _szRestoredExt[MAX_PATH];
  193. };
  194. // CAdvancedDlg - advanced options subordinate dialog
  195. class CAdvancedDlg : public CDialogImpl<CAdvancedDlg>,
  196. public CSubDlg
  197. {
  198. public:
  199. CAdvancedDlg(CFileSearchBand* pfsb) : CSubDlg(pfsb) {}
  200. ~CAdvancedDlg() {}
  201. enum { IDD = DLG_FSEARCH_ADVANCED };
  202. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd);
  203. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue);
  204. virtual void Clear();
  205. protected:
  206. BEGIN_MSG_MAP(CAdvancedDlg)
  207. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  208. CHAIN_MSG_MAP(CSubDlg)
  209. END_MSG_MAP()
  210. // message handlers
  211. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  212. LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL&);
  213. };
  214. class COptionsDlg : public CDialogImpl<COptionsDlg>,
  215. public CSubDlg
  216. {
  217. public:
  218. COptionsDlg(CFileSearchBand* pfsb);
  219. ~COptionsDlg() {}
  220. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd);
  221. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue);
  222. STDMETHOD (TranslateAccelerator)(MSG *pmsg);
  223. virtual void LoadSaveUIState(UINT nIDCtl, BOOL bSave);
  224. virtual BOOL GetMinSize(LPSIZE pSize);
  225. virtual BOOL Validate();
  226. virtual void Clear();
  227. virtual void OnWinIniChange();
  228. void UpdateSearchCmdStateUI(DISPID dispid = 0);
  229. LONG QueryHeight(LONG cx, LONG cy);
  230. virtual HWND GetBottomItem();
  231. BOOL IsAdvancedOptionChecked(UINT nID) {
  232. return _dlgAdvanced.IsDlgButtonChecked(nID) ? TRUE : FALSE ;
  233. }
  234. void TakeFocus();
  235. void DoDelayedInit();
  236. enum { IDD = DLG_FSEARCH_OPTIONS };
  237. protected:
  238. BEGIN_MSG_MAP(COptionsDlg)
  239. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  240. MESSAGE_HANDLER(WM_SIZE, OnSize)
  241. COMMAND_CODE_HANDLER(BN_CLICKED, OnBtnClick)
  242. NOTIFY_HANDLER(IDC_INDEX_SERVER, NM_CLICK, OnIndexServerClick)
  243. NOTIFY_HANDLER(IDC_INDEX_SERVER, NM_RETURN, OnIndexServerClick)
  244. CHAIN_MSG_MAP(CSubDlg)
  245. END_MSG_MAP()
  246. // messsage handlers
  247. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  248. LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL&);
  249. LRESULT OnBtnClick(WORD,WORD,HWND,BOOL&);
  250. LRESULT OnIndexServerClick(int, LPNMHDR, BOOL&);
  251. // utility methods
  252. void LayoutControls(int cx = -1, int cy = -1);
  253. void SizeToFit(BOOL bScrollBand = FALSE);
  254. // data
  255. private:
  256. // private subdialog identifiers
  257. enum SUBDLGID
  258. {
  259. SUBDLG_DATE,
  260. SUBDLG_TYPE,
  261. SUBDLG_SIZE,
  262. SUBDLG_ADVANCED,
  263. SUBDLG_Count
  264. };
  265. // subdialog instances
  266. CDateDlg _dlgDate;
  267. CTypeDlg _dlgType;
  268. CSizeDlg _dlgSize;
  269. CAdvancedDlg _dlgAdvanced;
  270. // subdialog data definition block.
  271. typedef struct {
  272. UINT nIDCheck;
  273. CSubDlg* pDlg;
  274. SIZE sizeDlg;
  275. RECT rcCheck;
  276. RECT rcDlg;
  277. } _SUBDLG;
  278. _SUBDLG _subdlgs[SUBDLG_Count];
  279. // misc
  280. UINT _nCIStatusText;
  281. };
  282. // top level dialog base class
  283. class CBandDlg
  284. {
  285. public:
  286. CBandDlg(CFileSearchBand* pfsb);
  287. ~CBandDlg();
  288. HWND Hwnd() const { return _hwnd; }
  289. // manditory overrideables
  290. virtual HWND Create(HWND hwndParent) = 0;
  291. virtual UINT GetIconID() const = 0;
  292. virtual UINT GetCaptionID() const = 0;
  293. virtual UINT GetCaptionDivID() const = 0;
  294. STDMETHOD (TranslateAccelerator)(MSG *pmsg);
  295. virtual void RemoveToolbarTurds(int cyOffset);
  296. // optional overrideables
  297. virtual void LayoutControls(int cx = -1, int cy = -1);
  298. virtual BOOL Validate() { return TRUE; }
  299. virtual void Clear() {};
  300. virtual BOOL GetMinSize(HWND hwndOC, LPSIZE pSize) const;
  301. virtual BOOL GetIdealSize(HWND hwndOC, LPSIZE pSize) const;
  302. virtual int GetIdealDeskbandWidth() const { return -1; }
  303. virtual void SetDefaultFocus();
  304. virtual HWND GetFirstTabItem() const { return NULL; }
  305. virtual HWND GetLastTabItem() const { return NULL; }
  306. virtual BOOL GetAutoCompleteObjectForWindow(HWND hwnd, IAutoComplete2** ppac2);
  307. virtual void NavigateToResults(IWebBrowser2* pwb2) {}
  308. virtual void LoadSaveUIState(UINT nIDCtl, BOOL bSave) {}
  309. virtual HWND ShowHelp(HWND hwndOwner) { return NULL; }
  310. virtual void OnWinIniChange() {}
  311. virtual void WndPosChanging(HWND hwndOC, LPWINDOWPOS pwp);
  312. virtual void RememberFocus(HWND hwndFocus);
  313. virtual BOOL RestoreFocus();
  314. virtual void OnBandShow(BOOL bShow) {} //**band** show/hide handler
  315. virtual void OnBandDialogShow(BOOL bShow) {} //band **dialog** show/hide handler
  316. virtual HRESULT SetScope(IN VARIANT* pvarScope, BOOL bTrack = FALSE);
  317. virtual HRESULT GetScope(OUT VARIANT* pvarScope);
  318. virtual HRESULT SetQueryFile(IN VARIANT* pvarScope);
  319. virtual HRESULT GetQueryFile(OUT VARIANT* pvarScope);
  320. virtual BOOL SearchInProgress() const { return FALSE; };
  321. virtual void StopSearch() {};
  322. protected:
  323. BEGIN_MSG_MAP(CBandDlg)
  324. MESSAGE_HANDLER(WM_SIZE, OnSize)
  325. MESSAGE_HANDLER(WM_PAINT, OnPaint)
  326. MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
  327. MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColorStatic)
  328. COMMAND_CODE_HANDLER(BN_SETFOCUS, OnChildSetFocusCmd)
  329. COMMAND_CODE_HANDLER(EN_SETFOCUS, OnChildSetFocusCmd)
  330. COMMAND_CODE_HANDLER(CBN_SETFOCUS, OnChildSetFocusCmd)
  331. NOTIFY_CODE_HANDLER(NM_SETFOCUS, OnChildSetFocusNotify)
  332. COMMAND_CODE_HANDLER(BN_KILLFOCUS, OnChildKillFocusCmd)
  333. COMMAND_CODE_HANDLER(EN_KILLFOCUS, OnChildKillFocusCmd)
  334. COMMAND_CODE_HANDLER(CBN_KILLFOCUS, OnChildKillFocusCmd)
  335. NOTIFY_CODE_HANDLER(NM_KILLFOCUS, OnChildKillFocusNotify)
  336. NOTIFY_CODE_HANDLER(CBEN_ENDEDIT, OnComboExEndEdit)
  337. END_MSG_MAP()
  338. // message handlers
  339. LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL&);
  340. LRESULT OnEraseBkgnd(UINT, WPARAM, LPARAM, BOOL&);
  341. LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL&);
  342. LRESULT OnCtlColorStatic(UINT, WPARAM, LPARAM, BOOL&);
  343. LRESULT OnSearchLink(int, LPNMHDR, BOOL&);
  344. LRESULT OnEditChange(WORD, WORD, HWND, BOOL&);
  345. LRESULT OnChildSetFocusCmd(WORD, WORD, HWND, BOOL&);
  346. LRESULT OnChildSetFocusNotify(int, LPNMHDR, BOOL&);
  347. LRESULT OnChildKillFocusCmd(WORD, WORD, HWND, BOOL&);
  348. LRESULT OnChildKillFocusNotify(int, LPNMHDR, BOOL&);
  349. LRESULT OnComboExEndEdit(int, LPNMHDR, BOOL&);
  350. // utility methods:
  351. void _Attach(HWND hwnd) { _hwnd = hwnd; }
  352. void _BeautifyCaption(UINT nIDCaption, UINT nIDIcon=0, UINT nIDIconResource=0);
  353. void _LayoutCaption(UINT nIDCaption, UINT nIDIcon, UINT nIDDiv, LONG cxDlg);
  354. void _LayoutSearchLinks(UINT nIDCaption, UINT nIDDiv, BOOL bShowDiv,
  355. LONG left, LONG right, LONG yMargin, LONG& yStart,
  356. const int rgLinkIDs[], LONG cLinkIDs);
  357. CFileSearchBand* _pfsb; // master band object
  358. VARIANT _varScope0;
  359. VARIANT _varQueryFile0;
  360. HWND _hwndLastFocus;
  361. private:
  362. HWND _hwnd;
  363. };
  364. inline BOOL CBandDlg::GetMinSize(HWND hwndOC, LPSIZE pSize) const {
  365. pSize->cx = pSize->cy = 0; return TRUE;
  366. }
  367. inline BOOL CBandDlg::GetAutoCompleteObjectForWindow(HWND hwnd, IAutoComplete2** ppac2) {
  368. *ppac2 = NULL; return FALSE;
  369. }
  370. // Band dialog as searchCmdExt object wrap and event sink.
  371. class CSearchCmdDlg : public DSearchCommandEvents, public CBandDlg
  372. {
  373. public:
  374. CSearchCmdDlg(CFileSearchBand* pfsb);
  375. ~CSearchCmdDlg();
  376. // ISearchCommandExt event sink
  377. // IUnknown
  378. STDMETHOD (QueryInterface) (REFIID riid, void** ppvObject);
  379. STDMETHOD_(ULONG, AddRef)();
  380. STDMETHOD_(ULONG, Release)();
  381. // IDispatch methods
  382. STDMETHOD(GetTypeInfoCount)(UINT*) { return E_NOTIMPL;}
  383. STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) { return E_NOTIMPL;}
  384. STDMETHOD(GetIDsOfNames)(REFIID, OLECHAR**, UINT, LCID, DISPID*) { return E_NOTIMPL;}
  385. STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
  386. // CBandDlg overrides
  387. virtual HWND Create(HWND hwndParent) = 0;
  388. virtual void Clear();
  389. STDMETHOD (TranslateAccelerator)(MSG *pmsg);
  390. // CSearchCmdDlg methods
  391. ISearchCommandExt* GetSearchCmd();
  392. virtual BOOL SearchInProgress() const { return _fSearchInProgress; }
  393. BOOL SearchAborted() const { return _fSearchAborted; }
  394. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd) { return E_NOTIMPL; }
  395. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue) { return E_NOTIMPL; }
  396. HRESULT StartSearch();
  397. virtual void StopSearch();
  398. HRESULT SetQueryFile(IN VARIANT* pvarScope);
  399. HRESULT DisconnectEvents();
  400. static void EnableStartStopButton(HWND hwndBtn, BOOL bEnable);
  401. // Overrideables
  402. virtual int GetSearchType() const = 0; // ret: SCE_SEARCHFORxxx
  403. virtual HWND GetAnimation() { return NULL ; }
  404. virtual void UpdateSearchCmdStateUI(DISPID dispid = 0);
  405. virtual BOOL OnSearchCmdError(HRESULT hr, LPCTSTR pszError);
  406. virtual void UpdateStatusText();
  407. virtual void StartStopAnimation(BOOL bStart) ;
  408. virtual void RestoreSearch() {};
  409. virtual void OnBandShow(BOOL bShow) ;
  410. protected:
  411. BOOL ProcessCmdError();
  412. BEGIN_MSG_MAP(CSearchCmdDlg)
  413. MESSAGE_HANDLER(WMU_RESTORESEARCH, OnRestoreSearch)
  414. CHAIN_MSG_MAP(CBandDlg)
  415. END_MSG_MAP()
  416. // message handlers
  417. LRESULT OnRestoreSearch(UINT, WPARAM, LPARAM, BOOL&);
  418. protected:
  419. // utility methods
  420. HRESULT Execute(BOOL bStart);
  421. // data
  422. IConnectionPoint* _pcp;
  423. DWORD _dwConnection;
  424. ISearchCommandExt* _pSrchCmd;
  425. BOOL _fSearchInProgress,
  426. _fSearchAborted,
  427. _fOnDestroy;
  428. };
  429. // top level dialog for Search for Files and Folders UI
  430. class CFindFilesDlg : public CDialogImpl<CFindFilesDlg>,
  431. public CSearchCmdDlg
  432. {
  433. public:
  434. CFindFilesDlg(CFileSearchBand* pfsb);
  435. ~CFindFilesDlg();
  436. virtual HWND Create(HWND hwndParent);
  437. virtual UINT GetIconID() const { return IDC_FSEARCH_ICON; }
  438. virtual UINT GetCaptionID() const { return IDC_FSEARCH_CAPTION; }
  439. virtual UINT GetCaptionDivID() const { return IDC_FSEARCH_DIV1; }
  440. virtual void LayoutControls(int cx = -1, int cy = -1);
  441. virtual BOOL Validate();
  442. virtual void Clear();
  443. virtual BOOL GetMinSize(HWND hwndOC, LPSIZE pSize) const;
  444. virtual int GetIdealDeskbandWidth() const;
  445. virtual void NavigateToResults(IWebBrowser2* pwb2);
  446. virtual HWND ShowHelp(HWND hwndOwner);
  447. virtual HWND GetFirstTabItem() const;
  448. virtual HWND GetLastTabItem() const;
  449. virtual BOOL GetAutoCompleteObjectForWindow(HWND hwnd, IAutoComplete2** ppac2);
  450. STDMETHOD (TranslateAccelerator)(MSG *pmsg);
  451. virtual int GetSearchType() const { return SCE_SEARCHFORFILES; }
  452. virtual HWND GetAnimation() { return GetDlgItem(IDC_FSEARCH_ICON); }
  453. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd);
  454. STDMETHOD (RestoreConstraint)(const BSTR bstrName, const VARIANT* pValue);
  455. virtual void UpdateSearchCmdStateUI(DISPID eventID = 0);
  456. virtual void RestoreSearch();
  457. virtual void LoadSaveUIState(UINT nIDCtl, BOOL bSave);
  458. virtual BOOL OnSearchCmdError(HRESULT hr, LPCTSTR pszError);
  459. BOOL SetDefaultScope();
  460. virtual void OnBandShow(BOOL bShow);
  461. virtual void OnBandDialogShow(BOOL bShow);
  462. virtual HRESULT SetScope(IN VARIANT* pvarScope, BOOL bTrack = FALSE);
  463. BOOL AssignNamespace(LPCTSTR pszPath, LPCITEMIDLIST pidl, LPCTSTR pszNamespace, BOOL bPassive /*only if no current selection*/);
  464. BOOL GetMinMaxInfo(HWND hwndOC, LPMINMAXINFO pmmi);
  465. void OnWinIniChange();
  466. enum { IDD = DLG_FSEARCH_MAIN };
  467. BEGIN_MSG_MAP(CFindFilesDlg)
  468. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  469. MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
  470. MESSAGE_HANDLER(WM_TIMER, OnTimer)
  471. MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  472. MESSAGE_HANDLER(WMU_COMBOPOPULATIONCOMPLETE, OnComboPopulationComplete)
  473. MESSAGE_HANDLER(WMU_STATECHANGE, OnStateChange)
  474. MESSAGE_HANDLER(WMU_UPDATELAYOUT, OnUpdateLayout)
  475. MESSAGE_HANDLER(WMU_NAMESPACERECONCILE, OnNamespaceReconcileMsg)
  476. MESSAGE_HANDLER(WMU_BANDFINISHEDDISPLAYING, OnBandFinishedDisplaying);
  477. COMMAND_HANDLER(IDC_FILESPEC, EN_CHANGE, OnEditChange)
  478. COMMAND_HANDLER(IDC_GREPTEXT, EN_CHANGE, OnEditChange)
  479. COMMAND_HANDLER(IDC_NAMESPACE, CBN_EDITCHANGE, OnNamespaceEditChange)
  480. COMMAND_HANDLER(IDC_NAMESPACE, CBN_SELENDOK, OnNamespaceSelEndOk)
  481. COMMAND_HANDLER(IDC_NAMESPACE, CBN_SELENDCANCEL, OnNamespaceReconcileCmd)
  482. COMMAND_HANDLER(IDC_NAMESPACE, CBN_DROPDOWN, OnNamespaceReconcileCmd)
  483. COMMAND_CODE_HANDLER(BN_CLICKED, OnBtnClick);
  484. NOTIFY_HANDLER(IDC_NAMESPACE, CBEN_DELETEITEM, OnNamespaceDeleteItem)
  485. NOTIFY_HANDLER(IDC_NAMESPACE, CBEN_ENDEDIT, OnNamespaceReconcileNotify)
  486. NOTIFY_HANDLER(IDC_SEARCHLINK_OPTIONS, NM_CLICK, OnOptions)
  487. NOTIFY_HANDLER(IDC_SEARCHLINK_OPTIONS, NM_RETURN, OnOptions)
  488. NOTIFY_HANDLER(IDC_GROUPBTN_OPTIONS, NM_CLICK, OnOptions)
  489. NOTIFY_HANDLER(IDC_GROUPBTN_OPTIONS, NM_RETURN, OnOptions)
  490. NOTIFY_HANDLER(IDC_GROUPBTN_OPTIONS, GBN_QUERYBUDDYHEIGHT, OnQueryOptionsHeight)
  491. NOTIFY_HANDLER(IDC_SEARCHLINK_FILES, NM_CLICK, OnSearchLink)
  492. NOTIFY_HANDLER(IDC_SEARCHLINK_FILES, NM_RETURN, OnSearchLink)
  493. NOTIFY_HANDLER(IDC_SEARCHLINK_COMPUTERS, NM_CLICK, OnSearchLink)
  494. NOTIFY_HANDLER(IDC_SEARCHLINK_COMPUTERS, NM_RETURN, OnSearchLink)
  495. NOTIFY_HANDLER(IDC_SEARCHLINK_PRINTERS, NM_CLICK, OnSearchLink)
  496. NOTIFY_HANDLER(IDC_SEARCHLINK_PRINTERS, NM_RETURN, OnSearchLink)
  497. NOTIFY_HANDLER(IDC_SEARCHLINK_PEOPLE, NM_CLICK, OnSearchLink)
  498. NOTIFY_HANDLER(IDC_SEARCHLINK_PEOPLE, NM_RETURN, OnSearchLink)
  499. NOTIFY_HANDLER(IDC_SEARCHLINK_INTERNET, NM_CLICK, OnSearchLink)
  500. NOTIFY_HANDLER(IDC_SEARCHLINK_INTERNET, NM_RETURN, OnSearchLink)
  501. CHAIN_MSG_MAP(CSearchCmdDlg) // fall through to base class handlers
  502. END_MSG_MAP()
  503. protected:
  504. // message handlers
  505. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  506. LRESULT OnEraseBkgnd(UINT, WPARAM, LPARAM, BOOL&);
  507. LRESULT OnComboPopulationComplete(UINT, WPARAM, LPARAM, BOOL&);
  508. LRESULT OnStateChange(UINT, WPARAM, LPARAM, BOOL&);
  509. LRESULT OnTimer(UINT, WPARAM, LPARAM, BOOL&);
  510. LRESULT OnUpdateLayout(UINT, WPARAM, LPARAM, BOOL&);
  511. LRESULT OnBtnClick(WORD, WORD, HWND, BOOL&);
  512. LRESULT OnNamespaceDeleteItem(int, LPNMHDR, BOOL&);
  513. LRESULT OnNamespaceEditChange(WORD, WORD, HWND, BOOL&);
  514. LRESULT OnNamespaceSelEndOk(WORD, WORD, HWND, BOOL&);
  515. LRESULT OnNamespaceReconcileCmd(WORD, WORD, HWND, BOOL&);
  516. LRESULT OnNamespaceReconcileNotify(int, LPNMHDR, BOOL&);
  517. LRESULT OnNamespaceReconcileMsg(UINT, WPARAM, LPARAM, BOOL&);
  518. LRESULT OnOptions(int, LPNMHDR, BOOL&);
  519. LRESULT OnQueryOptionsHeight(int, LPNMHDR, BOOL&);
  520. LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&);
  521. LRESULT OnBandFinishedDisplaying(UINT, WPARAM, LPARAM, BOOL&);
  522. private:
  523. // misc utility methods
  524. void _ShowOptions(BOOL bShow = TRUE);
  525. LPARAM _GetComboData(UINT id, INT_PTR idx);
  526. // namespace scoping
  527. BOOL _SetPreassignedScope();
  528. BOOL _SetFolderScope();
  529. BOOL _SetLocalDefaultScope();
  530. void _ShowNamespaceEditImage(BOOL bShow);
  531. // ad hoc namespace handling
  532. BOOL _PathFixup(LPTSTR pszDst, LPCTSTR pszSrc);
  533. BOOL _ShouldReconcileNamespace();
  534. void _UIReconcileNamespace(BOOL bAsync = FALSE);
  535. INT_PTR _ReconcileNamespace(OPTIONAL BOOL bAsync = FALSE);
  536. INT_PTR _AddNamespace(LPCTSTR pszPath, LPCITEMIDLIST pidl, LPCTSTR pszName, BOOL bSelectItem);
  537. // namespace browsing
  538. void _BrowseAndAssignNamespace();
  539. HRESULT _BrowseForNamespace(LPTSTR pszPath, UINT cchPath, LPITEMIDLIST* ppidlRet);
  540. static int _BrowseCallback(HWND hwnd, UINT msg, LPARAM lParam, LPARAM lpData);
  541. // more namespace helpers
  542. BOOL _IsSearchableFolder(LPCITEMIDLIST pidlFolder);
  543. HRESULT _GetTargetNamespace(IEnumIDList **ppenum);
  544. IEnumIDList *_GetItems(INT_PTR i);
  545. INT_PTR _FindNamespace(LPCTSTR pszPath, LPCITEMIDLIST pidl);
  546. private:
  547. // namespace combo thread
  548. static HRESULT AddNamespaceItemNotify(ULONG, PCBXITEM, LPARAM);
  549. static DWORD NamespaceThreadProc(void *pv);
  550. // data
  551. COptionsDlg _dlgOptions;
  552. FSEARCHTHREADSTATE _threadState;
  553. TCHAR _szInitialNames[MAX_PATH], // SHGDN_NORMAL
  554. _szInitialPath[MAX_PATH]; // SHGDN_FORPARSING
  555. LPITEMIDLIST _pidlInitial; // Stores the initial PDIL
  556. TCHAR _szCurrentPath[MAX_PATH];
  557. TCHAR _szLocalDrives[MAX_URL_STRING];
  558. ULONG _dwWarningFlags; // docfind warning bits.
  559. BOOL _dwRunOnceWarningFlags;
  560. LRESULT _iCurNamespace; // combobox item index for currently selected namespace.
  561. BOOL _fDebuted, // this band dialog has been displayed before.
  562. _bScoped, // ve assigned a value to the namespace combo.
  563. _fNamespace, // TRUE if the user has been typing in the namespace combo.
  564. _fDisplayOptions; // Search Options group box is displayed
  565. IAutoComplete2* _pacGrepText; // 'Containing Text' autocomplete object
  566. IStringMru* _pmruGrepText; // 'Containing Text' mru object
  567. IAutoComplete2* _pacFileSpec; // 'Files Named' autocomplete object
  568. IStringMru* _pmruFileSpec; // 'Files Named' mru object
  569. enum {
  570. TRACKSCOPE_NONE,
  571. TRACKSCOPE_GENERAL,
  572. TRACKSCOPE_SPECIFIC,
  573. } ;
  574. ULONG _fTrackScope; // defines scope-tracking behavior. See TRACKSCOPE_xxx flags
  575. BOOL _fBandFinishedDisplaying; // TRUE if we have already resceived WMU_BANDFINISHEDDISPLAYING
  576. };
  577. inline HWND CFindFilesDlg::Create(HWND hwndParent) {
  578. return CDialogImpl<CFindFilesDlg>::Create(hwndParent);
  579. }
  580. #ifdef __PSEARCH_BANDDLG__
  581. // CFindPrintersDlg - top level dialog for Search for Printers UI
  582. class CFindPrintersDlg : public CDialogImpl<CFindPrintersDlg>,
  583. public CBandDlg
  584. {
  585. public:
  586. CFindPrintersDlg(CFileSearchBand* pfsb);
  587. ~CFindPrintersDlg();
  588. // overrides of CBandDlg
  589. virtual HWND Create(HWND hwndParent);
  590. virtual UINT GetIconID() const { return IDC_PSEARCH_ICON; }
  591. virtual UINT GetCaptionID() const { return IDC_PSEARCH_CAPTION; }
  592. virtual UINT GetCaptionDivID() const { return IDC_FSEARCH_DIV1; }
  593. virtual void LayoutControls(int cx = -1, int cy = -1);
  594. virtual BOOL Validate();
  595. virtual void Clear();
  596. virtual BOOL GetMinSize(HWND hwndOC, LPSIZE pSize) const;
  597. virtual HWND GetFirstTabItem() const;
  598. virtual HWND GetLastTabItem() const;
  599. STDMETHOD (TranslateAccelerator)(MSG *pmsg);
  600. virtual void OnWinIniChange();
  601. enum { IDD = DLG_PSEARCH };
  602. protected:
  603. BEGIN_MSG_MAP(CFindPrintersDlg)
  604. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  605. COMMAND_HANDLER(IDC_PSEARCH_NAME, EN_CHANGE, OnEditChange)
  606. COMMAND_HANDLER(IDC_PSEARCH_LOCATION, EN_CHANGE, OnEditChange)
  607. COMMAND_HANDLER(IDC_PSEARCH_MODEL, EN_CHANGE, OnEditChange)
  608. COMMAND_HANDLER(IDC_SEARCH_START, BN_CLICKED, OnSearchStartBtn)
  609. NOTIFY_HANDLER(IDC_SEARCHLINK_COMPUTERS, NM_CLICK, OnSearchLink)
  610. NOTIFY_HANDLER(IDC_SEARCHLINK_COMPUTERS, NM_RETURN, OnSearchLink)
  611. NOTIFY_HANDLER(IDC_SEARCHLINK_FILES, NM_CLICK, OnSearchLink)
  612. NOTIFY_HANDLER(IDC_SEARCHLINK_FILES, NM_RETURN, OnSearchLink)
  613. NOTIFY_HANDLER(IDC_SEARCHLINK_PEOPLE, NM_CLICK, OnSearchLink)
  614. NOTIFY_HANDLER(IDC_SEARCHLINK_PEOPLE, NM_RETURN, OnSearchLink)
  615. NOTIFY_HANDLER(IDC_SEARCHLINK_INTERNET, NM_CLICK, OnSearchLink)
  616. NOTIFY_HANDLER(IDC_SEARCHLINK_INTERNET, NM_RETURN, OnSearchLink)
  617. CHAIN_MSG_MAP(CBandDlg)
  618. END_MSG_MAP()
  619. // message handlers
  620. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  621. LRESULT OnSearchStartBtn(WORD, WORD, HWND, BOOL&);
  622. };
  623. inline HWND CFindPrintersDlg::Create(HWND hwndParent) {
  624. return CDialogImpl<CFindPrintersDlg>::Create(hwndParent);
  625. }
  626. #endif __PSEARCH_BANDDLG__
  627. // CFindComputersDlg - top level dialog for Search for Computers UI
  628. class CFindComputersDlg : public CDialogImpl<CFindComputersDlg>,
  629. public CSearchCmdDlg
  630. {
  631. public:
  632. CFindComputersDlg(CFileSearchBand* pfsb);
  633. ~CFindComputersDlg();
  634. // overrides of CBandDlg
  635. virtual HWND Create(HWND hwndParent);
  636. virtual UINT GetIconID() const { return IDC_CSEARCH_ICON; }
  637. virtual UINT GetCaptionID() const { return IDC_CSEARCH_CAPTION; }
  638. virtual UINT GetCaptionDivID() const { return IDC_FSEARCH_DIV1; }
  639. virtual void LayoutControls(int cx = -1, int cy = -1);
  640. virtual BOOL Validate();
  641. virtual void Clear();
  642. virtual BOOL GetMinSize(HWND hwndOC, LPSIZE pSize) const;
  643. virtual void NavigateToResults(IWebBrowser2* pwb2);
  644. virtual HWND ShowHelp(HWND hwndOwner);
  645. virtual HWND GetFirstTabItem() const;
  646. virtual HWND GetLastTabItem() const;
  647. virtual BOOL GetAutoCompleteObjectForWindow(HWND hwnd, IAutoComplete2** ppac2);
  648. STDMETHOD (TranslateAccelerator)(MSG *pmsg);
  649. virtual void OnWinIniChange();
  650. virtual int GetSearchType() const { return SCE_SEARCHFORCOMPUTERS; }
  651. virtual HWND GetAnimation() { return GetDlgItem(IDC_CSEARCH_ICON); }
  652. STDMETHOD (AddConstraints)(ISearchCommandExt* pSrchCmd);
  653. virtual void UpdateStatusText();
  654. virtual void RestoreSearch();
  655. enum { IDD = DLG_CSEARCH };
  656. protected:
  657. BEGIN_MSG_MAP(CFindComputersDlg)
  658. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  659. MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  660. COMMAND_HANDLER(IDC_CSEARCH_NAME, EN_CHANGE, OnEditChange)
  661. COMMAND_HANDLER(IDC_SEARCH_START, BN_CLICKED, OnSearchStartBtn)
  662. COMMAND_HANDLER(IDC_SEARCH_STOP, BN_CLICKED, OnSearchStopBtn)
  663. NOTIFY_HANDLER(IDC_SEARCHLINK_FILES, NM_CLICK, OnSearchLink)
  664. NOTIFY_HANDLER(IDC_SEARCHLINK_FILES, NM_RETURN, OnSearchLink)
  665. NOTIFY_HANDLER(IDC_SEARCHLINK_PRINTERS, NM_CLICK, OnSearchLink)
  666. NOTIFY_HANDLER(IDC_SEARCHLINK_PRINTERS, NM_RETURN, OnSearchLink)
  667. NOTIFY_HANDLER(IDC_SEARCHLINK_PEOPLE, NM_CLICK, OnSearchLink)
  668. NOTIFY_HANDLER(IDC_SEARCHLINK_PEOPLE, NM_RETURN, OnSearchLink)
  669. NOTIFY_HANDLER(IDC_SEARCHLINK_INTERNET, NM_CLICK, OnSearchLink)
  670. NOTIFY_HANDLER(IDC_SEARCHLINK_INTERNET, NM_RETURN, OnSearchLink)
  671. CHAIN_MSG_MAP(CSearchCmdDlg)
  672. END_MSG_MAP()
  673. // message handlers
  674. LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&);
  675. LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&);
  676. LRESULT OnSearchStartBtn(WORD, WORD, HWND, BOOL&);
  677. LRESULT OnSearchStopBtn(WORD, WORD, HWND, BOOL&);
  678. // data
  679. IAutoComplete2* _pacComputerName; // 'Files Named' autocomplete object
  680. IStringMru* _pmruComputerName; // 'Files Named' mru object
  681. };
  682. inline HWND CFindComputersDlg::Create(HWND hwndParent) {
  683. return CDialogImpl<CFindComputersDlg>::Create(hwndParent);
  684. }
  685. DECLARE_INTERFACE_(IStringMru, IUnknown)
  686. {
  687. // *** IStringMru specific methods ***
  688. STDMETHOD(Add)(LPCOLESTR pwszAdd) PURE;
  689. };
  690. extern const IID IID_IStringMru;
  691. class CStringMru : public IStringMru, public IEnumString
  692. {
  693. public:
  694. static HRESULT CreateInstance(HKEY hKey, LPCTSTR szSubKey, LONG cMaxStrings, BOOL bCaseSensitive,
  695. REFIID riid, void ** ppv);
  696. protected:
  697. // IUnknown
  698. virtual STDMETHODIMP_(ULONG) AddRef(void);
  699. virtual STDMETHODIMP_(ULONG) Release(void);
  700. virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  701. // IStringMru
  702. virtual STDMETHODIMP Add(LPCOLESTR pwsz); // adds or promotes a string
  703. // IEnumString
  704. virtual STDMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched);
  705. virtual STDMETHODIMP Skip(ULONG celt);
  706. virtual STDMETHODIMP Reset(void);
  707. virtual STDMETHODIMP Clone(IEnumString **ppenum) { return E_NOTIMPL; }
  708. private:
  709. CStringMru();
  710. ~CStringMru();
  711. HRESULT _Open();
  712. HRESULT _Read(OUT OPTIONAL LONG* pcRead = NULL /*count of strings read*/);
  713. HRESULT _Write(OUT OPTIONAL LONG* pcWritten = NULL /*count of strings written*/);
  714. HRESULT _Promote(LONG iString);
  715. void _Close();
  716. void _Delete();
  717. void _Clear();
  718. HKEY _hKey,
  719. _hKeyRoot;
  720. TCHAR _szSubKey[MAX_PATH];
  721. LONG _cRef;
  722. BOOL _bCaseSensitive;
  723. LONG _cMax;
  724. LONG _iString;
  725. HDPA _hdpaStrings;
  726. };
  727. // DivWindow registration
  728. #define DIVWINDOW_CLASS TEXT("DivWindow")
  729. #define DWM_FIRST (WM_USER+0x300)
  730. #define DWM_SETHEIGHT (DWM_FIRST+0) // WPARAM: height in pixels, LPARAM: n/a, ret: BOOL
  731. #define DWM_SETBKCOLOR (DWM_FIRST+1) // WPARAM: COLORREF, LPARAM: n/a, ret: BOOL
  732. //--------------------//
  733. // Helper macros
  734. #define POINTSPERRECT (sizeof(RECT)/sizeof(POINT))
  735. //---------------------//
  736. // Misc utility
  737. LONG _PixelsForDbu(HWND hwndDlg, LONG cDbu, BOOL bHorz);
  738. #endif //__FSEARCH_DLGS_H__