- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
对于我的子类 RichTextBox
类,我可以捕获、抑制 Ctrl+Shift+# 的默认行为并重新使用 Ctrl+Shift+#,只要 # 在 1 到 9 之间。对于 Ctrl+Shift+0 ,我不能。我在表单类中尝试了 ProcessCmdKey
,在控件类中尝试了 onKeyDown
和 PreProcessMessage
。
下面是用于应该抑制 Ctrl+Shift+0 但不抑制 Ctrl+Shift+0 的控件类的示例代码:
public override bool PreProcessMessage(ref Message msg)
{
bool cancel = false;
int vKeyCode = (int)msg.WParam;
if(msg.Msg == WinApi.WM_KEYDOWN)
{
bool ctrlDown = (WinApi.GetKeyState(Keys.ControlKey) & (1 << 16)) == (1 << 16);
bool altDown = (WinApi.GetKeyState(Keys.Alt) & (1 << 16)) == (1 << 16);
bool shiftDown = (WinApi.GetKeyState(Keys.ShiftKey) & (1 << 16)) == (1 << 16);
if(ctrlDown && shiftDown && vKeyCode == (int)Keys.D0)
{
Debug.WriteLine("Cancel!");
cancel = true;
}
}
return cancel ? true : base.PreProcessMessage(ref msg);
}
但是,将 Keys.D0
更改为 Keys.D1
表明示例在其他方面有效。
如果这是一条线索,RichTextBox
响应 Ctrl+Shift+0 的默认行为是更改字体。我去寻找将此作为内置快捷方式提及的文档,但我没有找到任何东西(也许我没有使用正确的搜索词)。
我应该如何检测 Ctrl+Shift+0 以便我可以抑制默认行为并编写我自己的行为?
最佳答案
经过一些尝试,我发现了如何真正抑制 Ctrl + Shift + D0
。然而,新问题更加棘手,Ctrl + Shift + D0
被抑制 OK 但 beep sound
是在释放 Ctrl and Shift
时产生的,这太烦人了,因为你说你想覆盖这些键组合而不是丢弃它。因此不应生成哔声
。
在满怀希望地搜索之后,有一些样式
可以应用于RichTextBox
,以防止哔声
或一些消息被丢弃,从而导致抑制 哔声
但没有任何此类事情。我几乎要失望了,打算让你的问题永远无人回答。我不想添加只是部分解决您的问题的答案。然而幸运的是,我尝试发送一些 key
而不是丢弃的0 key
来使用
key 组合并制作 key 组合
有效 因此不会生成哔声
。这是为您提供的完整代码,请注意,我们必须在这里使用一些全局低级键盘钩子(Hook)
,正如我所说,应用程序级消息过滤器也无济于事:
[DllImport("user32")]
private static extern IntPtr SetWindowsHookEx(int hookType, KeyboardLowLevelProc proc, IntPtr moduleHandle, int threadID);
[DllImport("user32")]
private static extern int UnhookWindowsHookEx(IntPtr hHook);
[DllImport("user32")]
private static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32")]
private static extern IntPtr GetModuleHandle(string moduleName);
public struct KBDLLHOOKSTRUCT
{
public Keys key;
public int scanCode;
public int flags;
public int time;
public IntPtr extra;
}
public delegate IntPtr KeyboardLowLevelProc(int hCode, IntPtr wParam, IntPtr lParam);
public IntPtr KeyboardLowLevelCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0) {
KBDLLHOOKSTRUCT kbd = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
if (kbd.key == Keys.D0 && blockD0) {
if(ModifierKeys == (Keys.Control | Keys.Shift)) {
SendKeys.Send("{ESC}");
//Add custom code as the response to Ctrl + Shift + D0 here
//....
}
return new IntPtr(1);//Discard the default behavior
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
bool blockD0;
KeyboardLowLevelProc proc; //this should be declared in the form scope
IntPtr hHook;
//your Form1 constructor
public Form1(){
InitializeComponent();
//Get current module Handle
IntPtr currentModuleHandle = GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName);
//Set the keyboard hook
hHook = SetWindowsHookEx(13, proc, currentModuleHandle, 0);//WH_KEYBOARD_LL = 13
//register these Key events for your richTextBox1
richTextBox1.KeyDown += (s, e) => {
if(e.KeyCode != Keys.D0) blockD0 = true;
};
richTextBox1.KeyUp += (s, e) => {
if (ModifierKeys == Keys.None) blockD0 = false;
};
//Unhook keyboard when form is closed
FormClosed += (s,e) => {
if (hHook != IntPtr.Zero) {
UnhookWindowsHookEx(hHook);
hHook = IntPtr.Zero;
}
}
}
一些解释:我不明白为什么我们必须在这里使用Global Low-level Keyboard hook
,我猜当键组合Ctrl + Shift + D0
被按下,可能有一些关键消息被克隆并发送到另一个线程,这就是为什么当前线程中的所有手动拦截无法拦截或覆盖 Ctrl + Shift + D0
,但是 global low-level keyboard hook
可以处理 key messages
当前模块的所有线程,它可以拦截任何关键消息。
我提到了哔声
的问题,如果你想体验它,只要去掉SendKeys.Send("{ESC}");
,其实你可以尝试一些其他键,例如 1
、2
,...它们还使组合键 Ctrl + Shift + ...
有效并提供帮助避免任何哔声
。
上面的解决方案工作正常,这是最好的解决方案,因为 Ctrl + Shift + D0
应该被彻底地丢弃。但是它有点长(如您所见)。我发现当您按下 Ctrl + Shift + D0
时,将发送消息 WM_INPUTLANGCHANGEREQUEST
,此消息会导致您不希望出现的行为。所以我们可以尝试另一种解决方案,使用 PreProcessMessage
你仍然可以捕获组合 Ctrl + Shift + D0
但你不能丢弃它(因为它被分派(dispatch)到另一个线程) ,这意味着您可以在那里添加自己的代码,而不是丢弃 Ctrl + Shift + D0
,我们可以通过丢弃消息 WM_INPUTLANGCHANGEREQUEST
来丢弃它引起的效果/行为.我们有以下代码:
//Create a custom RichTextBox class
public class CustomRichTextBox : RichTextBox {
protected override void WndProc(ref Message m){
if(m.Msg == 0x50) return; //WM_INPUTLANGCHANGEREQUEST = 0x50
base.WndProc(ref m);
}
public override bool PreProcessMessage(ref Message msg) {
if (msg.Msg == 0x100)//WM_KEYDOWN = 0x100
{
Keys keyData = (Keys)msg.WParam | ModifierKeys;
if(keyData == (Keys.Control | Keys.Shift | Keys.D0)){
//your own code goes here...
}
}
return base.PreProcessMessage(ref msg);
}
}
您可以看到第二种方法要短得多,但是正如我所说,它实际上抑制Ctrl + Shift + D0
,它只是抑制由消息 WM_INPUTLANGCHANGEREQUEST
引起的默认行为。我想这足以解决您的问题。
关于c# - 如何覆盖 WinForms RichTextBox 的 Ctrl+Shift+0(零)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19556221/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!