我正在使用一个主要用C和C++构建的遗留(桌面风格,因为他们现在被称为桌面风格(Windows应用程序。当此应用程序在触摸屏 Windows 笔记本电脑上运行时,当用户在对话框屏幕上的输入框中点击时,我需要自动显示触摸键盘。这种行为非常普遍,据我所知,Microsoft Windows 8/8.1中禁用了这种以前的自动行为,并将在Windows 10中重新启用它。
所以。。。我可以通过编程方式显示触摸键盘,这部分已经解决。我现在要做的是捕捉 ttk::entry 小部件何时获得焦点,然后激活键盘。我最接近的是tk8.5.9/generic/tkFocus.c。有一种方法叫做Tk_FocusObjCmd:
/*
*--------------------------------------------------------------
*
* Tk_FocusObjCmd --
*
* This function is invoked to process the "focus" Tcl command. See the
* user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See the user documentation.
*
*--------------------------------------------------------------
*/
int
Tk_FocusObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *CONST objv[]) /* Argument objects. */
{
除其他事项外,此方法还给出了一个Tcl_Obj对象的数组。我试图做的是找出正在操作的那个是否属于某种类型,例如 ttk::entry。如果是,我将启动触摸键盘。我尝试使用object->typePtr->name,但这并没有给我我所期望的,有时它会崩溃(还没有弄清楚为什么(:
char *objectType = objv[1]->typePtr->name;
if (objectType)
{
printf("Object Type: %sn", objectType); // don't do this, it breaks sometimes.
}
这就是我卡住的地方。我将非常感谢任何见解,以使我朝着正确的方向前进。
你做错了。你应该做的是假设你被传递了一个小部件名称(类似于.a2.b5.c9
(,然后让Tk告诉你具有该名称的小部件的类是什么。
winfo class .a2.b5.c9
对于ttk::entry
的实例,这将返回TEntry
(除非您通过在创建小部件时传入-class
选项来更改它(。
从 C 级别,您将使用 Tk_Class()
来查询类,它接受单个Tk_Window
参数(您可以通过 Tk_NameToWindow
获取,以参数值的字符串形式传递,而这反过来又可以从 Tcl_GetString
中获取(。但是只使用Tcl_VarEval
可能更简单,假设非邪恶的窗口名称......
if (Tcl_VarEval(interp, "winfo class ", Tcl_GetString(objPtr), NULL) == TCL_OK) {
const char *className = Tcl_GetString(Tcl_GetObjResult(interp));
// ...
}
(真正谨慎或真正热衷于速度的人会使用Tcl_EvalObjv
,但这有点复杂。