www.pudn.com > testeditsrch.zip > EditSearch.cpp


//////////////////////////////////////////////////////////////// 
// If this code works, it was written by Paul DiLascia. 
// If not, I don't know who wrote it. 
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably NT too. 
// 
#include "stdafx.h" 
#include "resource.h" 
#include "EditSearch.h" 
#include "NonClient.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
IMPLEMENT_DYNAMIC(CEditSearch, CEdit) 
BEGIN_MESSAGE_MAP(CEditSearch, CEdit) 
	ON_WM_CREATE() 
	ON_WM_CONTEXTMENU() 
	ON_WM_GETDLGCODE() 
	ON_WM_CHAR() 
	ON_UPDATE_COMMAND_UI(ID_EDIT_CUT,	OnUpdateCut) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_COPY,	OnUpdateCopy) 
	ON_COMMAND(ID_EDIT_CUT,		 OnEditCut) 
	ON_COMMAND(ID_EDIT_COPY,	 OnEditCopy) 
	ON_COMMAND(ID_EDIT_PASTE,	 OnEditPaste) 
	ON_COMMAND(ID_EDIT_CONFIGURE,OnConfigure) 
 
	ON_COMMAND_RANGE(ID_FIRST_SEARCHSTRING, 
		ID_FIRST_SEARCHSTRING+MAXNUMSEARCHSTRINGS, OnSetSearch) 
	ON_UPDATE_COMMAND_UI_RANGE(ID_FIRST_SEARCHSTRING, 
		ID_FIRST_SEARCHSTRING+MAXNUMSEARCHSTRINGS, OnUpdateSearchItem) 
END_MESSAGE_MAP() 
 
// registry entries for various settings 
LPCTSTR SEARCHKEYS = _T("AllKeys"); 
LPCTSTR CURRENT    = _T("Current"); 
LPCTSTR SRCHTAG	 = _T("MYSEARCH"); 
 
////////////////// 
// construct: load profile or defaults 
// 
CEditSearch::CEditSearch(LPCTSTR pszRegKey) : m_sRegKey(pszRegKey) 
{ 
	if (!LoadProfile()) 
		LoadDefaults(); 
} 
 
///////////////// 
// destroy: save search strings 
// 
CEditSearch::~CEditSearch() 
{ 
} 
 
///////////////// 
// load builtin search strings 
// 
UINT CEditSearch::LoadDefaults() 
{ 
	static struct { 
		LPCTSTR name; 
		LPCTSTR search; 
	} StdSearchStrings[] = { 
		{ _T("Google"), 
_T("http://www.google.com/search?q=MYSEARCH&ie=UTF8&oe=UTF8&hl=zh-CN&btnG=Google%E6%90%9C%E7%B4%A2&lr=") }, 
		{ _T("新浪"), 
_T("http://webpage.sina.com.cn/cgi-bin/webpage/webpage.cgi?word=MYSEARCH&sk=0") }, 
		{ _T("ChinaRen"), 
_T("http://search.chinaren.com/baidu?tn=chinaren&si=gi&ct=0&cl=2&word=MYSEARCH&x=26&y=11") }, 
		{ _T("搜狐"), 
_T("http://searchpages.sohu.com/Sbaidu?tn=sohu1&si=gi&word=MYSEARCH&ct=0&cl=2&lm=0") }, 
		{ _T("网易"), 
_T("http://search.163.com/cgi-bin/search/engine/search2.fcgi?lang=all&key=MYSEARCH") }, 
		{ _T("中文雅虎"), 
_T("http://cn.google.yahoo.com/bin/query_cn?p=MYSEARCH&u=B&y=y&hc=0&hs=0") }, 
		{ _T("搜索客"), 
_T("http://www.cseek.com/cgi/srchengine.cgi?searchkey=MYSEARCH") }, 
		{ _T("&Altavista"), 
_T("http://www.altavista.com/cgi-bin/query?pg=q&kl=XX&stype=stext&q=MYSEARCH") }, 
		{ _T("E&xcite"), 
_T("http://search.excite.com/search.gw?search=MYSEARCH") }, 
		{ _T("&Hotbot"),  
_T("http://www.hotbot.com/?MT=MYSEARCH&SM=MC&DV=0&LG=any&DC=10&DE=2&_v=2&OPs=MDRTP") }, 
		{ _T("&Infoseek"), 
_T("http://infoseek.go.com/Titles?qt=MYSEARCH&col=WW&sv=IS&lk=noframes") }, 
		{ _T("&Lycos"), 
_T("http://www.lycos.com/cgi-bin/pursuit?matchmode=and&cat=lycos&query=MYSEARCH") }, 
		{ _T("&Yahoo"), 
_T("http://search.yahoo.com/search?p=MYSEARCH&n=25") } 
	}; 
	const NUMDEFAULTS=sizeof(StdSearchStrings)/sizeof(StdSearchStrings[0]); 
 
	for (int i=0; iGetProfileString(pszRegKey, SEARCHKEYS); 
	for (int i=0; iGetProfileString(pszRegKey, key); 
		keys = keys.Right(keys.GetLength()-iKey-1); 
	} 
	m_iCurrentSearchString = pApp->GetProfileInt(pszRegKey,CURRENT,0); 
	return m_nSearchStrings = i; 
} 
 
////////////////// 
// save search strings in registry key 
// 
void CEditSearch::SaveProfile() 
{ 
	if (m_sRegKey.IsEmpty()) 
		return; 
	LPCTSTR pszRegKey=m_sRegKey; 
 
	CWinApp* pApp = AfxGetApp(); 
	ASSERT_VALID(pApp); 
	CString allkeys; 
	for (int i=0; iWriteProfileString(pszRegKey, key, val); 
		allkeys += key + _T(";"); 
	} 
	pApp->WriteProfileString(pszRegKey, SEARCHKEYS, allkeys); 
	pApp->WriteProfileInt(pszRegKey, CURRENT, m_iCurrentSearchString); 
} 
 
//////////////// 
// Window created: load font 
// 
int CEditSearch::OnCreate(LPCREATESTRUCT lpcs) 
{ 
	if (CEdit::OnCreate(lpcs)==-1) 
		return -1; 
	CNonClientMetrics ncm; 
	m_font.CreateFontIndirect(&ncm.lfMessageFont); 
	SetFont(&m_font); 
	return 0; 
} 
 
////////////////// 
// Window destroyed: save profile. 
// 
void CEditSearch::PostNcDestroy() 
{ 
	TRACE(_T("CEditSearch::PostNcDestroy\n")); 
	SaveProfile(); 
	CEdit::PostNcDestroy(); 
} 
 
////////////////// 
// Override to implement the "select all the text when I get focus 
// from another window" feature. The first time you click the mouse 
// in the edit control, it will select all the text. If you click 
// again, it will position the cursor as usual. 
// 
LRESULT CEditSearch::WindowProc(UINT msg, WPARAM wp, LPARAM lp) 
{ 
	if (msg==WM_MOUSEACTIVATE) { 
		// don't call DefWindowProc, which will send to parent 
		SetFocus(); 
		return MA_ACTIVATE; 
	} 
 
	// do default thing 
	LRESULT lr = CEdit::WindowProc(msg, wp, lp); 
 
	if (msg==WM_SETFOCUS && (HWND)wp!=m_hWnd) { 
		// I got focus from a different window: make note 
		m_bNewlyActive = TRUE; 
	} 
	if (msg==WM_LBUTTONDOWN && m_bNewlyActive) { 
		// mouse down after newly active: select entire text 
		SetSel(0,-1); 
	} 
	if ((WM_MOUSEFIRST<=msg && msg<=WM_MOUSELAST) || 
	    (WM_KEYFIRST<=msg   && msg<=WM_KEYLAST)) { 
		// any input cancels newly active state 
		m_bNewlyActive = FALSE; 
	} 
	return lr; 
} 
 
////////////////// 
// If user presses Enter, do the search. 
// 
void CEditSearch::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{ 
	if (nChar==VK_RETURN) 
		DoSearch(); 
	else 
		CEdit::OnChar(nChar, nRepCnt, nFlags); 
} 
 
////////////////// 
// Window being created or subclassed: install WM_MENUINITPOPUP hook 
// 
void CEditSearch::PreSubclassWindow() 
{ 
	CEdit::PreSubclassWindow(); 
	m_popupInit.Install(this); 
} 
 
////////////////// 
// Convert user's string: spaces -> + sign and launch browser 
// 
void CEditSearch::DoSearch() 
{ 
	// convert whitespace to + 
	TCHAR oldstr[255]; 
	TCHAR newstr[255]; 
	int len = GetWindowText(oldstr,sizeof(oldstr)); 
	TCHAR *op, *np; 
	for (op = oldstr, np = newstr; *op; op++, np++) { 
		*np = _istspace(*op) ? _T('+') : *op; 
	} 
	*np = 0; 
 
	// replace "MYSEARCH" with users's search 
	CString url = m_arSearchStrings[m_iCurrentSearchString]; 
	int iRep = url.Find(SRCHTAG); 
	ASSERT(iRep>=0); 
	url = url.Left(iRep) + 
		newstr + 
		url.Right(url.GetLength() - iRep - _tcslen(SRCHTAG)); 
	ShellExecute(0, _T("open"), url, 0, 0, SW_SHOWNORMAL); 
} 
 
////////////////// 
// display context menu 
// 
void CEditSearch::OnContextMenu(CWnd* pWnd, CPoint pt) 
{ 
	TRACE(_T("CEditSearch::OnContextMenu\n")); 
	CMenu menu; 
	CreateSearchMenu(menu, TRUE); 
	menu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this, NULL); 
} 
	 
////////////////// 
// Append menu to existing menu 
// 
BOOL CEditSearch::CreateSearchMenu(CMenu& menu, BOOL bIncludeEditCmds) 
{ 
	if (menu) 
		menu.DestroyMenu(); 
 
	if (!menu.CreatePopupMenu()) 
		return FALSE; 
 
	static struct MYMENU { 
		UINT flags; 
		LPCTSTR name; 
		UINT id; 
	} MyItems[] = { 
		{ 0, _T("&Cut"),  ID_EDIT_CUT }, 
		{ 0, _T("&Copy"), ID_EDIT_COPY }, 
		{ 0, _T("&Paste"),ID_EDIT_PASTE }, 
		{ 0, _T("Con&figure..."),ID_EDIT_CONFIGURE }, 
		{ MF_SEPARATOR }, 
		{ -1 }, 
	}; 
 
	const NUMITEMS = sizeof(MyItems)/sizeof(MyItems[0]); 
 
	// Create menu on the fly from static data above 
	for (int i=0; im_nID - ID_FIRST_SEARCHSTRING; 
	ASSERT(0<=i && i<=ID_FIRST_SEARCHSTRING+MAXNUMSEARCHSTRINGS); 
	pCmdUI->SetCheck(i == m_iCurrentSearchString); 
} 
 
void CEditSearch::OnConfigure() 
{ 
	AfxMessageBox("OnConfigure"); 
}