使用twapi从工具包中加载图标

时间:2015-07-03 06:53:53

标签: tcl

我在名为main.tcl的文件夹中有一个名为App的tcl脚本。脚本中的一行使用来自twapi module的命令(该行实际上在proc中,当用户通过'X'窗口按钮关闭应用程序时,我正在尝试将应用程序最小化到系统托盘):

package require twapi

# ... code here
set hand [twapi::load_icon_from_file tclkit.ico]
# ... code here

文件tclkit.ico与脚本位于同一目录中(即文件夹App)。

main.tcl运行wish时,脚本可以正常运行,但在通过命令行将其包装到可执行文件中后,

> tclkit sdx.kit wrap App -runtime tclsh863.exe

可执行文件引发错误,特别是无法找到图标文件:

The system cannot find the file specified.
The system cannot find the file specified.
    while executing
"LoadImage $hmod $path $type $opts(width) $opts(height) $flags"
    (procedure "twapi::_load_image" line 18)
    invoked from within
"twapi::load_icon_from_file tclkit.ico"
    (procedure "min_to_tray" line 2)
    invoked from within
"min_to_tray"
    (command for "WM_DELETE_WINDOW" window manager protocol)

目前的解决方法是将tclkit.ico文件的副本放在与.exe相同的目录中,但我希望尽可能避免这种情况,并且只有独立的.exe文件。我尝试使用完整路径:

set hand [twapi::load_icon_from_file [file join [pwd] App.exe tclkit.ico]]

通常在我想读取.exe中的文件(.txt,.png文件等)时有效,但没有成功。

所以基本上,有没有办法让.exe从内部加载.ico文件或其他解决方法,不需要依赖.exe应用程序之外的文件?

1 个答案:

答案 0 :(得分:1)

核心问题是相关的Windows API实际上采用了文件名,而不是更容易包装从存档中加载(例如缓冲区)。这意味着您必须将文件从存档中复制出来,然后将该名称传递给系统调用。这实际上是Tcl在{{1}}内部执行的操作,当它从不直接向操作系统可见的源中提取DLL时;但它并没有自动为TWAPI做到这一点,因为该库采取的哲学立场只是一个薄的包装并让调用者处理后果(这意味着你可以轻松地做更多的技巧,只要你这样做了本发明)。

我建议将文件复制到某处的临时文件(即这些东西的标准位置; Tcl 8.6 has file tempfile以帮助处理这种技巧),然后将完整的文件名传递给TWAPI调用。我认为在Windows API中你可以传递一个简单的文件名,你也可以传递一个完整的文件名。 (这实际上很方便......)