15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


SetFocus for button controls

Roger Onslow -- Roger_Onslow@compsys.com.au
Thursday, August 22, 1996

Environment: VC 4.1 Windows 95

I have a number of controls of various types on my dialog (property page 
actually)
and I need to perform certain actions when each control receives focus.

I use WM_SETFOCUS handlers for my controls, and this works just fine for edit 
controls.

However, this message is NOT sent when a button control (push button, checkbox 
or radio button)
gets focus.

Obviously, buttons *do* receive focus (as buttons get grayed focus rect draw 
around
them etc), and I know from implementing owner drawn buttons in the past, that 
one has
to handle the drawing of the button when it has focus (ie. draw one's own focus 
rect).
However, the only message a button seems to handle is the click (or double 
click if
owner drawn).  I can't seem to find any message that is sent when a button gets 
focus.

How *can* I find out when a given button gets the focus?

Thanks in advance

Roger Onslow
Senior Software Engineer
Computer Systems Australia
RogerO@compsys.com.au



John Simmons -- jms@connectnet.com
Sunday, August 25, 1996

[Mini-digest: 3 responses]

At 03:05 PM 8/22/96 EAT, you wrote:
>Environment: VC 4.1 Windows 95
>
>I have a number of controls of various types on my dialog 
>(property page actually) and I need to perform certain 
>actions when each control receives focus.
>
>I use WM_SETFOCUS handlers for my controls, and this works 
>just fine for edit controls.  However, this message is NOT 
>sent when a button control (push button, checkbox or radio 
>button) gets focus.
>
>Obviously, buttons *do* receive focus (as buttons get 
>grayed focus rect draw around them etc), and I know from 
>implementing owner drawn buttons in the past, that one 
>has to handle the drawing of the button when it has focus 
>(ie. draw one's own focus rect).  However, the only 
>message a button seems to handle is the click (or double 
>click if owner drawn).  I can't seem to find any message 
>that is sent when a button gets focus.
>
>How *can* I find out when a given button gets the focus?


For buttons (checkboxes, radio buttons & pushbuttons) , you have to check
for ON_BN_CLICKED.  However, the dialog box still doesn't know what control
has the focus if the user tabs to a button or uses the up/down arrow keys in
a radio button group.  I've attached a file that shows how to get around
this problem.

It's called KEYSNAG.TXT.  If you have any questions gimme a shout.

struct vpCtlInfo 
{
  UINT   Id;
  BOOL   AcceptsCalc;
  BOOL   IsCurrency; 
  double MinValue;
  double MaxValue;
};    

const UINT KEY_HELP = 1000,
           KEY_PGUP = 1001,
           KEY_PGDN = 1002,
           KEY_TAB  = 1003;

class CMyDlg : public CDialog
{
  // holds control info for Calculator call
  vpCtlInfo m_CurrentCtl;
  
  // for trapping F1 key to show proper help //
  FARPROC lpfnFilterProc;  
  static HHOOK HookID;
  HINSTANCE hInst;
  #ifdef WIN32
    static DWORD CALLBACK KeystrokeHook(int nCode, WORD wParam, LONG lParam);
  #else
    static DWORD __export CALLBACK KeystrokeHook(int nCode, WORD wParam, LONG lParam);
  #endif
  void GetFocusedControl();

public:
  CmyDlg(CWnd* pParent = NULL); 
  //{{AFX_DATA(CGrowthAdmin)
  enum { IDD = DLG_MyDlg };
  //}}AFX_DATA

protected:
  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  //{{AFX_MSG(CMyDlg)
    afx_msg void OnOKAY();     
    afx_msg void OnCANCEL();
    afx_msg LONG OnKeystroke(UINT, LONG);
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};


///////////////////////////////////////////////////////////////
// CMyDlg dialog

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//{{AFX_MSG_MAP(CMyDlg)
ON_COMMAND(IDOK,OnOKAY)
ON_COMMAND(IDCANCEL,OnCANCEL)
ON_COMMAND(VPHELP,OnVPHELP)
ON_COMMAND(VPNEXT,OnVPNEXT)
ON_COMMAND(VPPREV,OnVPPREV)
ON_MESSAGE(WM_KEYSTROKE,OnKeystroke)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


//--------------------------------------------------------------/
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
       :CDialog(CMyDlg::IDD, pParent)
{
  //{{AFX_DATA_INIT(CMyDlg)
  //}}AFX_DATA_INIT
}

//--------------------------------------------------------------/
void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CMyDlg)
  //}}AFX_DATA_MAP
}

HHOOK CMyDlg::HookID=0;

//--------------------------------------------------------------/
BOOL CMyDlg::OnInitDialog()
{
  CDialog::OnInitDialog();

  LPDWORD processid = 0;
  #ifdef WIN32
    HookID = SetWindowsHookEx(WH_MSGFILTER, 
                              (HOOKPROC)CMyDlg::KeystrokeHook, 
	                      theApp.m_hInstance, 
                              GetWindowThreadProcessId(m_hWnd, processid));
  #else
    HookID = SetWindowsHookEx(WH_MSGFILTER, 
                              (HOOKPROC)CMyDlg::KeystrokeHook, 
                              theApp.m_hInstance, 
                              GetWindowTask(m_hWnd));
  #endif

  return TRUE;  // return TRUE unless you set the focus to a control
}

//------------------------------------------------------------/
void CMyDlg::OnOKAY()
{
  #ifdef WIN32
    UnhookWindowsHookEx(CMyDlg::HookID); 
  #else
    UnhookWindowsHook(WH_MSGFILTER,
                      (HOOKPROC)CLifeInsDetail::KeystrokeHook);
  #endif
  EndDialog(IDOK);
}

//------------------------------------------------------------/
void CMyDlg::OnCANCEL()
{
  #ifdef WIN32
    UnhookWindowsHookEx(CMyDlg::HookID); 
  #else
    UnhookWindowsHook(WH_MSGFILTER,
                      (HOOKPROC)CLifeInsDetail::KeystrokeHook);
  #endif
  EndDialog(IDCANCEL);
}

//------------------------------------------------------------/
void CMyDlg::OnVPHELP()
{
  WinHelp(IDD, HELP_CONTEXT);
  GotoDlgCtrl(GetDlgItem(m_CurrentCtl.Id));
}

//------------------------------------------------------------/
void CMyDlg::OnVPNEXT()
{ 
  #ifdef WIN32
     UnhookWindowsHookEx(CMyDlg::HookID); 
  #else
     UnhookWindowsHook(WH_MSGFILTER,
                       (HOOKPROC)CLifeInsDetail::KeystrokeHook);
  #endif

	EndDialog(VPNEXT);
}

//-----------------------------------------------------------/
void CMyDlg::OnVPPREV()
{
  #ifdef WIN32
    UnhookWindowsHookEx(CMyDlg::HookID); 
  #else
    UnhookWindowsHook(WH_MSGFILTER,(HOOKPROC) CLifeInsDetail::KeystrokeHook);
  #endif
  EndDialog(VPPREV);
}

//-----------------------------------------------------------//             
LONG CMyDlg::OnKeystroke(UINT wParam, LONG lParam)
{
  switch (toupper(wParam))
  {
    case KEY_HELP : OnVPHELP();          return 1L;
    case KEY_PGDN : OnVPNEXT();          return 1L;
    case KEY_PGUP : OnVPPREV();          return 1L;		
    case KEY_TAB  : GetFocusedControl(); return 0L;
    default       : break;
  }
  return 1L;
}

//------------------------------------------------------------//             
/* This function catches arrowkey movement and tab/shift-tab 
   key strokes.  The reason is that we had to know if the 
   currently focused control was a button.  As long as the 
   user clicks on the button with the mouse, everything is 
   cool,  but the minute they use a keystroke to move between 
   controls, the dialog doesn't know which control has the 
   focus (if it's a button).  This was more efficient than 
   enumerating thru the list of controls to see which one had 
   the focus. */
//------------------------------------------------------------//             
void CMyDlg::GetFocusedControl()
{
  m_CurrentCtl.Id = GetFocus()->GetDlgCtrlID();
  char classname[80];
  CString ClassName;
  ClassName.Empty();
  if (::GetClassName(GetDlgItem(m_CurrentCtl.Id)->m_hWnd, 
                                classname, sizeof(classname)))
    ClassName = classname;
  if (ClassName.Find("Button") >= 0)
    m_CurrentCtl.AcceptsCalc = FALSE;
}

//-----------------------------------------------------------//             
#ifdef WIN32
  DWORD CALLBACK CMyDlg::KeystrokeHook(int nCode, WORD wParam, LONG lParam)
#else
  DWORD __export CALLBACK CLifeInsDetail::KeystrokeHook(int nCode, WORD wParam, LONG lParam)
#endif
{
  if (nCode < 0)
    return CallNextHookEx((HHOOK) HookID, nCode, wParam, lParam);
  if (nCode == MSGF_DIALOGBOX)
  {
    MSG FAR *ptrMsg = (MSG FAR *)lParam; 
    if (WM_KEYDOWN == ptrMsg->message)
    { 
      switch (ptrMsg->wParam)
      {
	case VK_F1 :
             ::PostMessage(::GetParent(ptrMsg->hwnd),WM_KEYSTROKE,KEY_HELP,lParam);
             return 1L;
        case VK_NEXT :
             ::PostMessage(::GetParent(ptrMsg->hwnd),WM_KEYSTROKE,KEY_PGDN,lParam);
             return 1L;
        case VK_PRIOR : 
             ::PostMessage(::GetParent(ptrMsg->hwnd),WM_KEYSTROKE,KEY_PGUP,lParam);
             return 1L;
        case VK_UP    :
        case VK_DOWN  :
        case VK_RIGHT :
        case VK_LEFT  :
        case VK_TAB   : 
             ::PostMessage(::GetParent(ptrMsg->hwnd),WM_KEYSTROKE,KEY_TAB,lParam);
             return 0L;
      }
    }
  }
  return 0L;
}

/=========================================================\
| John Simmons (Redneck Techno-Biker)                     |
|    jms@connectnet.com                                   |
| Home Page                                               |
|    www2.connectnet.com/users/jms/                       |
|---------------------------------------------------------|
| ViewPlan, Inc. home page (my employer)                  |
|    www.viewplan.com/index.html                          |
|---------------------------------------------------------|
| IGN #12 American Eagle Motorsports Zerex Ford	          |
|    Teammates - Steve Stevens (#13 Hooters Ford and      |
|                               1995 IGN Points Champ)    |
|                Pat Campbell (#14 Dr. Pepper Ford)       |
| American Eagle Motorsports Team Page                    | 
|    www2.connectnet.com/users/jms/ignteam                |
| Hawaii Multi-Player Nickname:  AEMwest                  |
|---------------------------------------------------------|
| Competitor - Longest Signature File On The Net          |
\=========================================================/

-----From: "S. Balachandar" 

Hi

There is a notification message for button controls which they will send =
to the parent whenever they receive focus. It is similar to EN_SETFOCUS =
of the edit control..

The message is BN_SETFOCUS. But to get this notification message the =
button control should have the BS_NOTIFY style set. [Note : =
Notifications are sent thru WM_COMMAND message to the parent ].

Hope this helps
Bala
-------------------------------------------------------------------------=
----------------------------------------
S. Balachandar                                e-mail : =
chandar@adca01.enet.dec.com
Software Engineer                             Phone  : 3370445 Ext : 479
Digital Equipment (I) Ltd.,                   Fax    : 3371498
Digital House, 45/14 Tumkur Road,  =20
Yeshwanthpur II Stage,                   =20
Bangalore 560 022.                         =20
-------------------------------------------------------------------------=
----------------------------------------

-----From: "Greg Tighe" 

A button sends the BN_DISABLE, BN_PUSHED, BN_KILLFOCUS, BN_PAINT,
BN_SETFOCUS, and BN_UNPUSHED notification messages only if it has the
BS_NOTIFY style. It sends the BN_CLICKED and BN_DBLCLK notification
messages regardless of the BS_NOTIFY style.

	-Greg Tighe
	Applied Intelligent Systems, Inc.
	Ann Arbor, MI
	gdt@aisinc.com



Gabriel Parlea-Visalon -- Gabriel@derivs.demon.co.uk
Tuesday, August 27, 1996

In your message dated Thursday 22, August 1996 you wrote :

> Environment: VC 4.1 Windows 95
> 
> I have a number of controls of various types on my dialog (property page 
> actually)
> and I need to perform certain actions when each control receives focus.
> 
> I use WM_SETFOCUS handlers for my controls, and this works just fine for edit 
> controls.
> 
> However, this message is NOT sent when a button control (push button, checkbox 
> or radio button)
> gets focus.
> 
> Obviously, buttons *do* receive focus (as buttons get grayed focus rect draw 
> around
> them etc), and I know from implementing owner drawn buttons in the past, that 
> one has
> to handle the drawing of the button when it has focus (ie. draw one's own 
focus 
> rect).
> However, the only message a button seems to handle is the click (or double 
> click if
> owner drawn).  I can't seem to find any message that is sent when a button 
gets 
> focus.
> 
> How *can* I find out when a given button gets the focus?
> 
> Thanks in advance
> 
> Roger Onslow
> Senior Software Engineer
> Computer Systems Australia
> RogerO@compsys.com.au
> 
Override OnKillFocus() for the CPropertySheet and check for the button pointer.

Gabriel
-- 
                             Gabriel Parlea-Visalon
                               Software Engineer
                           Derivative Trading Systems
                           gabriel@derivs.demon.co.uk




| Вернуться в корень Архива |