我正在使用遗留(桌面风格,因为它们现在已知)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.
}
这就是我被困住的地方。我非常感谢让我走向正确方向的任何见解。
答案 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}},但这有点复杂。)