© 2004 Microsoft Corporation. All rights reserved.

Figure 2 AddWindowInfo.cpp
  //////////////////
// Add window info, either top-level or edit control
//
void CMyView::AddWindowInfo(int iItem, HWND hwnd)
{
   CListCtrl& lc = GetListCtrl();
   CWnd* pWnd = CWnd::FromHandle(hwnd);
   
   int iSubitem = 1;
   // add class name
   CString s;
   ::GetClassName(hwnd, s.GetBuffer(STRINGLEN), STRINGLEN);
   lc.SetItemText(iItem,iSubitem++,s);
   // add window text — use GetWindowText
   pWnd->GetWindowText(s);
   lc.SetItemText(iItem,iSubitem++,s);
   // add window text — use WM_GETTEXT
   DWORD result;
   SendMessageTimeout(hwnd,
      WM_GETTEXT,
      STRINGLEN,
      (LPARAM)s.GetBuffer(STRINGLEN),
      0,
      1000,
      &result);
   lc.SetItemText(iItem,iSubitem++,s);
   s.ReleaseBuffer();
}

Figure 4 Translating Edit Control Keys

EditTrans.h
  ////////////////////////////////////////////////////////////////
// MSDN Magazine — August 2001
// 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 Windows 
// 2000 too.
// Set tabsize = 3 in your editor.
//
/////////////////
// Function to translate edit control "accelerators"
//
BOOL TranslateEditAccelerator(HWND hwndEdit, MSG* pMsg);

EditTrans.cpp FakePre-94724425fd5e4447be14e704b99a1f94-732ae709fdd542379117d1296763a046 Figure 5 FocusChange.cpp
  ////////////////////////////////////////////////////////////////
// In SearchBar.cpp, my CMyDeskBand
BEGIN_MESSAGE_MAP(CMyDeskBand, CBandObj)
   •••
   ON_EN_SETFOCUS(1, OnEnSetFocus)
   ON_EN_KILLFOCUS(1, OnEnKillFocus)
END_MESSAGE_MAP()
void CMyDeskBand::OnEnSetFocus()
{
   OnFocusChange(TRUE);
}
void CMyDeskBand::OnEnKillFocus()
{
   OnFocusChange(FALSE);
}
////////////////////////////////////////////////////////////////
// In CBandObj.cpp, CBandObj, the generic band object
//
void CBandObj::OnFocusChange(BOOL bFocus)
{
   if (m_spSite) {
      m_spSite->OnFocusChangeIS((IInputObject*)&m_xInputObject, bFocus);
   }
}

Figure 6 trace.txt
  // I click the mouse on the edit control in the search bar. My desk band
// calls Internet Explorer's IInputObjectSite::OnFocusChangeIS and Internet 
// Explorer AddRef's me.
//
Cbandobj::OnCmdMsg
CMyDeskBand::OnEnSetFocus
 CBandObj(00B10098)::OnFocusChange(1)
  CBandObj(00B10098)::AddRef
//
// I type the letter 'a' and a flurry of calls ensues! IE calls my
// IInputObject::HasFocusIO and TranslateAcceleratorIO several times. It
// QueryInterface's me for IInputObject every time—Why doesn't it just save
// my interface pointer?  CBandObj::IInputObject::TranslateAcceleratorIO
// calls CMyDeskBand::OnTranslateAccelerator which does nothing since 'a' 
// is not a special key.
// Note: '\a' = 97
//       '\A' = 65
//
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::HasFocusIO: YES // yes, I have focus
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_KEYDOWN, 65)...
CBandObj::OnTranslateAccelerator
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_KEYDOWN, 65)...
CBandObj::OnTranslateAccelerator
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::HasFocusIO: YES // yes, I have focus
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_CHAR, 97)...
CBandObj::OnTranslateAccelerator:
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_CHAR, 97)...
CBandObj::OnTranslateAccelerator
CBandObj(00B10098)::Release
// Finally, the 'a' goes to my edit control
CEditSearch::OnChar(97)
CBandObj::OnCmdMsg
CBandObj::OnCmdMsg
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::HasFocusIO: YES // yes, I stil have focus
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_KEYUP, 65)...CBandObj::OnTranslateAccelerator:
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_KEYUP, 65)...CBandObj::OnTranslateAccelerator:
CBandObj(00B10098)::Release
//
// Now I type 'Backspace' (VK_BACK=8) to delete the 'a'.
//
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::HasFocusIO: YES // yes, I still have 
                                                  // focus
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_KEYDOWN, 8)...
CEditSearch::OnChar(8) // My edit control gets the Backspace!
 CBandObj::OnCmdMsg
 CBandObj::OnCmdMsg
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::HasFocusIO: YES // yes, I still have 
                                                  // focus
CBandObj(00B10098)::Release
CBandObj(00B10098)::QueryInterface(IInputObject)
>CBandObj::QueryInterface returns S_OK, *ppv=00B10334
CBandObj(00B10098)::IInputObject::TranslateAcceleratorIO
CMyDeskBand::OnTranslateAccelerator(WM_KEYUP, 8)...CBandObj(00B10098)::Release
CBandObj::OnCmdMsg
//
// I click on some other app. CMyDeskBand gets the EN_KILLFOCUS and calls
// CBandObj::OnFocusChange which calls IInputSite::OnFocusChangeIS(FALSE). 
// Internet Explorer in turn calls my IInputObject::UIActivateIO(FALSE). I 
// am deactivated. :(
//
CMyDeskBand::OnEnKillFocus
 CBandObj(00B10098)::OnFocusChange(0)
  CBandObj(00B10098)::QueryInterface(IInputObject)
  >CBandObj::QueryInterface returns S_OK, *ppv=00B10334
  CBandObj(00B10098)::IInputObject::UIActivateIO(0)
  CBandObj(00B10098)::Release
  CBandObj(00B10098)::Release