Мощный функционал скриптового языка Tcl в сочетании с виджетами Tk/TTK позволяет создавать в этой среде серьезные приложения. Этому способствует также его кросплатформенность и прекрасная интеграция с языками программирования C/C++.
И в качестве примера сразу приведем пример программы на языке C. Эта программа строит графический интерфейс, имеющий поле для ввода строки, кнопку, при нажатии которой вычисляется длина строки, и поля для отображения результата:
Текст программы на языке C выглядит следующим образом:
Я думаю код не нуждается в дополнительных комментариях. Получить выполняемый код можно следующим образом:
Если вы собираетесь писать приложение со сложным GUI, то целесообразно для его проектирования использовать дизайнеры. Это может быть и Vtcl, и TKproE-2.20 и другие. Я бы рекомендовал использовать TKproE. Из сохраненного проекта достаточно взять тело процедуры TKopenWindow и загрузить его с помощью функций Tcl_Eval или Tcl_EvalFile. В первом случае код вставляется в тело программы, например, присваивается переменной strtcl, как в нашем примере. Во втором случае сохраняется в файле и из него загружается.
Естественный вопрос, как обрабатывать события, например, нажатие кнопки. В этом случае ставится соответствие между именем функции в коде tcl (например, в опции –command у виджета button), который был загружен, и функцией в коде программы. В нашем примере это следующая строка:
Для обмена данными между tcl-интерпретатором и основной программой на языке C, могут, использоваться функции Tcl_GetVar и Tcl_SetVar (см. пример), Tcl_LinkVar и др.
Для разработки GUI-приложений с использованием Tk-виджетов на языке C++ разработана красивая библиотека CPPTK. Последнее ее обновление вышло в мае текущего года. Но мы будем иметь ввиду предпоследнюю версию, а именно CPPTK-1.0.2.
Использование этой библиотеки для разработки, подчеркиваю, для разработки графических приложений, позволяет забыть об интерфейсах библиотек libtcl и libtk (см. выше). Согласитесь, это немало, учитывая то, что интерфейс библиотеки CPPTK максимально приближен к интерфейсу Tcl/Tk и самое главное прекрасно документирован:
И так, библиотека CPPTK позволяет разрабатывать GUI-приложения на классических tk-виджетах. Но она настолько хорошо спроектирована, что перейти, а еще лучше, добавить поддержку тематических виджетов ttk не сосравляет никакого труда, что мы и сделали, добавив в первую очередь поддержку виджетов ttk::notebook и ttk::combobox.
Этот патч добавляет не только поддержку новых виджетов, то и поддержку режима –data при работе с images (images(create,photo, ''myimage'' –date (''PEM/base64-данные'');). К сожалению, при укладке в спойлер строки +template пришлось заменить на +template <typename T\> (в противном случае спойлер неверно отображал текст). Необходимо это учитывать и провести обратную замену.
Применить патч можно следующим образом. Создайте каталог. В него поместите каталог проекта CPPTK. В нем же сохраните, скажем, в файле patchForCPPTK-1.0.2.patch патч из спойлера (с учетом замечания) и, находясь в этом каталоге, примените патч:
Все, теперь у вас есть библиотека CPPTK с поддержкой новых виджетов. И все же писать GUI вручную неблагодарное дело. Для проектирования самого GUI все же удобно использовать дизайнер TKproE. Для получения из готового tcl-скрипта программы на C++ с библиотекой CPPTK разработан простой tcl-скрипт convertFromTclToCPPTK.tcl:
Для получения программы на C++ достаточно выполнить этот скрипт:
В качестве примера рассмотрим разработку программы формирования усовершенствованной электронной подписи с библиотекой SSF («Secure Store and Forward»), используемой в продуктах компании SAP AG для обеспечения криптографической защиту электронных документов за счет использования механизмов электронной подписи и шифрования с использованием российских криптоалгоритмов (ГОСТ 28147-89, ГОСТ Р 34.11-94, ГОСТ Р 34.11-2012, ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012). Проект GUI в дизайнере TKproE выглядит следующим образом:
Для получения банарного кода положим файл forBook.cc в каталог с пропатченной библиотекой CPPTK (см.выше) и выполним следующую команду:
Если теперь запустить полученный бинарный модуль forBook, то на экране монитора мы увидим знакомое изображение (см. выше). К сожалению, нажатие кнопок не приведет ни к какому результату, да и иконка нас не устраивает. И мы дописываем полученную программу. Включаем в нее код иконки:
Привязываем ее к главному окну:
Но самое главное, что мы делаем, это привязываем к кнопкам определенные функции, которые необходимо будет выполнить при их нажатии:
Естественно, пишем код самих функций.
И после получения бинарного кода запускаем его и видим следующее:
Вот и все. Но остались еще две вещи, про которые я хотел бы рассказать. Это создание расширений для Tcl посредством динамических библиотек и Tcl/Tk в Android.
И в качестве примера сразу приведем пример программы на языке C. Эта программа строит графический интерфейс, имеющий поле для ввода строки, кнопку, при нажатии которой вычисляется длина строки, и поля для отображения результата:
Текст программы на языке C выглядит следующим образом:
#include <stdlib.h>
#include <stdio.h>
#include <tcl.h>
#include <tk.h>
#include <string.h>
Tcl_Interp * tcl_interp ;
int lenStr(){
int code;
int len;
char slen[256];
char *res;
/*Читаем из widget-а введенную строку в переменную tcl с именем a*/
code = Tcl_Eval(tcl_interp, "set a [.ent1 get];");
/*Присваиваем значение tcl-переменной a строке res в нашем коде:*/
res = (char *)Tcl_GetVar(tcl_interp, "a", TCL_APPEND_VALUE);
/*Вычисляем средствами языка C длину прочитанной строки:*/
len = strlen(res);
/*Переводим длину в строку*/
slen[0] = '\0';
sprintf(slen, "%i", len);
/*Теперь полученное значение slen присваиваем Tcl-переменной lens:*/
Tcl_SetVar(tcl_interp, "lens", slen, TCL_GLOBAL_ONLY);
/*Чистим виджет, в который будет записана длина введенной строки*/
code = Tcl_Eval(tcl_interp, ".ent4 delete 0 end;");
/*И в чистый виджет вставляем полученное значене*/
code = Tcl_Eval(tcl_interp, ".ent4 insert 0 $lens;");
/*И возвращаемся*/
return TCL_OK;
}
int main (int argc, char *argv[]) {
/*Tcl/Tk - скрипт нашего примера */
char strtcl[] ="\
wm title . \"Пример программы на C с Tcl/Tk\";\
label .lab0 -text {strlen(};\
pack .lab0 -anchor {center} -side {left};\
entry .ent1 ;\
pack .ent1 -anchor {center} -side {left};\
label .lab2 -text {)};\
pack .lab2 -anchor {center} -side {left};\
button .but3 -text {=} -command {lenstr};\
pack .but3 -anchor {center} -side {left};\
entry .ent4 -width {5};\
pack .ent4 -pady {4} -side {top};\
pack .lab0 .ent1 .lab2 .but3 .ent4 -in {.};\
.ent4 delete 0 end;\
";
int code;
Tcl_FindExecutable(argv[0]);
/*Создание tcl-интерпретатора*/
tcl_interp = Tcl_CreateInterp();
/*Инициализация созданного tcl-интерпретатора*/
Tcl_Init(tcl_interp);
/*Инициализация Tk-интерпретатора в контексте созданного tcl-интерпретатора*/
Tk_Init(tcl_interp);
/*Загружаем наш Tcl/Tk код из строки*/
code = Tcl_Eval(tcl_interp, strtcl);
/*Но Tcl/Tk код можно загрузить и из файла:
code = Tcl_EvalFile(tcl_interp, filetcl);
*/
/*Добавляем к нашей кнопки вызов процедуры lenstr при ее нажатии*/
code = Tcl_Eval(tcl_interp, ".but3 configure -command lenstr;");
/*Связываем имя процедуры "lenstr" с функцией lenStr в этом C-коде*/
Tcl_CreateCommand(tcl_interp, "lenstr", (Tcl_CmdProc *)lenStr, NULL, NULL);
/*Главный цикл обработки событий от виджетов*/
Tk_MainLoop();
return 0;
}
Я думаю код не нуждается в дополнительных комментариях. Получить выполняемый код можно следующим образом:
$gcc -o test_c test_c.c -ltcl8.6 -ltk8.6
$
Если вы собираетесь писать приложение со сложным GUI, то целесообразно для его проектирования использовать дизайнеры. Это может быть и Vtcl, и TKproE-2.20 и другие. Я бы рекомендовал использовать TKproE. Из сохраненного проекта достаточно взять тело процедуры TKopenWindow и загрузить его с помощью функций Tcl_Eval или Tcl_EvalFile. В первом случае код вставляется в тело программы, например, присваивается переменной strtcl, как в нашем примере. Во втором случае сохраняется в файле и из него загружается.
Естественный вопрос, как обрабатывать события, например, нажатие кнопки. В этом случае ставится соответствие между именем функции в коде tcl (например, в опции –command у виджета button), который был загружен, и функцией в коде программы. В нашем примере это следующая строка:
/*Связываем имя процедуры "lenstr" с функцией lenStr в этом C-коде*/
Tcl_CreateCommand(tcl_interp, "lenstr", (Tcl_CmdProc *)lenStr, NULL, NULL);
Для обмена данными между tcl-интерпретатором и основной программой на языке C, могут, использоваться функции Tcl_GetVar и Tcl_SetVar (см. пример), Tcl_LinkVar и др.
Для разработки GUI-приложений с использованием Tk-виджетов на языке C++ разработана красивая библиотека CPPTK. Последнее ее обновление вышло в мае текущего года. Но мы будем иметь ввиду предпоследнюю версию, а именно CPPTK-1.0.2.
Использование этой библиотеки для разработки, подчеркиваю, для разработки графических приложений, позволяет забыть об интерфейсах библиотек libtcl и libtk (см. выше). Согласитесь, это немало, учитывая то, что интерфейс библиотеки CPPTK максимально приближен к интерфейсу Tcl/Tk и самое главное прекрасно документирован:
И так, библиотека CPPTK позволяет разрабатывать GUI-приложения на классических tk-виджетах. Но она настолько хорошо спроектирована, что перейти, а еще лучше, добавить поддержку тематических виджетов ttk не сосравляет никакого труда, что мы и сделали, добавив в первую очередь поддержку виджетов ttk::notebook и ttk::combobox.
Патч для библиотеки CPPTK-1.0.2 находится здесь
diff -ruN cpptk-1.0.2/base/cpptkbase.cc cpptk-1.0.2_with_ttk/base/cpptkbase.cc
--- cpptk-1.0.2/base/cpptkbase.cc 2017-12-12 09:58:00.269337115 +0300
+++ cpptk-1.0.2_with_ttk/base/cpptkbase.cc 2017-12-08 14:41:51.589205618 +0300
@@ -209,11 +209,16 @@
// refresh Tcl variables
linkCpptoTcl();
}
- catch (exception const &e)
+
+/*XXXXX*/
+// catch (exception const &e)
+ catch (std::exception const &e)
+
{
Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
return TCL_ERROR;
}
+
return TCL_OK;
}
diff -ruN cpptk-1.0.2/cpptk.cc cpptk-1.0.2_with_ttk/cpptk.cc
--- cpptk-1.0.2/cpptk.cc 2017-12-12 09:58:00.268337115 +0300
+++ cpptk-1.0.2_with_ttk/cpptk.cc 2017-12-11 20:10:09.699863718 +0300
@@ -226,6 +226,28 @@
return Expr(str);
}
+/*XXXXX*/
+Expr Tk::addtab(string const &w1,
+ string const &w2)
+{
+ string str("");
+ str += w1;
+ str += " add ";
+ str += w2;
+ str += " ";
+ return Expr(str);
+}
+Expr Tk::tab(string const &w1,
+ string const &w2)
+{
+ string str("");
+ str += w1;
+ str += " tab ";
+ str += w2;
+ str += " ";
+ return Expr(str);
+}
+
Expr Tk::panedwindow(string const &name)
{
@@ -254,6 +276,20 @@
str += name;
return Expr(str);
}
+
+/*XXXXX*/
+Expr Tk::combobox(string const &name)
+{
+ string str("ttk::combobox ");
+ str += name;
+ return Expr(str);
+}
+Expr Tk::notebook(string const &name)
+{
+ string str("ttk::notebook ");
+ str += name;
+ return Expr(str);
+}
Expr Tk::textw(string const &name)
{
diff -ruN cpptk-1.0.2/cpptkconstants.x cpptk-1.0.2_with_ttk/cpptkconstants.x
--- cpptk-1.0.2/cpptkconstants.x 2017-12-12 09:58:00.269337115 +0300
+++ cpptk-1.0.2_with_ttk/cpptkconstants.x 2017-12-08 17:51:55.772314308 +0300
@@ -81,6 +81,9 @@
CPPTK_CONSTANT(hourglass)
CPPTK_CONSTANT(horizontal)
CPPTK_CONSTANT(iconbitmap)
+//XXXXX
+CPPTK_CONSTANT(iconphoto)
+
CPPTK_CONSTANT(iconic)
CPPTK_CONSTANT(iconify)
CPPTK_CONSTANT(iconmask)
diff -ruN cpptk-1.0.2/cpptk.h cpptk-1.0.2_with_ttk/cpptk.h
--- cpptk-1.0.2/cpptk.h 2017-12-12 09:58:00.268337115 +0300
+++ cpptk-1.0.2_with_ttk/cpptk.h 2017-12-08 14:43:29.004206546 +0300
@@ -74,6 +74,12 @@
std::string const &w8 = std::string(),
std::string const &w9 = std::string(),
std::string const &w10 = std::string());
+/*XXXXX*/
+details::Expr addtab(std::string const &w1,
+ std::string const &w2 = std::string());
+details::Expr tab(std::string const &w1,
+ std::string const &w2 = std::string());
+
template <typename T\>
details::Expr pack(std::string const &option,
@@ -85,6 +91,27 @@
str += details::toString(t);
return details::Expr(str);
}
+/*XXXXX*/
+template <typename T\>
+details::Expr addtab(std::string const &option,
+ std::string const &w, T const &t)
+{
+ std::string str("addtab ");
+ str += option; str += " ";
+ str += w; str += " ";
+ str += details::toString(t);
+ return details::Expr(str);
+}
+template <typename T\>
+details::Expr tab(std::string const &option,
+ std::string const &w, T const &t)
+{
+ std::string str("tab ");
+ str += option; str += " ";
+ str += w; str += " ";
+ str += details::toString(t);
+ return details::Expr(str);
+}
details::Expr panedwindow(std::string const &name);
@@ -93,6 +120,9 @@
details::Expr scrollbar(std::string const &name);
details::Expr spinbox(std::string const &name);
+/*XXXXX*/
+details::Expr combobox(std::string const &name);
+details::Expr notebook(std::string const &name);
details::Expr textw(std::string const &name);
diff -ruN cpptk-1.0.2/cpptkoptions.x cpptk-1.0.2_with_ttk/cpptkoptions.x
--- cpptk-1.0.2/cpptkoptions.x 2017-12-12 09:58:00.269337115 +0300
+++ cpptk-1.0.2_with_ttk/cpptkoptions.x 2017-12-08 18:05:51.108322269 +0300
@@ -49,6 +49,9 @@
CPPTK_OPTION(columnspan, false)
CPPTK_OPTION(compositingrule, false)
CPPTK_OPTION(compound, false)
+//XXXXX
+CPPTK_OPTION(padding, false)
+
CPPTK_OPTION(confine, false)
CPPTK_OPTION(container, false)
CPPTK_OPTION(cursor, false)
@@ -76,6 +79,9 @@
CPPTK_OPTION(fg, false)
CPPTK_OPTION(fgstipple, false)
CPPTK_OPTION(file, true)
+//XXXXX
+CPPTK_OPTION(data, true)
+
CPPTK_OPTION(fill, false)
CPPTK_OPTION(font, false)
// TODO: fontmap option of the canvas postscript command
Этот патч добавляет не только поддержку новых виджетов, то и поддержку режима –data при работе с images (images(create,photo, ''myimage'' –date (''PEM/base64-данные'');). К сожалению, при укладке в спойлер строки +template пришлось заменить на +template <typename T\> (в противном случае спойлер неверно отображал текст). Необходимо это учитывать и провести обратную замену.
Применить патч можно следующим образом. Создайте каталог. В него поместите каталог проекта CPPTK. В нем же сохраните, скажем, в файле patchForCPPTK-1.0.2.patch патч из спойлера (с учетом замечания) и, находясь в этом каталоге, примените патч:
$patch –p0 < patchForCPPTK-1.0.2.patch
$
Все, теперь у вас есть библиотека CPPTK с поддержкой новых виджетов. И все же писать GUI вручную неблагодарное дело. Для проектирования самого GUI все же удобно использовать дизайнер TKproE. Для получения из готового tcl-скрипта программы на C++ с библиотекой CPPTK разработан простой tcl-скрипт convertFromTclToCPPTK.tcl:
tcl-скрипт convertFromTclToCPPTK.tcl
#!/usr/bin/tclsh
# 1 -- source file from tkproe
#Soft
## Procedure: parseConfig
proc ::parseConfig {w data cfile} {
set ldata $data
set len [llength $ldata]
#puts $len
set two ""
set tree ""
set first [lindex $ldata 0]
if { $len \> 1 } {
set two [lindex $ldata 1]
}
if { $len \> 2 } {
set tree [lindex $ldata 2]
}
if {$first == "wm"} {
set wmstr "wm($two"
for {set i 2} {$i < $len} {incr i} {
set par [lindex $ldata $i]
set a ", \"$par\""
set wmstr "$wmstr$a"
}
set a ");"
set wmstr "$wmstr$a"
puts "\t$wmstr"
return
}
#Определяем widget tk
set tkWid "frame canvas button entry label message listbox text menubutton menu scrollbar scale checkbutton radiobutton toplevel labelframe spinbox panedwindow"
set ttkWid "ttk::notebook ttk::combobox"
set beg [string first $first $tkWid]
if { $beg != -1 } {
set initI 2
set wmstr "\t$first (\"$two\""
# set wmstr "$first(\"$two\""
if { [string range $tree 0 0 ] != "-" } {
set wmstr "$wmstr, \"$tree\""
incr initI
}
set wmstr "$wmstr) "
set lenstr [string length $wmstr]
for {set i $initI} {$i < $len} {incr i} {
set par [lindex $ldata $i]
incr i
set parVal [lindex $ldata $i]
if { $par == "-variable" || $par == "-textvariable"} {
set wmstr "$wmstr $par ($parVal)"
} else {
set wmstr "$wmstr $par (\"$parVal\")"
}
incr lenstr [string length $par]
incr lenstr [string length $parVal]
if {$lenstr \> 70} {
set wmstr "$wmstr\n\t\t"
set lenstr 10
}
}
set wmstr "$wmstr;"
puts $wmstr
return
}
#addTab to notebook
set beg [string first " add ." $data]
if { $beg != -1 } {
set initI 2
set wmstr "\taddtab (\"$first\""
# set wmstr "$first(\"$two\""
if { [string range $tree 0 0 ] != "-" } {
set wmstr "$wmstr, \"$tree\""
incr initI
}
set wmstr "$wmstr) "
for {set i $initI} {$i < $len} {incr i} {
set par [lindex $ldata $i]
incr i
if { $par == "-image" } {continue}
set parVal [lindex $ldata $i]
if { $par == "-variable" || $par == "-textvariable"} {
set wmstr "$wmstr $par ($parVal)"
} else {
set wmstr "$wmstr $par (\"$parVal\")"
}
}
set wmstr "$wmstr;"
puts $wmstr
return
}
#ttk::notebook
set beg [string first "ttk::notebook" $data]
if { $beg != -1 } {
set initI 2
set wmstr "\tnotebook (\"$two\""
# set wmstr "$first(\"$two\""
if { [string range $tree 0 0 ] != "-" } {
set wmstr "$wmstr, \"$tree\""
incr initI
}
set wmstr "$wmstr) "
for {set i $initI} {$i < $len} {incr i} {
set par [lindex $ldata $i]
incr i
# if { $par == "-image" } {continue}
if { $par == "-variable" } {continue}
if { $par == "-textvariable" } {continue}
if { $par == "-takefocus" } {continue}
set parVal [lindex $ldata $i]
set wmstr "$wmstr $par (\"$parVal\")"
}
set wmstr "$wmstr;"
puts $wmstr
return
}
#ttk::combobox
set beg [string first "ttk::combobox" $data]
if { $beg != -1 } {
set initI 2
set wmstr "\tcombobox (\"$two\""
# set wmstr "$first(\"$two\""
if { [string range $tree 0 0 ] != "-" } {
set wmstr "$wmstr, \"$tree\""
incr initI
}
set wmstr "$wmstr) "
for {set i $initI} {$i < $len} {incr i} {
set par [lindex $ldata $i]
incr i
# if { $par == "-variable" } {continue}
# if { $par == "-textvariable" } {continue}
if { $par == "-takefocus" } {continue}
# if { $par == "-relwidth" } {continue}
set parVal [lindex $ldata $i]
if { $par == "-variable" || $par == "-textvariable"} {
set wmstr "$wmstr $par ($parVal)"
} else {
set wmstr "$wmstr $par (\"$parVal\")"
}
}
set wmstr "$wmstr;"
puts $wmstr
return
}
#tkPlace
set tkPlace "tkPlace: pack place grid"
set beg [string first $first $tkPlace]
if { $beg != -1 } {
set tire 0
set initI 2
set wmstr "\t$first (\"$two\""
set lenstr [string length $wmstr]
for {set i $initI} {$i < $len} {incr i} {
set par [lindex $ldata $i]
if { [string range $par 0 0 ] != "-" } {
set wmstr "$wmstr, \"$par\""
continue
} else {
if { $tire == 0} {
incr tire
set wmstr "$wmstr) "
}
}
if {$tire == 1} {
incr i
}
if { $par == "-variable" } {continue}
if { $par == "-textvariable" } {continue}
if { $par == "-relwidth" } {continue}
if { $par == "-fill" && $first == "pack" } {continue}
set parVal [lindex $ldata $i]
if {$parVal == ".\}"} {
set parVal "."
}
set wmstr "$wmstr $par (\"$parVal\")"
incr lenstr [string length $par]
incr lenstr [string length $parVal]
if {$lenstr \> 70} {
set wmstr "$wmstr\n\t\t"
set lenstr 10
}
}
set wmstr "$wmstr;"
puts $wmstr
return
}
if {$two == "configure"} {
set wmstr "\t\"$first\" << configure() "
for {set i 2} {$i < $len} {incr i} {
set par [lindex $ldata $i]
incr i
set parVal [lindex $ldata $i]
set wmstr "$wmstr $par (\"$parVal\")"
}
set wmstr "$wmstr;"
puts $wmstr
return
}
return
}
set largv [llength $argv]
if {$largv != 1} {
puts "Usage: [info script] <file tcl from TKproE\>\n"
exit
}
set fconf [file exists "$argv"]
if { $fconf == "0" } {
puts "File=\"$argv\" don't exist\n"
puts "Usage: [info script] <file tcl from Page\>\n"
exit
}
set file $argv
proc findFile {} {
set types {
{"GUI файл" {*.tcl} }
{"Любой файл" *}
}
set file ""
set homeDir $env(HOME)
set file [tk_getOpenFile -filetypes $types -parent . -initialdir $homeDir]
puts "You selected file \"$file\""
if {[string compare $file ""] == 0} {
return ""
}
}
# read the file one line at a time
set fp [open $file r]
fconfigure $fp -buffering line
puts "//Get file tcl from=$file"
#"proc TPopenWindow"
#"proc TPcloseWindow"
set parseStr 0
puts "#include \"cpptk.h\""
puts "#include <iostream\>\n"
puts "using namespace Tk;"
puts "using namespace std;\n"
puts "int main(int, char *argv\[\])\n\{\n try\n {\n\tinit(argv\[0\]);"
while 1 {
gets $fp data
if [eof $fp] break
if {$data == ""} continue
set com [string range $data 0 0]
if {$com == "\n" || $com == "#"} continue
set data [string trim $data]
set len [string first "proc TPopenWindow" $data 0]
if {$len != -1 } {
set parseStr 1
puts "/*$data\}*/"
continue
}
set len [string first "proc TPcloseWindow" $data 0]
if {$len != -1 } {
set parseStr 0
puts "/*$data\}*/\n"
continue
}
if { $parseStr == 0 } {continue}
parseConfig . $data $file
}
puts "\trunEventLoop();\n }\n catch (exception const &e)\n {\n\tcerr << \"Error: \" << e.what() << '\\n';\n \}\n\}"
close $fp
exit
Для получения программы на C++ достаточно выполнить этот скрипт:
$ convertFromTclToCPPTK.tcl <tcl-скрипт из TKproE> > <имя файла для сохранения C++ - кода>
$
В качестве примера рассмотрим разработку программы формирования усовершенствованной электронной подписи с библиотекой SSF («Secure Store and Forward»), используемой в продуктах компании SAP AG для обеспечения криптографической защиту электронных документов за счет использования механизмов электронной подписи и шифрования с использованием российских криптоалгоритмов (ГОСТ 28147-89, ГОСТ Р 34.11-94, ГОСТ Р 34.11-2012, ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012). Проект GUI в дизайнере TKproE выглядит следующим образом:
Скрипт этого проекта находится здесь
# Generated by TKproE 2.20 - Tue Dec 12 12:50:32 MSK 2017
encoding system utf-8
global myHOME
set myHOME $env(HOME)
# Load all images
# Define named fonts
# Global variable initialization
proc TPinitVars {} {
# Initialize global variables
namespace eval :: {;#Creating namespace ::;}
set {::selectedButton} {}
array set {::vTcl} {}
set ::TPexclusions(user_namespace) {}
set ::TPprojType TCL_TK
}
# Toplevel window procedures
proc TPopenWindow. {} {
# CLONEPATH = .
# Cloned Tue Dec 12 12:50:32 MSK 2017
. configure -background {#00F5FF}
bindtags . {. Tkproe.tcl all}
wm aspect .
wm focusmodel . passive
wm grid .
wm geometry . 723x618+383+57
wm iconmask .
wm iconposition .
wm maxsize . 1585 870
wm minsize . 1 1
wm overrideredirect . 0
wm positionfrom . user
wm resizable . 1 1
wm sizefrom .
wm state . normal
wm transient .
labelframe .lfSSF -borderwidth {4} -foreground {#141312} -relief {ridge} -text {Выберите библиотеку SSF} -background {#FFDEAD} -height {100} -padx {4} -width {100}
entry .lfSSF.entSSF -background {#FFFAFA} -foreground {#141312} -highlightbackground {#ffffff} -highlightcolor {#141312} -selectbackground {#418bd4} -selectforeground {#ffffff} -width {40}
pack .lfSSF.entSSF -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left
button .lfSSF.butSSF -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -text {Ваш выбор}
pack .lfSSF.butSSF -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 9 -pady 0 -side right
pack .lfSSF -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 10 -side top
pack .lfSSF.entSSF .lfSSF.butSSF -in .lfSSF
ttk::notebook .nbSSF -width {700} -height {400} -padding {7}
.nbSSF state {}
frame .nbSSF.frameNB1 -borderwidth {4} -relief {sunken} -background {#FF7256} -height {30} -highlightbackground {#e0dfde} -highlightcolor {#141312} -width {30}
label .nbSSF.frameNB1.labLogo -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -height {329} -highlightbackground {#e0dfde} -highlightcolor {#141312} -relief {raised} -text {labLogo} -width {509}
pack .nbSSF.frameNB1.labLogo -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 28 -side top
pack .nbSSF.frameNB1.labLogo -in .nbSSF.frameNB1
frame .nbSSF.frameNB2 -borderwidth {2} -relief {raised} -background {#FF4500} -height {30} -highlightbackground {#e0dfde} -highlightcolor {#141312} -pady {19} -width {30}
labelframe .nbSSF.frameNB2.lfSignDoc -borderwidth {4} -foreground {#141312} -relief {ridge} -text {Подписываемый документ} -background {#e0dfde} -height {100} -width {100}
entry .nbSSF.frameNB2.lfSignDoc.entSignDoc -background {#FFFAFA} -foreground {#141312} -highlightbackground {#ffffff} -highlightcolor {#141312} -selectbackground {#418bd4} -selectforeground {#ffffff} -width {40}
pack .nbSSF.frameNB2.lfSignDoc.entSignDoc -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 5 -pady 0 -side left
button .nbSSF.frameNB2.lfSignDoc.butSignDoc -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -text {Выберите}
pack .nbSSF.frameNB2.lfSignDoc.butSignDoc -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 6 -pady 0 -side top
pack .nbSSF.frameNB2.lfSignDoc -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 6 -side top
pack .nbSSF.frameNB2.lfSignDoc.entSignDoc .nbSSF.frameNB2.lfSignDoc.butSignDoc -in .nbSSF.frameNB2.lfSignDoc
labelframe .nbSSF.frameNB2.lfForType -borderwidth {4} -foreground {#141312} -relief {ridge} -text {Формат и тип подписи} -background {#e0dfde} -height {100} -padx {1} -pady {5} -width {100}
ttk::combobox .nbSSF.frameNB2.lfForType.comboFor -values {PKCS7 CADES_BES CADES_XLT1} -cursor {xterm}
.nbSSF.frameNB2.lfForType.comboFor state {}
pack .nbSSF.frameNB2.lfForType.comboFor -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 4 -pady 0 -side left
radiobutton .nbSSF.frameNB2.lfForType.radAtt -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -text {Присоединенная} -value {1}
pack .nbSSF.frameNB2.lfForType.radAtt -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 26 -pady 0 -side left
radiobutton .nbSSF.frameNB2.lfForType.radDet -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -text {Отсоединенная} -value {0}
pack .nbSSF.frameNB2.lfForType.radDet -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 13 -pady 0 -side top
pack .nbSSF.frameNB2.lfForType -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 16 -side top
pack .nbSSF.frameNB2.lfForType.comboFor .nbSSF.frameNB2.lfForType.radAtt .nbSSF.frameNB2.lfForType.radDet -in .nbSSF.frameNB2.lfForType
labelframe .nbSSF.frameNB2.lfCert -borderwidth {4} -foreground {#141312} -relief {ridge} -text {Сертификат для подписи} -background {#e0dfde} -height {100} -width {100}
entry .nbSSF.frameNB2.lfCert.entCert -background {#FFFAFA} -foreground {#141312} -highlightbackground {#ffffff} -highlightcolor {#141312} -selectbackground {#418bd4} -selectforeground {#ffffff} -width {40}
pack .nbSSF.frameNB2.lfCert.entCert -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 9 -pady 0 -side left
button .nbSSF.frameNB2.lfCert.butCert -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -text {Укажите путь}
pack .nbSSF.frameNB2.lfCert.butCert -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left
pack .nbSSF.frameNB2.lfCert -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 8 -side top
pack .nbSSF.frameNB2.lfCert.entCert .nbSSF.frameNB2.lfCert.butCert -in .nbSSF.frameNB2.lfCert
labelframe .nbSSF.frameNB2.lfAtCert -borderwidth {4} -foreground {#141312} -relief {ridge} -text {Как поступить с сертификатом} -background {#00FF00} -height {100} -width {100}
radiobutton .nbSSF.frameNB2.lfAtCert.radAtCert -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -text {Включить в подпись} -value {1}
pack .nbSSF.frameNB2.lfAtCert.radAtCert -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side left
radiobutton .nbSSF.frameNB2.lfAtCert.radDetCert -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -text {Не включать} -value {0}
pack .nbSSF.frameNB2.lfAtCert.radDetCert -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 10 -pady 0 -side top
pack .nbSSF.frameNB2.lfAtCert -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top
pack .nbSSF.frameNB2.lfAtCert.radAtCert .nbSSF.frameNB2.lfAtCert.radDetCert -in .nbSSF.frameNB2.lfAtCert
button .nbSSF.frameNB2.butSign -activebackground {#e0dfde} -activeforeground {#141312} -background {#20B2AA} -borderwidth {7} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -relief {ridge} -text {Сформировать подпись}
pack .nbSSF.frameNB2.butSign -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 14 -side top
pack .nbSSF.frameNB2.lfSignDoc .nbSSF.frameNB2.lfForType .nbSSF.frameNB2.lfCert .nbSSF.frameNB2.lfAtCert .nbSSF.frameNB2.butSign -in .nbSSF.frameNB2
frame .nbSSF.frameNB3 -borderwidth {2} -relief {raised} -background {#e0dfde} -height {30} -highlightbackground {#e0dfde} -highlightcolor {#141312} -width {30}
pack .nbSSF -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 0 -side top
labelframe .lfP11 -borderwidth {4} -foreground {#141312} -relief {ridge} -text {Хранилище вашего закрытого ключа} -background {#FFE4B5} -height {100} -width {100}
entry .lfP11.entP11 -background {#FFFAFA} -foreground {#141312} -highlightbackground {#ffffff} -highlightcolor {#141312} -selectbackground {#418bd4} -selectforeground {#ffffff} -width {40}
pack .lfP11.entP11 -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 8 -pady 0 -side left
button .lfP11.butP11 -activebackground {#e0dfde} -activeforeground {#141312} -background {#e0dfde} -borderwidth {4} -foreground {#141312} -highlightbackground {#e0dfde} -highlightcolor {#141312} -relief {ridge} -text {Выбор за вами}
pack .lfP11.butP11 -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 9 -pady 1 -side top
pack .lfP11 -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 -padx 0 -pady 14 -side top
pack .lfP11.entP11 .lfP11.butP11 -in .lfP11
.nbSSF add .nbSSF.frameNB1 -padding 0 -sticky nsew -state normal -text Логотип -image {} -compound none -underline -1
.nbSSF add .nbSSF.frameNB2 -padding 0 -sticky nsew -state normal -text Подписать -image {} -compound none -underline -1
.nbSSF add .nbSSF.frameNB3 -padding 0 -sticky nsew -state normal -text Проверить -image {} -compound none -underline -1
pack .lfSSF .nbSSF .lfP11 -in .}
proc TPcloseWindow. {} {
wm state . withdrawn}
# User created procedures
namespace eval :: {
#Creating namespace ::
}
# Display and start the application
if {[info proc TPstartupSrc] != {}} { TPstartupSrc }
TPinitVars
TPopenWindow.
if {[info proc TPendSrc] != {}} { TPendSrc }
# End of TKproE generated code
#P.S. К сожалению при укладке в спойлер символы > пришлось заменить на \>
#При сохранении скрипта выполните обратную замену.
</spoiler>
Сохранив скрипт в файле, например, forBook.tcl, любой может его загрузить в дизайнер TKproE и увидеть знакомую уже картинку (см. выше). Теперь, чтобы получить код C++ воспользуемся скриптом convertFromTclToCPPTK.tcl:
<source lang="bash">$ convertFromTclToCPPTK.tcl forBook.tcl >forBook.cc
$
Полученный код forBook.cc можно увидеть здесь
//Get file tcl from=forBook.tcl
#include "cpptk.h"
/*К сожалению при укладке в спойлер в следующей строке пришлось заменить > на \>
сделайте обратную замену*/
#include <iostream\>
using namespace Tk;
using namespace std;
int main(int, char *argv[])
{
try
{
init(argv[0]);
/*proc TPopenWindow. {} {}*/
"." << configure() -background ("#00F5FF");
wm(aspect, ".");
wm(focusmodel, ".", "passive");
wm(grid, ".");
wm(geometry, ".", "723x618+383+57");
wm(iconmask, ".");
wm(iconposition, ".");
wm(maxsize, ".", "1585", "870");
wm(minsize, ".", "1", "1");
wm(overrideredirect, ".", "0");
wm(positionfrom, ".", "user");
wm(resizable, ".", "1", "1");
wm(sizefrom, ".");
wm(state, ".", "normal");
wm(transient, ".");
labelframe (".lfSSF") -borderwidth ("4") -foreground ("#141312") -relief ("ridge") -text ("Выберите библиотеку SSF")
-background ("#FFDEAD") -height ("100") -padx ("4") -width ("100");
entry (".lfSSF.entSSF") -background ("#FFFAFA") -foreground ("#141312") -highlightbackground ("#ffffff")
-highlightcolor ("#141312") -selectbackground ("#418bd4") -selectforeground ("#ffffff")
-width ("40");
pack (".lfSSF.entSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("0") -side ("left")
;
button (".lfSSF.butSSF") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Ваш выбор");
pack (".lfSSF.butSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("9") -pady ("0") -side ("right")
;
pack (".lfSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("10") -side ("top")
;
pack (".lfSSF.entSSF", ".lfSSF.butSSF") -in (".lfSSF");
notebook (".nbSSF") -width ("700") -height ("400") -padding ("7");
frame (".nbSSF.frameNB1") -borderwidth ("4") -relief ("sunken") -background ("#FF7256")
-height ("30") -highlightbackground ("#e0dfde") -highlightcolor ("#141312") -width ("30")
;
label (".nbSSF.frameNB1.labLogo") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -foreground ("#141312") -height ("329") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -relief ("raised") -text ("labLogo") -width ("509");
pack (".nbSSF.frameNB1.labLogo") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("28") -side ("top");
pack (".nbSSF.frameNB1.labLogo") -in (".nbSSF.frameNB1");
frame (".nbSSF.frameNB2") -borderwidth ("2") -relief ("raised") -background ("#FF4500")
-height ("30") -highlightbackground ("#e0dfde") -highlightcolor ("#141312") -pady ("19")
-width ("30");
labelframe (".nbSSF.frameNB2.lfSignDoc") -borderwidth ("4") -foreground ("#141312")
-relief ("ridge") -text ("Подписываемый документ") -background ("#e0dfde") -height ("100")
-width ("100");
entry (".nbSSF.frameNB2.lfSignDoc.entSignDoc") -background ("#FFFAFA") -foreground ("#141312")
-highlightbackground ("#ffffff") -highlightcolor ("#141312") -selectbackground ("#418bd4")
-selectforeground ("#ffffff") -width ("40");
pack (".nbSSF.frameNB2.lfSignDoc.entSignDoc") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("5") -pady ("0") -side ("left");
button (".nbSSF.frameNB2.lfSignDoc.butSignDoc") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Выберите");
pack (".nbSSF.frameNB2.lfSignDoc.butSignDoc") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("6") -pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfSignDoc") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("6") -side ("top");
pack (".nbSSF.frameNB2.lfSignDoc.entSignDoc", ".nbSSF.frameNB2.lfSignDoc.butSignDoc") -in (".nbSSF.frameNB2.lfSignDoc")
;
labelframe (".nbSSF.frameNB2.lfForType") -borderwidth ("4") -foreground ("#141312")
-relief ("ridge") -text ("Формат и тип подписи") -background ("#e0dfde") -height ("100")
-padx ("1") -pady ("5") -width ("100");
combobox (".nbSSF.frameNB2.lfForType.comboFor") -values ("PKCS7 CADES_BES CADES_XLT1") -cursor ("xterm");
pack (".nbSSF.frameNB2.lfForType.comboFor") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("4") -pady ("0") -side ("left");
radiobutton (".nbSSF.frameNB2.lfForType.radAtt") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Присоединенная") -value ("1");
pack (".nbSSF.frameNB2.lfForType.radAtt") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("26") -pady ("0") -side ("left");
radiobutton (".nbSSF.frameNB2.lfForType.radDet") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Отсоединенная") -value ("0");
pack (".nbSSF.frameNB2.lfForType.radDet") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("13") -pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfForType") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("16") -side ("top");
pack (".nbSSF.frameNB2.lfForType.comboFor", ".nbSSF.frameNB2.lfForType.radAtt", ".nbSSF.frameNB2.lfForType.radDet") -in (".nbSSF.frameNB2.lfForType")
;
labelframe (".nbSSF.frameNB2.lfCert") -borderwidth ("4") -foreground ("#141312") -relief ("ridge")
-text ("Сертификат для подписи") -background ("#e0dfde") -height ("100") -width ("100")
;
entry (".nbSSF.frameNB2.lfCert.entCert") -background ("#FFFAFA") -foreground ("#141312")
-highlightbackground ("#ffffff") -highlightcolor ("#141312") -selectbackground ("#418bd4")
-selectforeground ("#ffffff") -width ("40");
pack (".nbSSF.frameNB2.lfCert.entCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("9") -pady ("0") -side ("left");
button (".nbSSF.frameNB2.lfCert.butCert") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Укажите путь");
pack (".nbSSF.frameNB2.lfCert.butCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("0") -pady ("0") -side ("left");
pack (".nbSSF.frameNB2.lfCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("8") -side ("top");
pack (".nbSSF.frameNB2.lfCert.entCert", ".nbSSF.frameNB2.lfCert.butCert") -in (".nbSSF.frameNB2.lfCert");
labelframe (".nbSSF.frameNB2.lfAtCert") -borderwidth ("4") -foreground ("#141312")
-relief ("ridge") -text ("Как поступить с сертификатом") -background ("#00FF00")
-height ("100") -width ("100");
radiobutton (".nbSSF.frameNB2.lfAtCert.radAtCert") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Включить в подпись") -value ("1");
pack (".nbSSF.frameNB2.lfAtCert.radAtCert") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("0") -pady ("0") -side ("left");
radiobutton (".nbSSF.frameNB2.lfAtCert.radDetCert") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Не включать") -value ("0");
pack (".nbSSF.frameNB2.lfAtCert.radDetCert") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("10") -pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfAtCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfAtCert.radAtCert", ".nbSSF.frameNB2.lfAtCert.radDetCert") -in (".nbSSF.frameNB2.lfAtCert");
button (".nbSSF.frameNB2.butSign") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#20B2AA") -borderwidth ("7") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -relief ("ridge") -text ("Сформировать подпись");
pack (".nbSSF.frameNB2.butSign") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("14") -side ("top");
pack (".nbSSF.frameNB2.lfSignDoc", ".nbSSF.frameNB2.lfForType", ".nbSSF.frameNB2.lfCert", ".nbSSF.frameNB2.lfAtCert", ".nbSSF.frameNB2.butSign") -in (".nbSSF.frameNB2");
frame (".nbSSF.frameNB3") -borderwidth ("2") -relief ("raised") -background ("#e0dfde")
-height ("30") -highlightbackground ("#e0dfde") -highlightcolor ("#141312") -width ("30")
;
pack (".nbSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("0") -side ("top");
labelframe (".lfP11") -borderwidth ("4") -foreground ("#141312") -relief ("ridge") -text ("Хранилище вашего закрытого ключа")
-background ("#FFE4B5") -height ("100") -width ("100");
entry (".lfP11.entP11") -background ("#FFFAFA") -foreground ("#141312") -highlightbackground ("#ffffff")
-highlightcolor ("#141312") -selectbackground ("#418bd4") -selectforeground ("#ffffff")
-width ("40");
pack (".lfP11.entP11") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("8") -pady ("0") -side ("left")
;
button (".lfP11.butP11") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -borderwidth ("4") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -relief ("ridge") -text ("Выбор за вами");
pack (".lfP11.butP11") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("9") -pady ("1") -side ("top")
;
pack (".lfP11") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("14") -side ("top")
;
pack (".lfP11.entP11", ".lfP11.butP11") -in (".lfP11");
addtab (".nbSSF", ".nbSSF.frameNB1") -padding ("0") -sticky ("nsew") -state ("normal") -text ("Логотип") -compound ("none") -underline ("-1");
addtab (".nbSSF", ".nbSSF.frameNB2") -padding ("0") -sticky ("nsew") -state ("normal") -text ("Подписать") -compound ("none") -underline ("-1");
addtab (".nbSSF", ".nbSSF.frameNB3") -padding ("0") -sticky ("nsew") -state ("normal") -text ("Проверить") -compound ("none") -underline ("-1");
pack (".lfSSF", ".nbSSF", ".lfP11") -in (".");
/*proc TPcloseWindow. {} {}*/
runEventLoop();
}
catch (exception const &e)
{
cerr << "Error: " << e.what() << '\n';
}
}
Для получения банарного кода положим файл forBook.cc в каталог с пропатченной библиотекой CPPTK (см.выше) и выполним следующую команду:
$ g++ -DUSE_INTERP_RESULT cpptk.cc base/cpptkbase.cc -o forBook forBook.cc -I./cpptk -Ibase -ltcl8.6 -ltk8.6 –pthread
$
Если теперь запустить полученный бинарный модуль forBook, то на экране монитора мы увидим знакомое изображение (см. выше). К сожалению, нажатие кнопок не приведет ни к какому результату, да и иконка нас не устраивает. И мы дописываем полученную программу. Включаем в нее код иконки:
images(create, photo, "stamp_32x32") -data (
"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr …
");
Привязываем ее к главному окну:
wm (iconphoto, ".", "stamp_32x32");
Но самое главное, что мы делаем, это привязываем к кнопкам определенные функции, которые необходимо будет выполнить при их нажатии:
".lfSSF.butSSF" << configure () -command (compute);
".nbSSF.frameNB2.lfSignDoc.butSignDoc" << configure () -command (findDoc);
".nbSSF.frameNB2.lfCert.butCert" << configure () -command (findCert);
".lfP11.butP11" << configure () -command (findPrivKey);
".nbSSF.frameNB2.lfForType.radAtt" << configure () -command (updateRad);
".nbSSF.frameNB2.lfForType.radDet" << configure () -command (updateRad);
".nbSSF.frameNB2.lfAtCert.radAtCert" << configure () -command (updateRad);
".nbSSF.frameNB2.lfAtCert.radDetCert" << configure () -command (updateRad);
".nbSSF.frameNB2.butSign" << configure () -command (createSign);
Естественно, пишем код самих функций.
В законченном виде код выглядит так
//Get file tcl from=GUIforSSFfromPAGE_PACK.tcl
#include "cpptk.h"
/*К сожалению при укладке в спойлер в следующей строке пришлось заменить > на \>
сделайте обратную замену*/
#include <iostream\>
using namespace Tk;
using namespace std;
string str;
string selSignType = "1";
string selCert = "1";
int len;
void compute()
{
string fileName(tk_getOpenFile() -filetypes ("{{Библиотека SSF} {.so}} {{Библиотека SSF MS} {.dll}} {{Любой файл} {*}}"));
".lfSSF.entSSF" << deleteentry (0, end);
".lfSSF.entSSF" << insert(end, fileName.c_str());
// ".nbSSF.frameNB2" << configure () -state (normal);
// ".nbSSF.frameNB3" << configure () -state (normal);
tab (".nbSSF", ".nbSSF.frameNB2") -state ("normal");
tab (".nbSSF", ".nbSSF.frameNB3") -state ("normal");
".nbSSF" << select (".nbSSF.frameNB2");
cout << "Hello Button C++/Tk!" << endl;
/*К сожалению при укладке в спойлер в следующей строке пришлось заменить > на \>
сделайте обратную замену*/
len = static_cast<int\>(str.size());
}
void findDoc()
{
string fileName(tk_getOpenFile() -filetypes ("{{Документ для подписи} {.doc}} {{Текстовый документ} {.txt}} {{Любой документ} {*}}"));
".nbSSF.frameNB2.lfSignDoc.entSignDoc" << deleteentry (0, end);
".nbSSF.frameNB2.lfSignDoc.entSignDoc" << insert(end, fileName.c_str());
}
void findCert()
{
string fileName(tk_getOpenFile() -filetypes ("{{Сертификат в формате DER} {.der}} {{Сертификат в формате DER} {.cer}} \
{{Сертификат в формате PEM} {.pem}} {{Сертификат в формате PEM} {.crt}} {{Любой файл} {*}}"));
".nbSSF.frameNB2.lfCert.entCert" << deleteentry (0, end);
".nbSSF.frameNB2.lfCert.entCert" << insert(end, fileName.c_str());
".lfP11.butP11" << configure () -state (normal);
}
void findPrivKey()
{
string fileName(tk_getOpenFile() -filetypes ("{{Хранилище в PKCS#12} {.p12}} {{Хранилище в PKCS#12} {.pfx}} \
{{Библиотека PKCS#11} {.so}} {{Библиотека PKCS#11 MS} {.dll}} {{Любой файл} {*}}"));
".lfP11.entP11" << deleteentry (0, end);
".lfP11.entP11" << insert(end, fileName.c_str());
".nbSSF.frameNB2.butSign" << configure () -state (normal);
}
void updateRad()
{
".nbSSF.frameNB2.lfForType.radAtt" << configure () -state (normal);
".nbSSF.frameNB2.lfForType.radDet" << configure () -state (normal);
".nbSSF.frameNB2.lfAtCert.radAtCert" << configure () -state (normal);
".nbSSF.frameNB2.lfAtCert.radDetCert" << configure () -state (normal);
// update();
}
void createSign()
{
char mesSign [1000];
cout << "Формирование подписи" << endl;
cout << selSignType.c_str() << endl;
cout << selCert.c_str() << endl;
// string response(tk_dialog(".", "Будете подписывать?", "Вы собираетесь подписать файл\n\n", warning, "OK", "OK", "Cancel"));
string content(".nbSSF.frameNB2.lfSignDoc.entSignDoc" << get());
strcpy(mesSign, "Вы собираетесь подписать файл\n");
if (strlen (content.c_str()) == 0)
return;
strcat(mesSign, content.c_str());
strcat(mesSign, "\nФормат подписи = ");
string content1(".nbSSF.frameNB2.lfForType.comboFor" << get());
strcat(mesSign, content1.c_str());
if (strcmp(selSignType.c_str(), "1")) {
strcat(mesSign, "\nПодпись не будет содержать документа\n");
} else {
strcat(mesSign, "\nДокумент включается в подпись\n");
}
strcat(mesSign, "Ваш сертификат из файла\n");
string content2(".nbSSF.frameNB2.lfCert.entCert" << get());
if (strlen (content2.c_str()) == 0)
return;
strcat(mesSign, content2.c_str());
if (strcmp(selCert.c_str(), "1")) {
strcat(mesSign, "\nНе будет включен в подпись\n");
} else {
strcat(mesSign, "\nбудет включен в подпись\n");
}
strcat(mesSign, "Ваш закрытый ключ будет будет получен посредством\n\n");
string content3(".lfP11.entP11" << get());
if (strlen (content3.c_str()) == 0)
return;
strcat(mesSign, content3.c_str());
string response(tk_messageBox() -title("Подписываем документ") -icon(question) -messagetext (mesSign) -messagetype (okcancel));
cout << response.c_str() << endl;
}
int main(int, char *argv[])
{
try
{
images(create, photo, "stamp_32x32") -data (
"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\
RK5CYII=");
init(argv[0]);
/*proc TPopenWindow. {} {}*/
"." << configure() -background ("#00F5FF");
fonts( configure, "TkDefaultFont") -size(12);
wm(title, ".", "Формирование Электронной Подписи (PKCS7, CADES_BES, CADES_XLT1)");
wm(aspect, ".");
wm(focusmodel, ".", "passive");
wm(grid, ".");
wm(geometry, ".", "723x618+383+57");
wm(iconmask, ".");
wm(iconposition, ".");
wm(maxsize, ".", "1585", "870");
wm(minsize, ".", "1", "1");
wm(overrideredirect, ".", "0");
wm(positionfrom, ".", "user");
wm(resizable, ".", "1", "1");
wm(sizefrom, ".");
wm(state, ".", "normal");
wm(transient, ".");
labelframe (".lfSSF") -borderwidth ("4") -foreground ("#141312") -relief ("ridge") -text ("Выберите библиотеку SSF")
-background ("#FFDEAD") -height ("100") -padx ("4") -width ("100");
entry (".lfSSF.entSSF") -background ("#FFFAFA") -foreground ("#141312") -highlightbackground ("#ffffff")
-highlightcolor ("#141312") -selectbackground ("#418bd4") -selectforeground ("#ffffff")
-width ("40");
pack (".lfSSF.entSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("0") -side ("left")
;
button (".lfSSF.butSSF") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Ваш выбор");
pack (".lfSSF.butSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("9") -pady ("0") -side ("right")
;
pack (".lfSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("10") -side ("top")
;
pack (".lfSSF.entSSF", ".lfSSF.butSSF") -in (".lfSSF");
notebook (".nbSSF") -width ("700") -height ("400") -padding ("7");
frame (".nbSSF.frameNB1") -borderwidth ("4") -relief ("sunken") -background ("#FF7256")
-height ("30") -highlightbackground ("#e0dfde") -highlightcolor ("#141312") -width ("30")
;
label (".nbSSF.frameNB1.labLogo") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -foreground ("#141312") -height ("329") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -relief ("raised") -text ("Здесь должен быть ваш логотип")
-width ("509");
pack (".nbSSF.frameNB1.labLogo") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("28") -side ("top");
pack (".nbSSF.frameNB1.labLogo") -in (".nbSSF.frameNB1");
frame (".nbSSF.frameNB2") -borderwidth ("2") -relief ("raised") -background ("#FF4500")
-height ("30") -highlightbackground ("#e0dfde") -highlightcolor ("#141312") -pady ("19")
-width ("30");
labelframe (".nbSSF.frameNB2.lfSignDoc") -borderwidth ("4") -foreground ("#141312")
-relief ("ridge") -text ("Подписываемый документ") -background ("#e0dfde") -height ("100")
-width ("100");
entry (".nbSSF.frameNB2.lfSignDoc.entSignDoc") -background ("#FFFAFA") -foreground ("#141312")
-highlightbackground ("#ffffff") -highlightcolor ("#141312") -selectbackground ("#418bd4")
-selectforeground ("#ffffff") -width ("40");
pack (".nbSSF.frameNB2.lfSignDoc.entSignDoc") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("5") -pady ("0") -side ("left");
button (".nbSSF.frameNB2.lfSignDoc.butSignDoc") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Выберите");
pack (".nbSSF.frameNB2.lfSignDoc.butSignDoc") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("6") -pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfSignDoc") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("6") -side ("top");
pack (".nbSSF.frameNB2.lfSignDoc.entSignDoc", ".nbSSF.frameNB2.lfSignDoc.butSignDoc") -in (".nbSSF.frameNB2.lfSignDoc")
;
labelframe (".nbSSF.frameNB2.lfForType") -borderwidth ("4") -foreground ("#141312")
-relief ("ridge") -text ("Формат и тип подписи") -background ("#e0dfde") -height ("100")
-padx ("1") -pady ("5") -width ("100");
combobox (".nbSSF.frameNB2.lfForType.comboFor") -values ("PKCS7 CADES_BES CADES_XLT1") -cursor ("xterm");
pack (".nbSSF.frameNB2.lfForType.comboFor") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("4") -pady ("0") -side ("left");
radiobutton (".nbSSF.frameNB2.lfForType.radAtt") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Присоединенная") -value ("1") -variable (selSignType)
;
pack (".nbSSF.frameNB2.lfForType.radAtt") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("26") -pady ("0") -side ("left");
radiobutton (".nbSSF.frameNB2.lfForType.radDet") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Отсоединенная") -value ("0") -variable (selSignType)
;
pack (".nbSSF.frameNB2.lfForType.radDet") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("13") -pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfForType") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("16") -side ("top");
pack (".nbSSF.frameNB2.lfForType.comboFor", ".nbSSF.frameNB2.lfForType.radAtt", ".nbSSF.frameNB2.lfForType.radDet") -in (".nbSSF.frameNB2.lfForType")
;
labelframe (".nbSSF.frameNB2.lfCert") -borderwidth ("4") -foreground ("#141312") -relief ("ridge")
-text ("Сертификат для подписи") -background ("#e0dfde") -height ("100") -width ("100")
;
entry (".nbSSF.frameNB2.lfCert.entCert") -background ("#FFFAFA") -foreground ("#141312")
-highlightbackground ("#ffffff") -highlightcolor ("#141312") -selectbackground ("#418bd4")
-selectforeground ("#ffffff") -width ("40");
pack (".nbSSF.frameNB2.lfCert.entCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("9") -pady ("0") -side ("left");
button (".nbSSF.frameNB2.lfCert.butCert") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Укажите путь");
pack (".nbSSF.frameNB2.lfCert.butCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0")
-padx ("0") -pady ("0") -side ("left");
pack (".nbSSF.frameNB2.lfCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("8") -side ("top");
pack (".nbSSF.frameNB2.lfCert.entCert", ".nbSSF.frameNB2.lfCert.butCert") -in (".nbSSF.frameNB2.lfCert");
labelframe (".nbSSF.frameNB2.lfAtCert") -borderwidth ("4") -foreground ("#141312")
-relief ("ridge") -text ("Как поступить с сертификатом") -background ("#00FF00")
-height ("100") -width ("100");
radiobutton (".nbSSF.frameNB2.lfAtCert.radAtCert") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Включить в подпись") -value ("1") -variable (selCert)
;
pack (".nbSSF.frameNB2.lfAtCert.radAtCert") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("0") -pady ("0") -side ("left");
radiobutton (".nbSSF.frameNB2.lfAtCert.radDetCert") -activebackground ("#e0dfde")
-activeforeground ("#141312") -background ("#e0dfde") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -text ("Не включать") -value ("0") -variable (selCert)
;
pack (".nbSSF.frameNB2.lfAtCert.radDetCert") -anchor ("center") -expand ("0") -ipadx ("0")
-ipady ("0") -padx ("10") -pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfAtCert") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("0") -side ("top");
pack (".nbSSF.frameNB2.lfAtCert.radAtCert", ".nbSSF.frameNB2.lfAtCert.radDetCert") -in (".nbSSF.frameNB2.lfAtCert");
button (".nbSSF.frameNB2.butSign") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#20B2AA") -borderwidth ("7") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -relief ("ridge") -text ("Сформировать подпись")
-image ("stamp_32x32") -compound("left");
pack (".nbSSF.frameNB2.butSign") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0")
-pady ("14") -side ("top");
pack (".nbSSF.frameNB2.lfSignDoc", ".nbSSF.frameNB2.lfForType", ".nbSSF.frameNB2.lfCert", ".nbSSF.frameNB2.lfAtCert", ".nbSSF.frameNB2.butSign") -in (".nbSSF.frameNB2");
frame (".nbSSF.frameNB3") -borderwidth ("2") -relief ("raised") -background ("#e0dfde")
-height ("30") -highlightbackground ("#e0dfde") -highlightcolor ("#141312") -width ("30")
;
pack (".nbSSF") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("0") -side ("top");
labelframe (".lfP11") -borderwidth ("4") -foreground ("#141312") -relief ("ridge") -text ("Хранилище вашего закрытого ключа")
-background ("#FFE4B5") -height ("100") -width ("100");
entry (".lfP11.entP11") -background ("#FFFAFA") -foreground ("#141312") -highlightbackground ("#ffffff")
-highlightcolor ("#141312") -selectbackground ("#418bd4") -selectforeground ("#ffffff")
-width ("40");
pack (".lfP11.entP11") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("8") -pady ("0") -side ("left")
;
button (".lfP11.butP11") -activebackground ("#e0dfde") -activeforeground ("#141312")
-background ("#e0dfde") -borderwidth ("4") -foreground ("#141312") -highlightbackground ("#e0dfde")
-highlightcolor ("#141312") -relief ("ridge") -text ("Выбор за вами");
pack (".lfP11.butP11") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("9") -pady ("1") -side ("top")
;
pack (".lfP11") -anchor ("center") -expand ("0") -ipadx ("0") -ipady ("0") -padx ("0") -pady ("14") -side ("top")
;
pack (".lfP11.entP11", ".lfP11.butP11") -in (".lfP11");
addtab (".nbSSF", ".nbSSF.frameNB1") -padding ("0") -sticky ("nsew") -state ("normal") -text ("Логотип") -compound ("none") -underline ("-1");
addtab (".nbSSF", ".nbSSF.frameNB2") -padding ("0") -sticky ("nsew") -state ("normal") -text ("Подписать") -compound ("none") -underline ("-1");
addtab (".nbSSF", ".nbSSF.frameNB3") -padding ("0") -sticky ("nsew") -state ("normal") -text ("Проверить") -compound ("none") -underline ("-1");
pack (".lfSSF", ".nbSSF", ".lfP11") -in (".");
/*proc TPcloseWindow. {} {}*/
".lfSSF.butSSF" << configure () -command (compute);
".nbSSF.frameNB2.lfSignDoc.butSignDoc" << configure () -command (findDoc);
".nbSSF.frameNB2.lfCert.butCert" << configure () -command (findCert);
".lfP11.butP11" << configure () -command (findPrivKey);
".nbSSF.frameNB2.lfForType.radAtt" << configure () -command (updateRad);
".nbSSF.frameNB2.lfForType.radDet" << configure () -command (updateRad);
".nbSSF.frameNB2.lfAtCert.radAtCert" << configure () -command (updateRad);
".nbSSF.frameNB2.lfAtCert.radDetCert" << configure () -command (updateRad);
".nbSSF.frameNB2.butSign" << configure () -command (createSign);
".nbSSF.frameNB2.butSign" << configure () -state (disabled);
".lfP11.butP11" << configure () -state (disabled);
".nbSSF.frameNB2.lfForType.comboFor" << deleteentry (0, end);
".nbSSF.frameNB2.lfForType.comboFor" << insert(end, "PKCS7");
tab (".nbSSF", ".nbSSF.frameNB2") -state (disabled);
tab (".nbSSF", ".nbSSF.frameNB3") -state (disabled);
wm (iconphoto, ".", "stamp_32x32");
runEventLoop();
}
catch (exception const &e)
{
cerr << "Error: " << e.what() << '\n';
}
}
И после получения бинарного кода запускаем его и видим следующее:
Вот и все. Но остались еще две вещи, про которые я хотел бы рассказать. Это создание расширений для Tcl посредством динамических библиотек и Tcl/Tk в Android.