当子按钮被按下时,窗口失去焦点
C++ Window losing focus when child button is pressed
我正在尝试为c++应用程序运行GUI,但我遇到了按键事件的问题。基本上,一切都很好,只要我不点击任何按钮(主窗口注册关键事件),但一旦我点击一个按钮,主窗口失去焦点,它不再捕捉关键事件。这可能是一个愚蠢的问题,但我对c++非常陌生。这是我使用的一些代码:
创建主窗口:
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Application Name", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
540, /* The programs width */
250, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
创建一个按钮:
CreateWindow(TEXT("button"), TEXT("Start"),
WS_VISIBLE | WS_CHILD,
x, y, width, height,
hwnd, (HMENU) 6, NULL, NULL);
我还注意到,每当我点击一个按钮,WM_KILLFOCUS
事件被触发,这就是为什么我认为这是一个焦点问题。我还尝试捕获WM_KILLFOCUS事件,然后使用SetActiveWindow
再次设置焦点,但这会使我的程序崩溃。
任何帮助都将是感激的:)
原来我使用了错误的函数(SetWindowActive
)。阿萨夫·列维的回答对我来说似乎很复杂,我想可能有另一种解决方法。我设法找到SetFocus
函数,通过提供它的句柄,将焦点放在任何给定的窗口。
要使其工作,我需要做的是,一旦必要的代码在WM_COMMAND
块中执行,我调用SetFocus函数与主窗口的句柄。这使焦点回到主窗口,并允许它接收事件。
注意,将SetFocus放在WM_KILLFOCUS
块中会导致按钮和其中的任何其他组件对事件没有响应。
这是设计。主窗口是window
,但按钮是window
,并且在任何给定时间只有一个可以有焦点。如果你不想让按钮"偷"焦点,添加一个OnFocus处理程序(或拦截WM_SETFOCUS
),并立即将焦点返回到前一个窗口(我相信它在WM_SETFOCUS
的WPARAM
中)。
一个简单的方法是:
- hMyButton = CreateWindow("button",…).
- 定义MyButtonProc(HWND, UINT, WPARAM, LPARAM)函数
- 调用SetWindowLong(hMyButton, GWL_WNDPROC, (LONG)MyButtonProc)将此函数返回的值保存在g_OldButtonProc中。
- 内部MyButtonProc()捕获WM_SETFOCUS,并调用SetFocus(hMyMainWindow)。总是在MyButtonProc()函数结束时返回CallWindowProc(h_OldButtonProc, hwnd, msg,…),除非消息是WM_SETFOCUS。
第一个答案部分准确。子类化按钮可以得到"rid"的"问题";然而,处理WM_SETFOCUS是在父窗口,或子类过程或BN_SETFOCUS将导致无响应的UI,如果你从按钮的焦点。
你应该在子类过程中重写的是WM_LBUTTONUP。因为当你松开鼠标按钮时,你已经点击了窗口按钮。注:我认为这是一个完全垃圾的按钮来窃取焦点。应该有一个像BS_NO_STEAL_FOCUS这样的样式来防止这种情况。因为当你想要另一个窗口来处理按键或滚动时,这是非常麻烦的。
/** Procedure for subclass.
This procedure is called first for the widget/control.
Unhandled or partially handled message can goes to
original procedure by calling DefSubclassProc(...).
buttonProcEx takes all four params of normal procedure, plus a
param for user defined object.
Note this is what win32 should have done in the first place.
*/
LRESULT CALLBACK buttonProcEx(HWND hwnd,uint msg,WPARAM,LPARAM,DWORD_PTR)
{
if(msg == WM_LBUTTONUP)
{
setFocus(GetParent(hwnd));
return 0; //do not allow default behaviour
}
else return DefSubclassProc(hwnd,msg,wparam,lparam);
}
//Call this after creating your button
SetWindowSubclass ((HWND)按钮,buttonProcEx, 0, NULL);
or
struct Content {...}content; //lifetime should be long enough
SetWindowSubclass((HWND)button,buttonProcEx,0,(DWORD_PTR)&content);
- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 问:如何使用C++中的按钮从窗口打开窗口
- SDL 窗口不会弹出
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 如何在cpp文件之间切换窗口?在Qt中
- QuadTree只在窗口的右上角绘制
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 处理闪烁窗口事件
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- Win32:在单击其子窗口时,Combobox失去了焦点
- 将鼠标和键盘输入传递到背景窗口而不会失去焦点
- 子窗口 (CEdit) 失去焦点
- Qt:即使子窗口失去焦点,也要保持子窗口位于父窗口的顶部
- 显示消息框后,子窗口失去焦点
- 如果应用程序窗口失去激活c++,则绕过OnFocus/GetFocus事件的触发器
- 我怎样才能使窗口失去焦点
- 为什么当窗口在win32上失去焦点时,被覆盖的非客户端区域显示默认值
- 当子按钮被按下时,窗口失去焦点
- 如何在离开(关闭或失去焦点)窗口之前显示模态确认消息