И в качестве примера сразу приведем пример программы на языке 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/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<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);
}
+/*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 <typename T\>
details::Expr pack(std::string const &option,
@@ -85,6 +91,27 @@
str += details::toString(t);
return details::Expr(str);
}
+/*LISSI*/
+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);
+/*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 <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:
# 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] <file tcl from TKproE\>\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] <file tcl from Page\>\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 <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 выглядит следующим образом:
#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. 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. К сожалению при укладке в спойлер символы > пришлось заменить на \>
#При сохранении скрипта выполните обратную замену.
Сохранив скрипт в файле, например, forBook.tcl, любой может его загрузить в дизайнер TKproE и увидеть знакомую уже картинку (см. выше). Теперь, чтобы получить код C++ воспользуемся скриптом convertFromTclToCPPTK.tcl:
$ convertFromTclToCPPTK.tcl forBook.tcl >forBook.cc
$
//Code for CPP generate LISSI-Soft
#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);
Естественно, пишем код самих функций.
//Code for CPP generate LISSI-Soft
#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.
Комментарии (24)
saipr Автор
12.12.2017 21:44Спасибо. Удивительно то, что я писал свой ответ товарищу еще не зная про ваш комментарий.
А получилось как подкопирку в хорошем смысле этого слова.
Amomum
12.12.2017 22:03Скажите пожалуйста, каков практический смысл использовать С89 в 2017 году?
Сужу по объявлению всех переменных в начале функций и по отсутствию однострочных комментариев:
int lenStr(){ int code; int len; char slen[256]; char *res; /*Читаем из widget-а введенную строку в переменную tcl с именем a*/ code = Tcl_Eval(tcl_interp, "set a [.ent1 get];");
yroman
13.12.2017 04:28Как-то громоздко все получилось, а преимуществ каких-то особых не видно. Не проще взять тот же Python+Tkinter? Сдается мне, в последнем случае код будет на порядок компактнее и проще при одном и том же выхлопе.
saipr Автор
13.12.2017 09:06Вы о чем? Python + Tkinter = Tcl/Tk только со всеми недостатками (вот уж где громоздость так громоздкость). И как может быть на порядок компактнее, если Tkinter с Python это фактически просто обертка вокруг Tcl/Tk.
Вот здесь и здесь есть про Python + Tkinter.yroman
13.12.2017 09:30Спасибо, я в курсе про Python + Tkinter. Вот только не в курсе про недостатки. Зато разработка и отлов ошибок на порядок проще на питоне, нежели на той лапше (уж простите) сишного кода, который вы привели в статье. Если вы это делаете just for fun, то окей, вопросов нет, а если для практических целей, то в чем смысл, если тоже самое можно реализовать так же кроссплатформенно, но на порядок проще?
saipr Автор
13.12.2017 09:48Си это Си, Python это Python. Если вы возьмете "эту лапшу" и положите на Pyton получите один в один тот же код!!! С точностью до синтаксиса. И ошибка для Tk-GUI отлавливаются абсолюно одинаково, их ловит Tcl/Tk.
Не знаю с чем спорить? Есть задачи, которые можно решить и на скриптовых языках, на Python-e (но поверьте это лучше делать на Tcl) например, а есть задачи которые решаются только и только на C/C++.yroman
13.12.2017 10:10Почему? На питоне я этот же интерфейс сделаю по-питоновски, мне же не нужно брать тиклевский скрипт и грузить его в интерпретатор. Под использованием Python + Tkinter я имел ввиду все тоже самое сделать на питоне через виджеты Ткинтера, красиво и чисто, плюс логику приложения на нем же. Тяжелые места выносить в С/C++, благо интегрировать сишный код с питоном проще простого.
Я не говорю, что то, что вы написали, не нужно. Я всего лишь хочу понять чем ваш подход лучше того, что я предложил, и ничего более.saipr Автор
13.12.2017 10:46Вот здесь вы найдете проект на Python + Tkinter со всеми исходниками GUI, включая проект. Посмотрите, сравните и ответьте на вопрос "я имел ввиду все тоже самое сделать на питоне через виджеты Ткинтера, красиво и чисто, плюс логику приложения на нем же".
Ну ни чем не отличается. Кому что нравится или на чем уже было сделаною
saipr Автор
13.12.2017 10:52красиво и чисто
Если вы имеете ввиду отступы в блоках python-а, то да, он заставляет писать структурированно.
shepemic
13.12.2017 09:06+1Можно взять и питон, но думаю, что статья тогда будет называться «Разработка приложений на языке Python с использованием Tkinter». В данной же статье описывается работа с Tcl/Tk именно из C/C++. Вполне полезная статья.
yroman
13.12.2017 09:38Ну я вроде бы и не говорил что она вредная. Но мне не очень ясен практический смысл. Код в статье просто вырвиглазный, а судя по самому процессу интеграции, поддерживать это будет очень сложно. Поэтому мной и был задан вопрос — зачем так сложно, если можно быстрее и проще с тем же результатом?
Ostan
Я понимаю так: программирование — это создание программ, реализующих определённую логику работы. Создание графических форм это «не вполне» программирование. Это как-бы сопутствующая программированию сфера.
Статья не представляет собой ничего полезного, больше похожа на вводную главу какого-то учебника по Tcl/Tk. Вот если бы автор написал какую-нибудь полезную утилиту и выложил здесь исходный код с разбором, тогда польза была бы.
saipr Автор
Это или это, а может это может устроить?
Создание форм — не программирование. Могу согласиться. А вот разработать логику этих форм, заставить выполнять главную задачу и как их создать с минимальными усилиями — это все программирование с Большой буквы. Да и без путеводителя тяжело программировать
Ostan
Нет не может! Это коммерческие продукты с закрытым исходным кодом.
С таким же успехом, Я мог бы написать бесполезную статью про Qt, с приведение нескольких «учебных» примеров о том, как создавать формочки с кнопочками.
Сам таким заниматься не буду, если хотите вот вам ссылка на страницу документации. Переведите на русский язык и будет ещё одна статья: «Разработка приложений на языках C/C++ с использованием Qt»
saipr Автор
А про Qt мы знаем начиная с 1.14. И где вы увидели коммерческие продукты? Качайте, изучайте код и т.д. Т.е. вы хотите сказать, что все учебники, все статьи про так как можно и что можно использовать, бесполезны? Интересно, а как вы училися! Кстати, и про Qt статья с примерами не помешала бы и кому-то очень бы помогла. Напишите и вам скажут спасибо.
Ostan
Вот как раз таки учебники — полезны, а ваша статья бесполезна. Если Я решу изучить Tcl/Tk, то найду официальную документацию и буду читать. Или книгу, которая даст полную информацию о предмете. А собирать у себя в голове «мозаику» из таких вот информационных фрагментов, как ваша статья, нет смысла.
saipr Автор
Я вам помогу, вот самая свежая книга:
Написана прекрасно.
mazkorulez
Не согласен с Вами. Задачи человеко-машинного интерфейса очень важны и влияют на решение задачи в целом (ведь, логику работы определяют люди, использую её как инструмент для решения своих задач): как будут подаваться данные в машину, сколько нужно выполнить операций для того, чтобы вбить массив данных из сотни или тысячи элементов, а как эти данные будут отображаться, как их отобразить из оперативной памяти или жесткого диска? Автор статьи показывает нам одно из таких решений — Tcl/Tk. Поэтому считаю, что статья является полезной и даже очень познавательной. Используя полученные данные можно уже создавать свои приложения с использованием этой замечательной технологии.