Разработка приложений на языках C/C++ с использованием Tcl/Tk

image Мощный функционал скриптового языка Tcl в сочетании с виджетами Tk/TTK позволяет создавать в этой среде серьезные приложения. Этому способствует также его кросплатформенность и прекрасная интеграция с языками программирования C/C++.
И в качестве примера сразу приведем пример программы на языке C. Эта программа строит графический интерфейс, имеющий поле для ввода строки, кнопку, при нажатии которой вычисляется длина строки, и поля для отображения результата:

image

Текст программы на языке C выглядит следующим образом:

#include 
#include 
#include 
#include 
#include 
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 и самое главное прекрасно документирован:

image

И так, библиотека 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)
+
+/*LISSI*/
+// catch (exception const &e)
+ catch (std: exception const &e)
+
{
Tcl_SetResult (interp, const_cast(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);
}
+/*LISSI*/
+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);
}
+
+/*LISSI*/
+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)
+//LISSI
+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 ());
+/*LISSI*/
+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
details: Expr pack (std: string const &option,
@@ -85,6 +91,27 @@
str += details: toString (t);
return details: Expr (str);
}
+/*LISSI*/
+template
+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
+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);
+/*LISSI*/
+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)
+//LISSI
+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)
+//LISSI
+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 (в противном случае спойлер неверно отображал текст). Необходимо это учитывать и провести обратную замену.

Применить патч можно следующим образом. Создайте каталог. В него поместите каталог проекта 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
#LISSI-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] \n»
puts «Copyrait LISSI-Soft Ltd\n»
exit
}
set fconf [file exists »$argv»]
if { $fconf == »0» } {
puts «File=\»$argv\» don’t exist\n»
puts «Usage: [info script] \n»
puts «Copyrait LISSI-Soft Ltd\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 »//Code for CPP generate LISSI-Soft»
puts »#include \«cpptk.h\»
puts »#include \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  > <имя файла для сохранения C++ - кода>
$


В качестве примера рассмотрим разработку программы формирования усовершенствованной электронной подписи с библиотекой SSF («Secure Store and Forward»), используемой в продуктах компании SAP AG для обеспечения криптографической защиту электронных документов за счет использования механизмов электронной подписи и шифрования с использованием российских криптоалгоритмов (ГОСТ 28147–89, ГОСТ Р 34.11–94, ГОСТ Р 34.11–2012, ГОСТ Р 34.10–2001, ГОСТ Р 34.10–2012). Проект GUI в дизайнере TKproE выглядит следующим образом:

image

Скрипт этого проекта находится здесь
# Generated by TKproE 2.20 — Tue Dec 12 12:50:32 MSK 2017
#Add from LISSI-Soft
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. 723×618+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. К сожалению при укладке в спойлер символы > пришлось заменить на \>
#При сохранении скрипта выполните обратную замену.


Сохранив скрипт в файле, например, forBook.tcl, любой может его загрузить в дизайнер TKproE и увидеть знакомую уже картинку (см. выше). Теперь, чтобы получить код C++ воспользуемся скриптом convertFromTclToCPPTK.tcl:

$ convertFromTclToCPPTK.tcl forBook.tcl >forBook.cc
$


Полученный код forBook.cc можно увидеть здесь
//Get file tcl from=forBook.tcl
//Code for CPP generate LISSI-Soft
#include «cpptk.h»
/*К сожалению при укладке в спойлер в следующей строке пришлось заменить > на \>
сделайте обратную замену*/
#include
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,».»,»723×618+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
//Code for CPP generate LISSI-Soft
#include «cpptk.h»
/*К сожалению при укладке в спойлер в следующей строке пришлось заменить > на \>
сделайте обратную замену*/
#include

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(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_32×32») -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,».»,»723×618+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.

© Habrahabr.ru