如何确定Tcl_Obj是否是某种类型的 ttk:: 实体,例如 ttk:entry



我正在使用一个主要用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,但这有点复杂。

最新更新