我已经尽了最大努力,无法弄清楚这里发生了什么.它在Delphi 4中运行良好.在升级到Delphi 2009之后,我不知道这是否应该是它应该工作的方式,或者它是否是一个问题:
这是我的程序菜单在Delphi 2009下的设计模式中的样子:
请注意,主菜单和文件子菜单中的每个单词都有一个带下划线的字母.应该是这样的.这个带下划线的字母称为加速键,是Windows应用程序的标准字母,因此您可以使用Alt键和该字母快速选择菜单项,然后使用键盘而不是鼠标快速选择子菜单项.
通过使用"&"字符作为项目标题的一部分,您可以通过这种方式获得它们,例如:Save&As ...
当我运行我的应用程序,并使用鼠标打开文件菜单时,它看起来像这样:
主菜单中的字符带下划线,但"文件"菜单中没有下划线.
相反,我使用Alt-F键打开文件子菜单,然后看起来像这样:
并且所有Accelerator Key字母都有正确的下划线.
我玩过AutoHotKeys选项,但这不是问题.
以前有人遇到过这个问题吗?第二个图像中的示例是否是我不知道的正确行为?或者我可能错过了一些选项或编码错误?
2009年11月(一年后):mghie似乎已经找到了根源,并找出了问题所在.请参阅下面接受的答案.
我们有一个非常大的内部MFC应用程序。它具有一个带菜单栏的主窗口,以及数百个唯一的子窗口(无菜单栏),这些子窗口显示在主窗口的顶部(并非同时显示)。这些子窗口实现为,CDialog但CreateWindow无法运行(通过,不是DoModal)。他们的父母HWND定为NULL。
我们最近收到了一项功能请求-即使子窗口之一是活动窗口,也可以从主窗口中使用特定的菜单栏加速器。从用户的角度来看,这是有道理的。
可以通过应用程序范围的键盘挂钩很容易地伪造它,并注意确切的击键,但是我想知道是否有更干净的方法?
我正在使用'&'角色在我的TLabel控件上使用加速键.通过这种方式,用户可以按Alt+ Character after the &以将控件聚焦在表单上.
例:
var
MyLabel : TLabel;
MyEdit : TEdit;
begin
MyEdit := TEdit.Create(Self);
MyEdit.Left := 20;
MyEdit.Top := 40;
MyEdit.Parent := Self;
MyLabel := TLabel.Create(Self);
MyLabel.FocusControl := MyEdit;
MyLabel.Caption := '&Test';
MyLabel.Left := 20;
MyLabel.Top := 20;
MyLabel.Parent := Self;
end;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,MyLabel出现带有'T'下划线的字符并按下Alt+ T原因MyEdit进行聚焦.
如果MyLabel.Caption没有这个'&'角色我怎么能得到?这样做有内置功能吗?
我期待得到'Test'字符串而不是'&Test'
在Windows 7下,我有一个以窗口状态启动的Java程序,JFrame.ICONIFIED我要求它在加载时不会窃取焦点.
我通过设置setFocusableWindowState到false调用之前完成此操作setVisible,然后将其恢复到true之后.这工作正常,我的程序在后台有效加载.
但是,我注意到我的键盘加速器都不再工作,这是使用的直接结果setFocusableWindowState.我甚至尝试在窗口可见后设置我的键盘加速器,但没有运气.下面SSCCE说明了问题-用户不能按Ctrl + T,如果我打电话setFocusableWindowState.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE extends JFrame implements ActionListener {
private JMenuBar mBar;
private JMenu mFile;
private JMenuItem miTest;
public SSCCE() {
setSize(300, 200);
mBar = new JMenuBar();
mFile = new JMenu("File");
miTest = new JMenuItem("Test");
miTest.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
miTest.addActionListener(this);
mFile.add(miTest);
mBar.add(mFile);
setJMenuBar(mBar);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setExtendedState(getExtendedState() | JFrame.ICONIFIED);
setFocusableWindowState(false);
setVisible(true);
setFocusableWindowState(true);
}
@Override
public void actionPerformed(ActionEvent e) { …Run Code Online (Sandbox Code Playgroud) 我错过了什么步骤?
我有一个加速器表:
我在我的app类中添加了一个成员变量:
HACCEL m_hAccel;
Run Code Online (Sandbox Code Playgroud)
我添加了以下覆盖:
BOOL CMeetingScheduleAssistantApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if (m_hAccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_hAccel, lpMsg))
{
AfxMessageBox(_T("Found"));
return(TRUE);
}
}
return CWinAppEx::ProcessMessageFilter(code, lpMsg);
}
Run Code Online (Sandbox Code Playgroud)
我只使用弹出消息框进行调试,它确认正在检测按键.
我的菜单资源设置正确:
所以我的菜单是菜单处理程序的操作.我已经设置了加载加速表的程序.如果我按下,例如Ctrl+ Shift+,X而加速器表检测到它为什么我的弹出对话框没有实际处理它?
我应该指出,我的主应用程序对话框显示两个编辑器之一.因此,当显示编辑器时,我为该编辑器加载加速器表.
我错过了什么步骤?为什么对话框没有处理加速器?
我找到了这个答案如何使子控件处理父CView的加速器命令.
我发现如果我HACCEL直接添加到弹出对话框然后使用PreTranslateMessage:
if (m_hAccelTable)
{
if (::TranslateAccelerator(GetSafeHwnd(), m_hAccelTable, pMsg))
return TRUE;
}
Run Code Online (Sandbox Code Playgroud)
有用.
delphi ×2
mfc ×2
c++ ×1
delphi-2007 ×1
delphi-2009 ×1
focus ×1
java ×1
menu ×1
swing ×1
winapi ×1