如何判断Tcl_Obj是否是某种ttk :: entity,例如ttk:entry?

时间:2015-03-04 17:10:35

标签: c++ tcl tk

我正在使用遗留(桌面风格,因为它们现在已知)Windows应用程序主要使用C和C ++构建。当此应用程序在触摸屏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->名称,但这并没有给我我所期望的,有时它崩溃了(还没弄清楚原因):

char *objectType = objv[1]->typePtr->name;

if (objectType)
{
    printf("Object Type: %s\n", objectType); // don't do this, it breaks sometimes.
}

这就是我被困住的地方。我非常感谢让我走向正确方向的任何见解。

1 个答案:

答案 0 :(得分:1)

你这样做非常错误。您所做的是假设您已经传递了一个小部件名称(类似.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

(真正谨慎或真正热衷于速度的人会使用{{1}},但这有点复杂。)