![]() |
+7 (495) 229-0436 | ![]() |
shopadmin@itshop.ru | 119334, г. Москва, ул. Бардина, д. 4, корп. 3 | ![]() |
![]() |
![]() |
|
|
Как использовать справку в программах Delphi05.04.2011 11:38
Как использовать справку в программах Delphi
2. Практика: указываем файл справки. 3. Поддержка справки в Delphi программах. 4. Практика: простой вызов статической справки. 5. Практика: динамический вызов контекстно-зависимой справки. 6. Обзор распространённых форматов файлов справок. 7. Поддержка форматов справки в Delphi. 8.Заключение
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
program Project1; uses Forms, SysUtils, // <- Добавлено Unit1 in 'Unit1.pas' {Form1} ; {$R *.res} begin Application . Initialize; Application . MainFormOnTaskbar := True ; Application . HelpFile := ExtractFilePath(Application . ExeName) + 'Help\HelpFile.hlp' ; // <- Добавлено Application . CreateForm(TForm1, Form1); Application . Run; end . |
HelpFile.hlp
и лежать в подпапке Help
вашей программы. Разумеется, вы должны заменить эту строчку своими данными.Через GUI: Project
/ Options
/ Application
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
program Project1; uses Forms, SysUtils, // <- Добавлено Unit1 in 'Unit1.pas' {Form1} ; {$R *.res} begin Application . Initialize; Application . MainFormOnTaskbar := True ; Application . HelpFile := ExtractFilePath(Application . ExeName) + Application . HelpFile; // <- Добавлено Application . CreateForm(TForm1, Form1); Application . Run; end . |
Что даёт вам 100% гарантию работы, но... не проще ли просто использовать программную установку пути изначально, не трогая GUI?
1
2
3
4 |
procedure TForm1 . FormCreate(Sender: TObject); begin HelpFile := ExtractFilePath(Application . ExeName) + 'Help\MainForm.hlp' ; end ; |
Нажатие F1
Эта функция реализует контекстую справку. Когда пользователь нажимает F1
, приложение ищет в файле справке тему (topic) с номером контекста (context number) или ключевым словом (keyword), заданными в свойствах компонента, имеющего фокус. Если найдена одна или несколько тем - то открывается файл справки, показывая эти темы в отдельном окне.
Кнопка с вопросиком в заголовке окна
Эта кнопка активирует контекстно-зависимый режим справки на форме - так называемая функция "What's this?" ("Что это такое?"). Когда пользователь нажимает на эту кнопку, форма временно отключается, а курсор меняет форму на стрелочку с вопросиком:
Нажатие на любом элементе управления в этом режиме заставит приложение выполнить поиск темы в файле справки, ассоциированной с этим компонентом. Если тема найдена, то она будет показана во всплывающем окошке.
Обычно этот способ не используется в современных программах. Исторически он появился в 16 разрядных Windows, когда ещё не было всплывающих подсказок. Сегодня же вместо этого функционала намного проще использовать обычное свойство Hint
.
Кнопка "Справка" с Kind = bkHelp
Это простой способ вызвать справку, не создавая ни строчки кода. Нажатие на кнопку откроет тему с номером контекста или ключевым словом, заданными в свойствах либо самой кнопки, либо (обычно) формы.
Application.HelpCommand
Это гибкий метод, который позволяет вам выполнить любую команду с вашим файлом справки. Подробнее эта команда рассмотрена ниже.
Application.HelpJump
Это вспомогательная функция, которая является обёрткой к Application.HelpCommand
с командой "jump". Она позволяет вам отобразить тему справки по её ID (имени).
Application.HelpContext
Это вспомогательная функция, которая является обёрткой к Application.HelpCommand
. Она позволяет вам показать тему по так называемому номеру контекста (context number).
Application.HelpKeyword
Это вспомогательная функция, которая является обёрткой к Application.HelpCommand
. Она позволяет вам показать тему по ключевому слову (keyword).
Каждое серьёзное Windows приложение имеет пункт меню "Справка" вроде такого:
Итак, как вам открыть окно Finder? На самом деле, это очень просто: поместите этот код в обработчик нажатия пункта меню:
1
2
3
4 |
procedure TForm1 . miHelpContentsClick(Sender: TObject); begin Application . HelpCommand(HELP_FINDER, 0 ); end ; |
1
2
3
4 |
procedure TForm1 . miHelpContentsClick(Sender: TObject); begin Application . HelpCommand(HELP_TAB, 0 ); end ; |
HELP_TAB
не определена. В этом случае добавьте в подходящее место программы это определение:
1
2 |
const HELP_TAB = 15 ; |
1
2
3
4 |
procedure TForm1 . miHelpDefaultClick(Sender: TObject); begin Application . HelpCommand(HELP_CONTENTS, 0 ); end ; |
1 |
Application . HelpCommand(HELP_CONTENTS, 0 ); |
Следующий пример показывает, как можно открыть справку на вкладке индекса:
1
2
3
4
5
6
7
8 |
procedure TForm1 . ShowKeywordIndex; var Command: array [ 0..255 ] of Char ; // примечание: этот код также работает с D2009+ begin Command := 'SEARCH()' ; Application . HelpCommand(HELP_FORCEFILE, 0 ); Application . HelpCommand(HELP_COMMAND, Longint (@Command)); end ; |
Следующий пример открывает окно справки с активным окном поиска:
1
2
3
4
5
6
7
8 |
procedure TForm1 . ShowFullTextSearch; var Command: array [ 0..255 ] of Char ; // примечание: этот код также работает с D2009+ begin Command := 'FIND()' ; Application . HelpCommand(HELP_FORCEFILE, 0 ); Application . HelpCommand(HELP_COMMAND, Longint (@command)); end ; |
Application.HelpJump
, который принимает один строковый параметр - ID (имя) темы. Например:
1
2
3
4 |
procedure TForm1 . ShowTopicByName; begin Application . HelpJump( 'mytopic' ); end ; |
True
, если тема существует и была найдена, и False
- в противном случае. Однако, в последнем случае также автоматически показывается сообщение пользователю о том, что тема не существует. HelpJump
нет, то вот её код:
1
2
3
4
5
6
7
8
9
10
11 |
function TForm1 . HelpJump( const JumpID: string ): Boolean ; var Command: array [ 0..255 ] of Char ; begin Result := True ; if InvokeHelp(HELP_CONTENTS, 0 ) then begin StrLFmt(Command, SizeOf(Command) - 1 , 'JumpID("","%s")' , [JumpID]); Result := Application . HelpCommand(HELP_COMMAND, Longint (@Command)); end ; end ; |
Application.HelpContext
, который принимает один числовой параметр - номер контекста. Например:
1
2
3
4 |
procedure TForm1 . ShowTopicByNumber; begin Application . HelpContext( 2 ); end ; |
True
, если тема существует и была найдена, и False
- в противном случае. HelpContext
нет, то вот её код:
1
2
3
4 |
function TForm1 . HelpContext( const AContext: Integer ): Boolean ; begin Result := Application . HelpCommand(HELP_CONTEXT, AContext); end ; |
Эта команда покажет тему в отдельном окне. Если вы хотите использовать всплывающее окно - используйте другую команду:
1
2
3
4 |
procedure TForm1 . ShowTopicByNumberInPopup; begin Application . HelpCommand(HELP_CONTEXTPOPUP, 2 ); end ; |
F1
, то вы получаете описание этого свойства.Это работает при помощи ключевых слов. Когда вы нажимаете F1
, в справке ищутся темы с ключевым словом, которое указано под курсором или в инспекторе объектов. Для этого файл справки должен содержать список ключевых слов, ассоциированных с темами. Вы задаёте это при создании файла справки (указывая ключевые слова в свойствах темы).
Для показа темы по ключевому слову используется метод Application.HelpKeyword
, который принимает один строковый параметр - ключевое слово. Например:
1
2
3
4 |
procedure TForm1 . ShowTopicByKeyword; begin Application . HelpKeyword( 'example' ); end ; |
HelpContext
нет, то вот её код:
1
2
3
4
5
6
7 |
function TForm1 . HelpKeyword( const AKeyword: String ): Boolean ; var Command: array [ 0..255 ] of Char ; begin StrLcopy(Command, PChar (AKeyword), SizeOf(Command) - 1 ); Result := Application . HelpCommand(HELP_KEY, Integer (@Command)); end ; |
1
2
3
4 |
procedure TForm1 . CloseHelp; begin Application . HelpCommand(HELP_QUIT, 0 ); end ; |
Kind
) bkHelp
(обработчик при этом реализовывать не требуется).Итого, сейчас нам осталось поговорить про первый пункт.
Нажатие F1
, когда фокус ввода находится на каком-то элементе управления. Это основной способ показа контекстной справки. Когда пользователь застревает, он нажимает F1, а программа показывает ему тему справки, в зависимости от того, где он находится. Этот способ поддерживается Delphi и вам не нужно писать для него код.
Функция "What's this?". Это либо кнопка с вопросиком в заголовке окна, либо аналогичная кнопка с вопросиком на панели инструментов (Toolbar-е), либо пункт меню Справка
/Что это такое?
. Как я уже говорил, это старый режим работы со справкой. Я не буду его особо рассматривать, потому что в современных программах гораздо проще и удобнее использовать всплывающие подсказки.
Кнопка с Kind = bkHelp
или аналогичный способ. Этот способ нельзя полностью отнести к контекстой справке - ведь когда вы щёлкаете на кнопку, то фокус уходит с текущего элемента управления. Тем не менее, я перечисляю этот способ, как ещё один вариант автоматического вызова справки без написания кода.
Возможно, вы уже заметили эти свойства в инспекторе объектов - это свойство HelpContext
и свойство HelpKeyword
:
HelpType
определяет, какое свойство нужно использовать для вызова контекстной справки. Обычно используются номера контекстов, а не ключевые слова - этот вариант является вариантом по умолчанию для свойства HelpType
.Для работы контекстной справки или эти номера (не важно - созданные вами или проставленные автоматически) или ключевые слова должны быть присвоены темам и установлены в свойства компонентов на форме. Номера должны быть уникальны как в файле справки, так и в Delphi проекте. Вы можете присвоить один и тот же номер двум и более компонентам - но это будет означать, что эти компоненты привязаны к одной и той же теме. В отличие от номеров контекста, ключевые слова не обязаны быть уникальными. Если с одним ключевым словом связано более одной темы, то вам будет показано окно, из которого вы сможете выбрать нужную тему.
Когда пользователь вызывает контекстную справку (любым из способов, описанных в предыдущем пункте - либо через F1
, либо через функцию "What's this?", либо кнопкой "Справка") - то показывается тема справки, контекстный номер которой указан в свойстве HelpContext
. Либо же, если HelpType
установлено в htKeyword
, то показывается тема(ы) с ключевым словом из свойства HelpKeyword
. Для работы контекстной справки вам не нужно делать ничего, кроме как проставить номера контекстов темам и компонентам. Всю работу Delphi сделает автоматически.
Вам не нужно проставлять номера контекстов или ключевые слова абсолютно всем компонентам на форме - ведь свойства HelpContext
и HelpKeyword
наследуется. Т.е. если вдруг у компонента нужное свойство не задано (равно нулю или пустой строке соответственно), то используется свойство HelpContext
/HelpKeyword
его родителя (в смысле Parent
). Если же это свойство не задано и у родителя - то проверяется свойство родителя родителя. И так далее, вплоть до формы. Если же свойство не задано и у формы, то контекстная справка вообще не вызывается. Если вы используете кнопку вызова справки с Kind = bkHelp
, то вы обязаны присвоить номер контекста или ключевое слово либо ей, либо форме.
Итак, суммируя: чтобы в вашей программе работала контекстная справка, вам нужно:
Вы должны указать приложению, что у вас есть файл справки. Это общее действие для любого типа справки в Delphi приложении.
Вы должны придумать и присвоить номера контекстов (либо ключевые слова, либо и то и другое) темам в вашем файле справки. Необязательно делать это для всех тем. Если ключевые слова желательно проставлять вообще (для работы индекса), то номера контекстов можно указывать только у тех тем, которые должны быть доступны через контекстную справку. Вы можете включить автоматическую нумерацию, если ваша программа для создания файлов справок это позволяет.
Вы должны присвоить контекстные номера (либо ключевые слова) форме и компонентам на ней в вашем Delphi приложении, чтобы ассоциировать элементы управления в приложении с темами справки. Как минимум, вы должны указать эти номера (ключевые слова) для форм.
F1
- автоматически откроется тема в справке, которую вы задали в свойствах текущего элемента управления.16 битный Windows Help aka WinHelp 1.0 (.HLP) - проприетарный формат файлов справки, разработанный компанией Microsoft для организации справочной системы. Исходная информация подготавливается в форматах RTF (текст) и BMP (изображения), а затем с использованием компилятора генерируется бинарный файл с расширением HLP. Поддержки Unicode нет. Может быть декомпилирован в исходные файлы. Разработан в 1990 и поддерживается в Win16, Win32, WinNT до XP включительно. Устарел в 2006. Ограничено доступен в Windows Vista и Windows 7 (и выше) - поддержка для него должна быть установлена дополнительно. Сегодня в здравом уме не используется никем.
32 битный Windows Help aka WinHelp 2.0-4.0 (.HLP + .CNT) - улучшенный вариант формата .HLP, появившийся в Windows 95. Поддерживается в Win32/WinNT до Windows XP включительно. Поддержки Unicode нет. Устарел в 2006. Ограничено доступен в Windows Vista и Windows 7 (и выше) - поддержка для него должна быть установлена дополнительно. Сегодня в основном используется старыми приложениями или теми, кому нужны специальные функции формата WinHelp.
Compiled HTML Help aka HTML Help 1.0-1.4 (.CHM) - основной и самый популярный формат файлов справок, выпущенный в 1997 и поддерживаемый начиная с Windows 98 во всех Windows, включая Windows Vista и Windows 7. Представляет собой скомпилированный файл, полученный из обычных HTML-файлов со специальной разметкой. По этой причине формат стал популярным для создания e-books. Может быть декомпилирован в исходные файлы. Однако в этот формат уже не вносятся изменения и новые возможности, а лишь устраняются найденные уязвимости. Microsoft планирует заменить его на какой-нибудь другой формат в будущем. Поддержка Unicode ограничена.
Assistance Platform 1.0 (.H1S) - достаточно специфичный формат справки, поскольку используется только для расширения встроенной справки самой ОС OEM партнёрами. Понятно, что он не предназначен для общего использования.
Microsoft Help aka HTML Help 2.0 (.HXS) - формат справки, используемый Visual Studio 2002/2003/2005/2008 и последними версиями Delphi. Разработан в 2001. Поддерживает Unicode. Сжатый файл .HxS получается из набора тем, написанных в HTML (похоже на .CHM). В отличие от всех прочих форматов, этот формат справки НЕ предназначен для программ общего назначения. Дело в том, что просмотрщик справки этого формата не входит в комплект ни одной ОС Windows на сегодняшний день. Поддержка справки этого формата устанавливается только вместе с Visual Studio или Delphi - это Document Explorer (dexplore.exe). Плюс ко всему вы не можете таскать вместе со своей программой установщик для этой справки (согласно лицензии).
Microsoft Help System aka HTML Help 3.0 (.MSHC) - формат справки, используемый Visual Studio 2010. Разработан в 2009. Поддерживает Unicode. Аналогично формату HTML Help 2.0/HXS - НЕ предназначен для программ общего назначения (по крайней мере пока), хотя ограничений на просмотрщик уже нет (справку можно просматривать в любом браузере). Файл .MSHC является обычным переименованным .ZIP файлом. Компилятор не требуется - файлы содержимого, содержащие ссылки друг на друга, просто укладываются в архив. Сильные стороны формата: открытость, быстрота, простота и прозрачная интеграция с online-справкой. Этот формат справки имеет потенциал заменить собой .CHM и стать новой стандартной системой справки в будущем.
HTML (.HTML) - представляет собой просто набор обычных HTM/HTML файлов. Понятно, что такой формат достаточно ограничен и обычно не имеет никаких преимуществ перед .CHM - окромя полной поддержки Unicode.
Portable Document Format (.PDF) - формат, созданный Adobe Systems в 1993. Обычно этот формат используется для печати справки (ещё точнее - руководства) на бумаге, а не как файл справки в программе.
Web/Online - вообще не файловая справка. Представляет собой открытие web-сайта со страничкой справки на нём.
WinHelpViewer
в любую секцию uses
.
uses
модуль HTMLHelpViewer
(как обычно: чем раньше - тем лучше).Примечание: не подключайте одновременно WinHelpViewer
и HTMLHelpViewer
. Либо первый, либо второй, либо ни один, но не оба сразу.
Для Delphi 7 и ниже вы можете использовать моё решение. Использовать его не менее просто - просто распакуйте архив в папку вашего проекта и добавьте модуль HTMLHelpViewerEx
в любой uses
вашего проекта.
Это решение также может быть использовано в Delphi 2005 и выше, если вас не устраивает стандартное решение (модуль HTMLHelpViewer
). И снова: подключайте в uses только один модуль (либо WinHelpViewer
, либо HTMLHelpViewer
, либо HTMLHelpViewerEx
, либо ни одного).
См. табличку ниже для сравнения возможностей форматов и их реализации.
Application.OnHelp
. В обработчике вам нужно организовать реакцию на команды, которые реально использует ваше приложение, например:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 |
type TForm1 = class (TForm) procedure FormCreate(Sender: TObject); function ApplicationHelp(Command: Word ; Data: Longint ; var CallHelp: Boolean ): Boolean ; ... end ; ... procedure TForm1 . FormCreate(Sender: TObject); begin Application . OnHelp := ApplicationHelp; end ; function TForm1 . ApplicationHelp(Command: Word ; Data: Longint ; var CallHelp: Boolean ): Boolean ; procedure OpenURL( const AURL: String ); var SEI: TShellExecuteInfo; begin FillChar(SEI, SizeOf(SEI), 0 ); SEI . cbSize := SizeOf(SEI); {$IFDEF UNICODE} SEI . fMask := SEE_MASK_UNICODE; { $ENDIF } SEI . Wnd := Handle; SEI . lpVerb := 'open' ; SEI . lpFile := PChar (AURL); SEI . nShow := SW_SHOWNORMAL; if not ShellExecuteEx(@SEI) then RaiseLastOSError; end ; var DataStr: String ; begin // Пока установим признак успешного выполнения Result := True ; case Command of // Открытие заголовочной страницы HELP_FINDER, HELP_TAB, HELP_CONTENTS: OpenURL(Application . HelpFile); // Поиск по ключевому слову HELP_KEY: OpenURL(Application . HelpFile + '?q=' + PChar (Data)); // Открытие темы по номеру HELP_CONTEXT, HELP_CONTEXTPOPUP: OpenURL(Application . HelpFile + '/article' + IntToStr(Data) + '.html' ); // Расширенные команды: HELP_COMMAND: begin DataStr := PChar (Data); // Открытие индекса if StartsStr( 'SEARCH(' , DataStr) then OpenURL(Application . HelpFile) else // Открытие поиска if StartsStr( 'FIND(' , DataStr) then OpenURL(Application . HelpFile) else // Переход к теме по её имени if StartsStr( 'JI(' , DataStr) then begin // Обрезали 'JI(' DataStr := Trim(Copy(DataStr, 4 , MaxInt)); // Обрезали ')' SetLength(DataStr, Length(DataStr) - 1 ); OpenURL(Application . HelpFile + '/' + DataStr + '.html' ); end else // Прочие команды - считаем поиском по ключевому слову Result := ApplicationHelp(HELP_KEY, Integer (DataStr), CallHelp); end ; // HELP_QUIT: - здесь можно закрыть окно браузера // ... <- тут прочие команды, если надо else // Все прочие команды обрабатывать не умеем - указываем, что завершились неудачно Result := False ; end ; // Мы сделали всю работу, делать больше нечего CallHelp := False ; end ; |
HELP_KEY
(а также её обёртка через HELP_COMMAND
), HELP_CONTEXT
/HELP_CONTEXTPOPUP
, HELP_COMMAND
с командой 'JI'
, а также какая-то команда "открытия справки вообще" (например, HELP_FINDER
).Событие Application.OnHelp
вызывается при выполнении любой команды со справкой в вашей Delphi программе, позволяя вам отреагировать на неё и открыть web-страничку.
Только не забудьте установить свойство HelpFile
! Иначе Delphi программа будет считать, что у вас нет справки. Вы можете установить в это свойство URL справочной системы (как это предполагается в примере выше). К примеру, для примера выше вы можете установить свойство в 'http://www.google.com/search'
. Только понятно, что открытие темы по контекстному номеру или имени работать не будет. Зато открытие темы по ключевому слову приведёт к поиску этого слова в Google.
Я думаю, что табличка достаточно понятна, за исключением колонки D7/DXE - это я так обозначил стороннее (не штатное) решение с подключением модуля HTMLHelpViewerEx
.
Возможность | .HLP | .CHM | Web | ||||
---|---|---|---|---|---|---|---|
Команда или метод | Описание | Delphi 7 | Delphi XE | Delphi 7 | Delphi XE | D7/DXE | Пример выше |
HelpJump | Тема по ID | + | + | - | + | 2 | + |
HelpContext | Тема по контексту | + | + | - | + | + | + |
HelpKeyword | Тема по ключевому слову | 1 | 1 | - | + | + | + |
HELP_CONTENTS | Тема по умолчанию | + | + | - | + | + | +/- |
HELP_FINDER | Открыть окно справки | + | + | - | - | + | +/- |
HELP_TAB | Содержание | + | + | - | - | + | +/- |
SEARCH() | Индекс | + | + | - | - | + | +/- |
FIND() | Поиск | + | + | - | - | + | +/- |
HELP_QUIT | Выход | + | - | - | + | + | - |
Исправление/обходной путь для 1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
procedure TForm1 . btByKeywordClick(Sender: TObject); var SaveOld: String ; OldDir: String ; begin SaveOld := Application . HelpFile; OldDir := GetCurrentDir; try ChDir(ExtractFilePath(Application . HelpFile)); Application . HelpFile := ExtractFileName(Application . HelpFile); Application . HelpKeyword( 'example' ); finally Application . HelpFile := SaveOld; SetCurrentDir(OldDir); end ; end ; |
Вместо:
1 |
Application . HelpJump( 'mytopic' ); |
1 |
Application . HelpJump( 'JI(mytopic)' ); |
1 |
Application . HelpJump( '::/mytopic.htm' ); |
1 |
Application . HelpJump( '::\mytopic.htm' ); |
Если у вас всё ещё есть вопрос, а как же создавать сами файлы справки, то я вам рекомендую воспользоваться программой Help & Manual - это лучшее решение для создания справки в форматах HLP, CHM, HXS, PDF, HTML, RTF и E-book.
Вы можете создавать файлы справки в HLP и CHM и вручную, используя только бесплатные компиляторы (Microsoft Help Workshop и HTML Help Workshop соответственно).
Помощь |
![]() | |
![]() | Задать вопрос |
программы | |
обучение | |
экзамены | |
компьютеры | |
![]() | |
![]() | Бесплатный звонок |
![]() | |
![]() | ICQ-консультанты |
![]() | |
![]() | Skype-консультанты |
Общая справка | |
Как оформить заказ | |
Тарифы доставки | |
Способы оплаты | |
Прайс-лист | |
Карта сайта | |
![]() |
Бестселлеры |
О нас |
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.
На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям. Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе. В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.
|
119334, г. Москва, ул. Бардина, д. 4, корп. 3 +7 (495) 229-0436 shopadmin@itshop.ru |
|
© ООО "Interface Ltd." Продаем программное обеспечение с 1990 года |