如何确定 Tcl_Obj 是否是某种 ttk:: 实体,例如 ttk:entry?
How can I find out if a Tcl_Obj is a certain kind of ttk:: entity, such as ttk:entry?
我正在使用一个遗留的(桌面风格,现在已知)Windows 应用程序主要是用 C 和 C++ 构建的。当此应用程序 运行 在触摸屏 Windows 笔记本电脑上运行时,我需要在用户点击对话框屏幕上的输入框内部时自动显示触摸键盘。这种行为很常见,据我所知,Microsoft 禁用 这种以前在 Windows 8/8.1 中的自动行为,并将在 [=] 中重新启用它29=]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: %s\n", objectType); // don't do this, it breaks sometimes.
}
这就是我卡住的地方。我将不胜感激任何能让我朝着正确方向前进的见解。
你的做法大错特错。你应该做的是假设你传递了一个小部件名称(类似于.a2.b5.c9
)然后让Tk告诉你知道这个名字的小部件的 class 是什么。
winfo class .a2.b5.c9
对于 ttk::entry
的实例,这将 return TEntry
(除非您通过在小部件创建时传入 -class
选项来更改它)。
从 C 级别开始,您可以使用 Tk_Class()
查询 class,它接受一个 Tk_Window
参数(您可以通过 Tk_NameToWindow
、传入参数值的字符串形式,您又可以从 Tcl_GetString
获得)。但是使用 Tcl_VarEval
可能更简单,假设是非邪恶的 window 名字……
if (Tcl_VarEval(interp, "winfo class ", Tcl_GetString(objPtr), NULL) == TCL_OK) {
const char *className = Tcl_GetString(Tcl_GetObjResult(interp));
// ...
}
(真正谨慎的人或真正追求速度的人会使用Tcl_EvalObjv
,但那有点复杂。)
我正在使用一个遗留的(桌面风格,现在已知)Windows 应用程序主要是用 C 和 C++ 构建的。当此应用程序 运行 在触摸屏 Windows 笔记本电脑上运行时,我需要在用户点击对话框屏幕上的输入框内部时自动显示触摸键盘。这种行为很常见,据我所知,Microsoft 禁用 这种以前在 Windows 8/8.1 中的自动行为,并将在 [=] 中重新启用它29=]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: %s\n", objectType); // don't do this, it breaks sometimes.
}
这就是我卡住的地方。我将不胜感激任何能让我朝着正确方向前进的见解。
你的做法大错特错。你应该做的是假设你传递了一个小部件名称(类似于.a2.b5.c9
)然后让Tk告诉你知道这个名字的小部件的 class 是什么。
winfo class .a2.b5.c9
对于 ttk::entry
的实例,这将 return TEntry
(除非您通过在小部件创建时传入 -class
选项来更改它)。
从 C 级别开始,您可以使用 Tk_Class()
查询 class,它接受一个 Tk_Window
参数(您可以通过 Tk_NameToWindow
、传入参数值的字符串形式,您又可以从 Tcl_GetString
获得)。但是使用 Tcl_VarEval
可能更简单,假设是非邪恶的 window 名字……
if (Tcl_VarEval(interp, "winfo class ", Tcl_GetString(objPtr), NULL) == TCL_OK) {
const char *className = Tcl_GetString(Tcl_GetObjResult(interp));
// ...
}
(真正谨慎的人或真正追求速度的人会使用Tcl_EvalObjv
,但那有点复杂。)