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
| Вернуться в корень Архива
|