Leaked source code of windows server 2003
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.

380 lines
8.8 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1993-1998 Microsoft Corporation. All Rights Reserved.
  3. //
  4. // MODULE: find.cpp
  5. //
  6. // PURPOSE:
  7. //
  8. #include "pch.hxx"
  9. #include "find.h"
  10. #include "findres.h"
  11. #include "menures.h"
  12. #include "instance.h"
  13. #include "msgview.h"
  14. #include "menuutil.h"
  15. #include "finder.h"
  16. #include "shlwapip.h"
  17. // These will be handy
  18. inline _width(RECT rc) { return (rc.right - rc.left); }
  19. inline _height(RECT rc) { return (rc.bottom - rc.top); }
  20. inline UINT _GetTextLength(HWND hwnd, DWORD id) { return (UINT) SendDlgItemMessage(hwnd, id, WM_GETTEXTLENGTH, 0, 0); }
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CFindNext
  23. //
  24. CFindNext::CFindNext()
  25. {
  26. m_cRef = 1;
  27. m_hwnd = NULL;
  28. m_hwndParent = NULL;
  29. }
  30. CFindNext::~CFindNext()
  31. {
  32. Assert(!IsWindow(m_hwnd));
  33. SetDwOption(OPT_SEARCH_BODIES, m_fBodies, 0, 0);
  34. }
  35. //
  36. // FUNCTION: CFindNext::QueryInterface()
  37. //
  38. // PURPOSE: Allows caller to retrieve the various interfaces supported by
  39. // this class.
  40. //
  41. HRESULT CFindNext::QueryInterface(REFIID riid, LPVOID *ppvObj)
  42. {
  43. TraceCall("CFindNext::QueryInterface");
  44. *ppvObj = NULL;
  45. if (IsEqualIID(riid, IID_IUnknown))
  46. *ppvObj = (LPVOID) (IUnknown *) this;
  47. else if (IsEqualIID(riid, IID_IOleCommandTarget))
  48. *ppvObj = (LPVOID) (IOleCommandTarget *) this;
  49. if (*ppvObj)
  50. {
  51. AddRef();
  52. return (S_OK);
  53. }
  54. return (E_NOINTERFACE);
  55. }
  56. //
  57. // FUNCTION: CFindNext::AddRef()
  58. //
  59. // PURPOSE: Adds a reference count to this object.
  60. //
  61. ULONG CFindNext::AddRef(void)
  62. {
  63. TraceCall("CFindNext::AddRef");
  64. return ((ULONG) InterlockedIncrement((LONG *) &m_cRef));
  65. }
  66. //
  67. // FUNCTION: CFindNext::Release()
  68. //
  69. // PURPOSE: Releases a reference on this object.
  70. //
  71. ULONG CFindNext::Release(void)
  72. {
  73. TraceCall("CFindNext::Release");
  74. if (0 == InterlockedDecrement((LONG *) &m_cRef))
  75. {
  76. delete this;
  77. return 0;
  78. }
  79. return (m_cRef);
  80. }
  81. //
  82. // FUNCTION: CFindNext::Show()
  83. //
  84. // PURPOSE: Causes the dialog to be created and displayed
  85. //
  86. // PARAMETERS:
  87. // [in] hwndParent - Handle of the parent for the dialog
  88. // [out] phWnd - Returns the handle of the new dialog window
  89. //
  90. // RETURN VALUE:
  91. // HRESULT
  92. //
  93. HRESULT CFindNext::Show(HWND hwndParent, HWND *phWnd)
  94. {
  95. int iReturn;
  96. TraceCall("CFindNext::Show");
  97. if (!IsWindow(hwndParent))
  98. return (E_INVALIDARG);
  99. // Create the dialog box
  100. iReturn = (int) DialogBoxParamWrapW(g_hLocRes, MAKEINTRESOURCEW(IDD_FIND_NEXT), hwndParent,
  101. FindDlgProc, (LPARAM) this);
  102. return (iReturn ? S_OK : E_FAIL);
  103. }
  104. //
  105. // FUNCTION: CFindNext::Close()
  106. //
  107. // PURPOSE: Causes the find dialog to be closed.
  108. //
  109. HRESULT CFindNext::Close(void)
  110. {
  111. TraceCall("CFindNext::Close");
  112. if (IsWindow(m_hwnd))
  113. {
  114. EndDialog(m_hwnd, 0);
  115. m_hwnd = NULL;
  116. }
  117. return (S_OK);
  118. }
  119. //
  120. // FUNCTION: CFindNext::TranslateAccelerator()
  121. //
  122. // PURPOSE: Called by the parent to allow us to translate our own
  123. // messages.
  124. //
  125. // PARAMETERS:
  126. // LPMSG pMsg
  127. //
  128. // RETURN VALUE:
  129. // HRESULT
  130. //
  131. HRESULT CFindNext::TranslateAccelerator(LPMSG pMsg)
  132. {
  133. if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_F3))
  134. OnFindNow();
  135. else if (IsDialogMessageWrapW(m_hwnd, pMsg))
  136. return (S_OK);
  137. return (S_FALSE);
  138. }
  139. //
  140. // FUNCTION: CFindNext::GetFindString()
  141. //
  142. // PURPOSE: Get's the current search string from the dialog
  143. //
  144. // PARAMETERS:
  145. // [in, out] psz - Buffer to copy the string into
  146. // [in] cchMax - Size of psz.
  147. //
  148. HRESULT CFindNext::GetFindString(LPTSTR psz, DWORD cchMax, BOOL *pfBodies)
  149. {
  150. TraceCall("CFindNext::GetFindString");
  151. if (!psz || !cchMax || !pfBodies)
  152. return (E_INVALIDARG);
  153. // Get the current contents of the combo box
  154. m_cMRUList.EnumList(0, psz, cchMax);
  155. if (pfBodies)
  156. *pfBodies = m_fBodies;
  157. return (S_OK);
  158. }
  159. //
  160. // FUNCTION: CFindNext::FindDlgProc()
  161. //
  162. // PURPOSE: Static callback for the dialog proc. Does the work of finding
  163. // the correct this pointer and sending the messages to that
  164. // callback.
  165. //
  166. INT_PTR CALLBACK CFindNext::FindDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  167. {
  168. CFindNext *pThis;
  169. if (uMsg == WM_INITDIALOG)
  170. {
  171. SetWindowLongPtr(hwnd, DWLP_USER, lParam);
  172. pThis = (CFindNext *) lParam;
  173. }
  174. else
  175. pThis = (CFindNext *) GetWindowLongPtr(hwnd, DWLP_USER);
  176. if (pThis)
  177. return (pThis->DlgProc(hwnd, uMsg, wParam, lParam));
  178. return (FALSE);
  179. }
  180. static const HELPMAP g_rgCtxMapFindNext[] = {
  181. {IDC_FIND_HISTORY, 50300},
  182. {IDC_ALL_TEXT, 50310},
  183. {IDC_FIND_NOW, 50305},
  184. {IDC_ADVANCED, 50315},
  185. {0, 0}
  186. };
  187. INT_PTR CALLBACK CFindNext::DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  188. {
  189. LRESULT lResult;
  190. switch (uMsg)
  191. {
  192. case WM_INITDIALOG:
  193. return (BOOL) HANDLE_WM_INITDIALOG(hwnd, wParam, lParam, OnInitDialog);
  194. case WM_COMMAND:
  195. return (BOOL) HANDLE_WM_COMMAND(hwnd, wParam, lParam, OnCommand);
  196. case WM_HELP:
  197. case WM_CONTEXTMENU:
  198. return OnContextHelp(hwnd, uMsg, wParam, lParam, g_rgCtxMapFindNext);
  199. }
  200. return (FALSE);
  201. }
  202. //
  203. // FUNCTION: CFindNext::OnInitDialog()
  204. //
  205. // PURPOSE: Initializes the UI for the dialog.
  206. //
  207. // PARAMETERS:
  208. // [in] hwnd - Handle of the dialog being created
  209. // [in] hwndFocus - Handle of the control that should have focus
  210. // [in] lParam - Initialization data.
  211. //
  212. // RETURN VALUE:
  213. // Returns TRUE to let windows set the focus
  214. //
  215. BOOL CFindNext::OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
  216. {
  217. TCHAR sz[256];
  218. UINT nItem = 0;
  219. TraceCall("CFindNext::OnInitDialog");
  220. m_hwnd = hwnd;
  221. SendDlgItemMessage(hwnd, IDC_FIND_HISTORY, CB_LIMITTEXT, CCHMAX_FIND, 0);
  222. SetIntlFont(GetDlgItem(hwnd, IDC_FIND_HISTORY));
  223. m_fBodies = DwGetOption(OPT_SEARCH_BODIES);
  224. if (m_fBodies)
  225. SendDlgItemMessage(hwnd, IDC_ALL_TEXT, BM_SETCHECK, 1, 0);
  226. // Got's to load the find history
  227. m_cMRUList.CreateList(10, 0, c_szRegFindHistory);
  228. while (-1 != m_cMRUList.EnumList(nItem++, sz, ARRAYSIZE(sz)))
  229. {
  230. SendDlgItemMessage(hwnd, IDC_FIND_HISTORY, CB_ADDSTRING, 0, (LPARAM) sz);
  231. }
  232. // Disable the Find button
  233. EnableWindow(GetDlgItem(hwnd, IDC_FIND_NOW), FALSE);
  234. CenterDialog(m_hwnd);
  235. return (TRUE);
  236. }
  237. //
  238. // FUNCTION: CFindNext::OnCommand()
  239. //
  240. // PURPOSE: Handles command messages that are sent from the various
  241. // controls in the dialog.
  242. //
  243. void CFindNext::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  244. {
  245. TraceCall("CFindNext::OnCommand");
  246. switch (id)
  247. {
  248. case IDC_FIND_HISTORY:
  249. {
  250. switch (codeNotify)
  251. {
  252. case CBN_EDITCHANGE:
  253. EnableWindow(GetDlgItem(m_hwnd, IDC_FIND_NOW),
  254. _GetTextLength(m_hwnd, IDC_FIND_HISTORY));
  255. break;
  256. case CBN_SELCHANGE:
  257. EnableWindow(GetDlgItem(m_hwnd, IDC_FIND_NOW), TRUE);
  258. break;
  259. }
  260. break;
  261. }
  262. case IDC_ALL_TEXT:
  263. {
  264. m_fBodies = (BST_CHECKED == IsDlgButtonChecked(m_hwnd, IDC_ALL_TEXT));
  265. break;
  266. }
  267. case IDC_FIND_NOW:
  268. {
  269. if (codeNotify == BN_CLICKED)
  270. {
  271. OnFindNow();
  272. }
  273. break;
  274. }
  275. case IDC_ADVANCED:
  276. {
  277. if (codeNotify == BN_CLICKED)
  278. {
  279. DoFindMsg(FOLDERID_ROOT, 0);
  280. }
  281. break;
  282. }
  283. case IDCANCEL:
  284. case IDCLOSE:
  285. EndDialog(hwnd, 0);
  286. break;
  287. }
  288. }
  289. void CFindNext::OnFindNow(void)
  290. {
  291. TCHAR sz[CCHMAX_STRINGRES];
  292. int i;
  293. // Get the current string
  294. GetWindowText(GetDlgItem(m_hwnd, IDC_FIND_HISTORY), sz, ARRAYSIZE(sz));
  295. // Add this string to our history
  296. i = m_cMRUList.AddString(sz);
  297. // Reload the combo box
  298. UINT nItem = 0;
  299. HWND hwndCombo = GetDlgItem(m_hwnd, IDC_FIND_HISTORY);
  300. SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
  301. while (-1 != m_cMRUList.EnumList(nItem++, sz, ARRAYSIZE(sz)))
  302. {
  303. SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) sz);
  304. }
  305. SendMessage(hwndCombo, CB_SETCURSEL, 0, 0);
  306. EndDialog(m_hwnd, 1);
  307. }