vba textbox在失去焦点后如何重新获取焦点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vba textbox在失去焦点后如何重新获取焦点相关的知识,希望对你有一定的参考价值。

现在我想检查textbox的输入内容是不是数字,如果不是数字的话弹出提示框,并且将焦点重新停在textbox上,可是我在exit方法里设置setfocus方法不好使,求各位大神指导

参考技术A TextBox1.SetFocus 改成 Cancel=True 参考技术B exit事件里有个参数CANCEL 吧他的值改为false,
只要在EXIT事里写入CANCEL=FALSE。就不会退出TEXTBOX。
我也是刚学VBA以后多指教
参考技术C 直接在提示框语句后面接着用setfocus方法不行吗追问

不行啊
代码如下:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Not IsNumeric(TextBox1.Value) Then
MsgBox ("非数字")
TextBox1.SetFocus
End If
End Sub
提示信息弹出来了,但是没有获得焦点

追答

不能写在它本身的Exit 事件里,输入文本后下一步是怎么做的,代码应在下一步里。
要在本身的事件里检查,应用 TextBox1_Change() 或TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)事件代码,可限制不是数字的输入。

追问

现在我想检查textbox的输入内容是不是数字,如果不是数字的话弹出提示框,并且将焦点重新停在textbox上,能提供代码吗,谢谢

追答

Private Sub TextBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
For i = 1 To Len(TextBox1.Text)
n = Asc(Right(TextBox1.Text, 1))
If n = 46 Or n > 47 And n < 58 Then Exit For
TextBox1.Text = Left(TextBox1.Text, Len(TextBox1.Text) - 1)
Next
End Sub
上面代码就控制了只能输入数字0~9和小数点,其他输入则会清除

追问

比这个方法有个问题,做到了检查,但是没有解决让它重新获取焦点的问题
不过还是非常感谢你,我已经想到另外办法来解决了

追答

你能确定输入之后该干什么,比如按“确定”按钮,那么你的代码就放在单击“确定”的代码里。

如果不能确定输入之后该干什么,那么可设一个全局变量(逻辑型),比如Bo,在你的代码确定它的值:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Bo=false
If Not IsNumeric(TextBox1.Value) Then
MsgBox ("非数字")
Bo=trueT
End If
End Sub

再他后续可能的事件代码里都加一句:if Bo=true then TextBox1.SetFocus
这样也能达到目的

本回答被提问者采纳

C# Winform 控件或窗体失去焦点时,获取键盘输入数据(我用winform获取另一个窗口的数据)

当我最小化winform窗口时,我想接受记事本或文本编辑器输入的数据!
当winform或其控件失去焦点时,winform中的textbox能接收到键盘输入的数据

全局键盘钩子,如下,你再把键盘钩子的数据弄到textbox就可以了。
using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections.Generic;
namespace HookGlobal

/// <summary>
/// 这个类可以让你得到一个在运行中程序的所有键盘事件
/// 并且引发一个带KeyEventArgs和MouseEventArgs参数的.NET事件以便你很容易使用这些信息
/// </summary>
/// <remarks>
/// 修改:lihx
/// 修改时间:04.11.8
/// </remarks>
public class KeyBordHook

private const int WM_KEYDOWN = 0x100;
private const int WM_KEYUP = 0x101;
private const int WM_SYSKEYDOWN = 0x104;
private const int WM_SYSKEYUP = 0x105;
//全局的事件
public event KeyEventHandler OnKeyDownEvent;
public event KeyEventHandler OnKeyUpEvent;
public event KeyPressEventHandler OnKeyPressEvent;
static int hKeyboardHook = 0; //键盘钩子句柄
//鼠标常量
public const int WH_KEYBOARD_LL = 13; //keyboard hook constant
HookProc KeyboardHookProcedure; //声明键盘钩子事件类型.
//声明键盘钩子的封送结构类型
[StructLayout(LayoutKind.Sequential)]
public class KeyboardHookStruct

public int vkCode; //表示一个在1到254间的虚似键盘码
public int scanCode; //表示硬件扫描码
public int flags;
public int time;
public int dwExtraInfo;

//装置钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//卸下钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
//下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
[DllImport("user32")]
public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
//先前按下的键
public List<Keys> preKeys = new List<Keys>();
/// <summary>
/// 墨认的构造函数构造当前类的实例并自动的运行起来.
/// </summary>
public KeyBordHook()

Start();

//析构函数.
~KeyBordHook()

Stop();

public void Start()

//安装键盘钩子
if (hKeyboardHook == 0)

KeyboardHookProcedure = new HookProc(KeyboardHookProc);
//hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
Process curProcess = Process.GetCurrentProcess();
ProcessModule curModule = curProcess.MainModule;
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
if (hKeyboardHook == 0)

Stop();
throw new Exception("SetWindowsHookEx ist failed.");



public void Stop()

bool retKeyboard = true;
if (hKeyboardHook != 0)

retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;

//如果卸下钩子失败
if (!(retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");

private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)

if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))

KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
//当有OnKeyDownEvent 或 OnKeyPressEvent不为null时,ctrl alt shift keyup时 preKeys
//中的对应的键增加
if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
if (IsCtrlAltShiftKeys(keyData) && preKeys.IndexOf(keyData) == -1)

preKeys.Add(keyData);


//引发OnKeyDownEvent
if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
OnKeyDownEvent(this, e);

//引发OnKeyPressEvent
if (OnKeyPressEvent != null && wParam == WM_KEYDOWN)

byte[] keyState = new byte[256];
GetKeyboardState(keyState);
byte[] inBuffer = new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode,
MyKeyboardHookStruct.scanCode,
keyState,
inBuffer,
MyKeyboardHookStruct.flags) == 1)

KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
OnKeyPressEvent(this, e);


//当有OnKeyDownEvent 或 OnKeyPressEvent不为null时,ctrl alt shift keyup时 preKeys
//中的对应的键删除
if ((OnKeyDownEvent != null || OnKeyPressEvent != null) && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
if (IsCtrlAltShiftKeys(keyData))

for (int i = preKeys.Count - 1; i >= 0; i--)

if (preKeys[i] == keyData)

preKeys.RemoveAt(i);




//引发OnKeyUpEvent
if (OnKeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))

Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(GetDownKeys(keyData));
OnKeyUpEvent(this, e);


return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);


private Keys GetDownKeys(Keys key)

Keys rtnKey = Keys.None;
foreach (Keys keyTemp in preKeys)

switch (keyTemp)

case Keys.LControlKey:
case Keys.RControlKey:
rtnKey = rtnKey | Keys.Control;
break;
case Keys.LMenu:
case Keys.RMenu:
rtnKey = rtnKey | Keys.Alt;
break;
case Keys.LShiftKey:
case Keys.RShiftKey:
rtnKey = rtnKey | Keys.Shift;
break;
default:
break;


rtnKey = rtnKey | key;
return rtnKey;

private Boolean IsCtrlAltShiftKeys(Keys key)

switch (key)

case Keys.LControlKey:
case Keys.RControlKey:
case Keys.LMenu:
case Keys.RMenu:
case Keys.LShiftKey:
case Keys.RShiftKey:
return true;
default:
return false;



参考技术A 失去焦点的控件添加一个Validated事件
事件里面写 txtbox1.Focus()
至于获取另一个窗口的数据
首先两个窗口同个命名空间
某窗口被获取的数据用public修饰(如public int a=0)
另外一个就可以通过 form1.a
这个是我想的 - - 没有测试过 自己试试
参考技术B C# 全局键盘钩子. 参考技术C 能不能说的再明白点... 有图吗 参考技术D 关键词:HOOK

以上是关于vba textbox在失去焦点后如何重新获取焦点的主要内容,如果未能解决你的问题,请参考以下文章

如何让WPF中窗体失去焦点后TextBox中的被选中文本仍然保持高亮状态?

第一次输入字符后,Asp.Net TextBox 失去焦点

如何在文本更改时启用/禁用绑定到 ICommand 的按钮,而不是失去 TextBox 的焦点

C# Winform 控件或窗体失去焦点时,获取键盘输入数据(我用winform获取另一个窗口的数据)

焦点后如何刷新页面?

选择值后强制 FilteringSelect 失去焦点