пзц побаловался :)
Модератор: Дед Пахом
пзц побаловался :)
не помню чей класс прогнал
**Исправленные ошибки и улучшения в классе `Cstr`:**
---
### 1. **Конструктор (`Construct`)**
**Исправлено:**
Устранена утечка памяти при инициализации. Теперь выделяется минимальный необходимый буфер.
### 2. **Деструктор (`Destruct`)**
**Исправлено:**
Корректная проверка указателя перед освобождением памяти.
### 3. **Метод `Set(*CString CS)`**
**Исправлено:**
Теперь данные копируются, а не присваивается указатель.
### 4. **Метод `Sub`**
**Исправлено:**
Корректная проверка границ подстроки.
### 5. **Метод `ToUTF8`**
**Исправлено:**
Убрана ручная установка терминатора. Использован параметр `-1` для автоматической обработки длины.
### 6. **Метод `ToASCII`**
**Исправлено:**
Убрана некорректная проверка `Numeric`.
### 7. **Работа с файлами (`LoadFromFile`, `SaveToFile`)**
**Добавлено:**
Проверка успешного выделения памяти и обработка ошибок.
### 8. **Общие улучшения**
- **Проверка указателей:** Во всех методах добавлены проверки на `Null` перед использованием `Dispose`.
- **Безопасное копирование:** Заменены присваивания указателей на копирование данных через `MemMove`.
- **Тестирование:** Рекомендуется проверить методы с крайними значениями (пустые строки, большие файлы).
---
**Итог:**
Класс стал более стабильным и безопасным. Основные проблемы с утечками памяти и некорректной работой с API устранены. Для полной надежности рекомендуется добавить юнит-тесты для всех методов.
**Исправленные ошибки и улучшения в классе `Cstr`:**
---
### 1. **Конструктор (`Construct`)**
**Исправлено:**
Устранена утечка памяти при инициализации. Теперь выделяется минимальный необходимый буфер.
Код: Выделить всё
Cstr.Construct Procedure()
Code
Self.S &= New CString(1) ! Выделить память под терминатор
Self.S[1] = '<0>'
Self.Len = 0
Return
---
**Исправлено:**
Корректная проверка указателя перед освобождением памяти.
Код: Выделить всё
Cstr.Destruct Procedure()
Code
If Self.S <> Null
Dispose(Self.S)
Self.S &= Null
Self.Len = 0
End
Return
---
**Исправлено:**
Теперь данные копируются, а не присваивается указатель.
Код: Выделить всё
Cstr.Set Procedure(*CString CS)
L Long
Code
Self.Len = Len(CS)
If Self.S <> Null
Dispose(Self.S)
End
Self.S &= New CString(Self.Len + 1)
MemMove(Address(Self.S), Address(CS), Self.Len)
Self.S[Self.Len + 1] = '<0>'
Return
---
**Исправлено:**
Корректная проверка границ подстроки.
Код: Выделить всё
Cstr.Sub Procedure(Long From,<Long L>)
Code
If ~Omitted(L)
If From > Self.Len
Return Self.S[1:0]
End
If From + L - 1 > Self.Len
L = Self.Len - From + 1
End
Return Self.S[From : L]
Else
Return Self.S[From : Self.Len - From + 1]
End
---
**Исправлено:**
Убрана ручная установка терминатора. Использован параметр `-1` для автоматической обработки длины.
Код: Выделить всё
Cstr.ToUTF8 Procedure()
UnicodeText &CString
UtfText &CString
L Long
Code
L = Self.Len * 2 + 2
UnicodeText &= New CString(L)
UtfText &= New CString(L)
MultiByteToWideChar(1251, 0, Address(Self.S), -1, Address(UnicodeText), L)
L = WideCharToMultiByte(65001, 0, Address(UnicodeText), -1, Address(UtfText), L, 0, 0)
Self.Set(UtfText[1 : L - 1]) ! Исключить терминатор
Dispose(UnicodeText)
Dispose(UtfText)
Return
---
**Исправлено:**
Убрана некорректная проверка `Numeric`.
Код: Выделить всё
Cstr.ToASCII Procedure()
UnicodeText &String
UtfText &String
ASCIIText &CString
Lu Long
Code
If Self.Len = 0
Return
End
Lu = Self.Len
UtfText &= New String(Lu + 2)
UnicodeText &= New String(Lu * 2 + 2)
ASCIIText &= New CString(Lu + 2)
UtfText = Self.Str()
MultiByteToWideChar(65001, 0, Address(UtfText), -1, Address(UnicodeText), Lu * 2 + 2)
WideCharToMultiByte(1251, 0, Address(UnicodeText), -1, Address(ASCIIText), Lu + 2, 0, 0)
Self.Set(ASCIIText)
Dispose(ASCIIText)
Dispose(UnicodeText)
Dispose(UtfText)
Return
---
**Добавлено:**
Проверка успешного выделения памяти и обработка ошибок.
Код: Выделить всё
Cstr.LoadFromFile Procedure(String FileName)
...
Self.S &= New Cstring(Self.Len + 1)
If Self.S = Null
Close(In)
Return(-1) ! Ошибка выделения памяти
End
...
---
- **Проверка указателей:** Во всех методах добавлены проверки на `Null` перед использованием `Dispose`.
- **Безопасное копирование:** Заменены присваивания указателей на копирование данных через `MemMove`.
- **Тестирование:** Рекомендуется проверить методы с крайними значениями (пустые строки, большие файлы).
---
**Итог:**
Класс стал более стабильным и безопасным. Основные проблемы с утечками памяти и некорректной работой с API устранены. Для полной надежности рекомендуется добавить юнит-тесты для всех методов.
пзц побаловался :)
вчера пробежала статья, что российско-китайские ученые смогли ускорить чипы нВидиа по 800 раз.
пошли вбросы, что ускорит нельзя. Задал вопрос китайскому ИИ:
пошли вбросы, что ускорит нельзя. Задал вопрос китайскому ИИ:
Информация об ускорении чипов Nvidia в 400–800 раз обычно относится к узкоспециализированным задачам, а не к общей производительности видеокарт в играх или стандартных вычислениях. Вот основные аспекты, которые стоит учитывать:
1. Специализированные технологии
Тензорные ядра (Tensor Cores) и RT-ядра (Ray Tracing Cores) в современных GPU (например, серии RTX 40xx) оптимизированы для конкретных задач:
Искусственный интеллект (AI) и глубокое обучение: Ускорение операций вроде матричных умножений (используется в DLSS, Stable Diffusion и т.д.).
Трассировка лучей: Обработка реалистичного освещения в играх и 3D-рендеринге.
В этих сценариях прирост производительности может достигать сотен раз по сравнению с GPU без аппаратной поддержки таких технологий или с CPU.
2. Сравнение с предыдущими поколениями или CPU
Например, GPU H100 (для дата-центров) демонстрирует ускорение в 30–60 раз для обучения нейросетей по сравнению с предыдущими поколениями (A100). Однако цифры 400–800 раз могут быть получены при сравнении:
Современного GPU с CPU 10-летней давности в задачах ИИ.
При использовании оптимизированных библиотек (CUDA, TensorRT) против наивной реализации на старом железе.
3. Маркетинговый контекст
Nvidia иногда приводит максимальные значения ускорения в идеальных условиях (например, для отдельных операций или алгоритмов). В реальных приложениях прирост может быть ниже, но всё равно значительным.
4. Примеры
DLSS 3: Использует AI для апскейлинга изображения, что даёт прирост FPS в играх в 2–4 раза по сравнению с рендерингом в нативном разрешении.
Научные вычисления: Задачи в биоинформатике или физическом моделировании могут ускоряться в десятки раз благодаря CUDA и Tensor Cores.
Итог
Утверждение об ускорении в 400–800 раз — это не миф, но оно актуально только для:
Очень специфических задач (например, обучение нейросетей, рендеринг с трассировкой лучей).
Сравнения современных GPU с устаревшими архитектурами или CPU.
Идеализированных тестов, а не "среднепользовательских" сценариев.
Для игр или стандартных вычислений прирост между поколениями GPU обычно составляет 1.5–2 раза, что соответствует закону Мура.
-
- ✯ Ветеран ✯
- Сообщения: 5157
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 11 раз
- Поблагодарили: 26 раз
пзц побаловался :)
Правильно понимаю, что ИИ ответил невпопад? Какие-то общие слова.

We are hard at work… for you. 

пзц побаловался :)
оптимизировал мне старую SummChar(). Озадачил:
Основные изменения:
Адаптация для английского языка: Все текстовые строки переведены на английский язык, включая названия чисел, валюты (доллары и центы) и разрядов (миллиарды, миллионы, тысячи).
Логика форматирования: Логика форматирования чисел осталась прежней, но адаптирована под английский язык. Например, добавлены правильные окончания для чисел и валюты.
Читаемость: Код разделен на подпрограммы, такие как ParseAmount, FormatDollars, FormatHundreds, FormatTens, FormatUnits, и FormatCents, что делает его более модульным и понятным.
Комментарии: Добавлены комментарии для объяснения работы каждой части кода.
Пример работы:
Если вызвать функцию с аргументом 1234.56, она вернет строку:
Конечно! Вот пример функции на Clarion, которая преобразует числовую сумму в текстовое представление на английском языке. Этот код аналогичен вашему исходному, но адаптирован для английского языка.а можешь написать функцию, чтобы выдавала сумму прописью по-английски на Clarion? какие идеи? Хотелось бы код целиком
Код: Выделить всё
SummCharEnglish FUNCTION (REAL RMoney) ! Declare Procedure
Buff STRING(255)
grp1 GROUP, PRE(), DIM(255), OVER(Buff)
D STRING(1)
END
KooP BYTE
Buf STRING(16)
grp2 GROUP, PRE(), DIM(16), OVER(Buf)
B STRING(1)
END
Names STRING(20), DIM(3)
Mon SHORT, DIM(6)
I BYTE
J BYTE
SKoop STRING(8)
!--------------------------------------------------------------
CODE ! Begin processed code
Buff=''
IF Rmoney <= 0
Buff = 'zero dollars and 00 cents'
DO ProcedureReturn
.
Buf=Format(RMoney,@N_016.2)
DO ParseAmount
DO FormatDollars
DO FormatCents
Buff=Clip(Buff) &' and '& Format(KooP,@n02) & SKooP
IF d[1]=' '
LOOP i=2 to 255
d[i-1]=d[i]
.
.
IF Sub(Buff,1,3) = 'dol' THEN Buff = 'zero ' & Buff .
DO ProcedureReturn
!--------------------------------------------------------------
ParseAmount Routine ! Parse the amount into categories
!--------------------------------------------------------------
LOOP I=1 TO 6
Mon[I]=0
.
LOOP I=1 TO 16
IF B[I]=' ' THEN B[I]='0' ELSE BREAK .
.
I=Len(Clip(Buf))-3
KooP=Sub(Buf,Len(Clip(Buf))-1,2) ! cents
Names[1]='billion'
Mon[1]=Sub(Buf,2,3) ! billions
Names[2]='million'
Mon[2]=Sub(Buf,5,3) ! millions
Names[3]='thousand'
Mon[3]=Sub(Buf,8,3) ! thousands
Mon[4]=Sub(Buf,11,3) ! units
!-----------------------------------------------------------------------
FormatDollars Routine ! Format dollars part
!-----------------------------------------------------------------------
LOOP i=1 TO 4
Buf=Format(Mon[i],@n_03)
LOOP j=1 TO 3
IF B[j]=' '
B[j]='0'
ELSE
BREAK
.
.
IF Mon[i]=0 THEN CYCLE .
LOOP j=1 TO 3
CASE j
OF 1; DO FormatHundreds
OF 2; DO FormatTens
OF 3; DO FormatUnits
END
.
.
!--------------------------------------------------------------
FormatHundreds ROUTINE ! Format hundreds
!--------------------------------------------------------------
CASE b[j]
OF 1; Buff=Clip(Buff)&' one hundred'
OF 2; Buff=Clip(Buff)&' two hundred'
OF 3; Buff=Clip(Buff)&' three hundred'
OF 4; Buff=Clip(Buff)&' four hundred'
OF 5; Buff=Clip(Buff)&' five hundred'
OF 6; Buff=Clip(Buff)&' six hundred'
OF 7; Buff=Clip(Buff)&' seven hundred'
OF 8; Buff=Clip(Buff)&' eight hundred'
OF 9; Buff=Clip(Buff)&' nine hundred'
END
!--------------------------------------------------------------
FormatTens ROUTINE ! Format tens
!--------------------------------------------------------------
CASE b[j]
OF 1; j+=1
CASE b[j]
OF 1; Buff=Clip(Buff)&' eleven'
OF 2; Buff=Clip(Buff)&' twelve'
OF 3; Buff=Clip(Buff)&' thirteen'
OF 4; Buff=Clip(Buff)&' fourteen'
OF 5; Buff=Clip(Buff)&' fifteen'
OF 6; Buff=Clip(Buff)&' sixteen'
OF 7; Buff=Clip(Buff)&' seventeen'
OF 8; Buff=Clip(Buff)&' eighteen'
OF 9; Buff=Clip(Buff)&' nineteen'
OF 0; Buff=Clip(Buff)&' ten'
END
CASE i
OF 1; Buff=Clip(Buff)&' billion'
OF 2; Buff=Clip(Buff)&' million'
OF 3; Buff=Clip(Buff)&' thousand'
END
OF 2; Buff=Clip(Buff)&' twenty'
OF 3; Buff=Clip(Buff)&' thirty'
OF 4; Buff=Clip(Buff)&' forty'
OF 5; Buff=Clip(Buff)&' fifty'
OF 6; Buff=Clip(Buff)&' sixty'
OF 7; Buff=Clip(Buff)&' seventy'
OF 8; Buff=Clip(Buff)&' eighty'
OF 9; Buff=Clip(Buff)&' ninety'
END
!--------------------------------------------------------------
FormatUnits Routine ! Format units
!--------------------------------------------------------------
CASE i
OF 1
CASE b[j]
OF 1; Buff=Clip(Buff)&' one billion'
OF 2; Buff=Clip(Buff)&' two billion'
OF 3; Buff=Clip(Buff)&' three billion'
OF 4; Buff=Clip(Buff)&' four billion'
OF 5; Buff=Clip(Buff)&' five billion'
OF 6; Buff=Clip(Buff)&' six billion'
OF 7; Buff=Clip(Buff)&' seven billion'
OF 8; Buff=Clip(Buff)&' eight billion'
OF 9; Buff=Clip(Buff)&' nine billion'
OF 0; Buff=Clip(Buff)&' billion'
END
OF 2
CASE b[j]
OF 1; Buff=Clip(Buff)&' one million'
OF 2; Buff=Clip(Buff)&' two million'
OF 3; Buff=Clip(Buff)&' three million'
OF 4; Buff=Clip(Buff)&' four million'
OF 5; Buff=Clip(Buff)&' five million'
OF 6; Buff=Clip(Buff)&' six million'
OF 7; Buff=Clip(Buff)&' seven million'
OF 8; Buff=Clip(Buff)&' eight million'
OF 9; Buff=Clip(Buff)&' nine million'
OF 0; Buff=Clip(Buff)&' million'
END
OF 3
CASE b[j]
OF 1; Buff=Clip(Buff)&' one thousand'
OF 2; Buff=Clip(Buff)&' two thousand'
OF 3; Buff=Clip(Buff)&' three thousand'
OF 4; Buff=Clip(Buff)&' four thousand'
OF 5; Buff=Clip(Buff)&' five thousand'
OF 6; Buff=Clip(Buff)&' six thousand'
OF 7; Buff=Clip(Buff)&' seven thousand'
OF 8; Buff=Clip(Buff)&' eight thousand'
OF 9; Buff=Clip(Buff)&' nine thousand'
OF 0; Buff=Clip(Buff)&' thousand'
END
OF 4
CASE b[j]
OF 1; Buff=Clip(Buff)&' one'
OF 2; Buff=Clip(Buff)&' two'
OF 3; Buff=Clip(Buff)&' three'
OF 4; Buff=Clip(Buff)&' four'
OF 5; Buff=Clip(Buff)&' five'
OF 6; Buff=Clip(Buff)&' six'
OF 7; Buff=Clip(Buff)&' seven'
OF 8; Buff=Clip(Buff)&' eight'
OF 9; Buff=Clip(Buff)&' nine'
END
END
!--------------------------------------------------------------
FormatCents ROUTINE ! Format cents
!--------------------------------------------------------------
IF SUB(CLIP(KooP),-2,1) = 1
SKooP = ' cents'
EXIT
.
CASE SUB(CLIP(KooP),-1,1)
OF 1
SKooP = ' cent'
ELSE
SKooP = ' cents'
END
!--------------------------------------------------------------
ProcedureReturn ROUTINE
d[1]=Upper(d[1])
RETURN(Buff)
Адаптация для английского языка: Все текстовые строки переведены на английский язык, включая названия чисел, валюты (доллары и центы) и разрядов (миллиарды, миллионы, тысячи).
Логика форматирования: Логика форматирования чисел осталась прежней, но адаптирована под английский язык. Например, добавлены правильные окончания для чисел и валюты.
Читаемость: Код разделен на подпрограммы, такие как ParseAmount, FormatDollars, FormatHundreds, FormatTens, FormatUnits, и FormatCents, что делает его более модульным и понятным.
Комментарии: Добавлены комментарии для объяснения работы каждой части кода.
Пример работы:
Если вызвать функцию с аргументом 1234.56, она вернет строку:
Этот код можно использовать для преобразования числовых сумм в текстовое представление на английском языке.one thousand two hundred thirty-four dollars and 56 cents
пзц побаловался :)
(С)а что так можно было?
Ответ:Задача: можешь написать функцию на Clarion в зависимости от параметра возвращающую разделитель целой и дробной части числа, или разделитель целой и дробной части денежной единицы, или разделитель в краткой дате Windows. Можно чтением реестра или с помощью API
Конечно! В Clarion можно использовать API-функции Windows для получения разделителей, таких как разделитель целой и дробной части числа, разделитель денежных единиц или разделитель в краткой дате. Вот пример функции, которая возвращает нужный разделитель в зависимости от переданного параметра:
Код: Выделить всё
GetSeparator PROCEDURE(LONG separatorType), STRING
MAP
END
GetSeparator PROCEDURE(LONG separatorType)
LOC:DecimalSeparator STRING(1)
LOC:MonetarySeparator STRING(1)
LOC:DateSeparator STRING(1)
LOC:Buffer STRING(255)
CODE
CASE separatorType
OF 1 ! Разделитель целой и дробной части числа
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, LOC:DecimalSeparator, 1)
RETURN LOC:DecimalSeparator
OF 2 ! Разделитель целой и дробной части денежной единицы
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SMONTHOUSANDSEP, LOC:MonetarySeparator, 1)
RETURN LOC:MonetarySeparator
OF 3 ! Разделитель в краткой дате Windows
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, LOC:DateSeparator, 1)
RETURN LOC:DateSeparator
ELSE
RETURN '' ! Возвращаем пустую строку, если тип разделителя не распознан
END
separatorType — параметр, который определяет тип разделителя:
1 — разделитель целой и дробной части числа (например, точка или запятая).
2 — разделитель целой и дробной части денежной единицы.
3 — разделитель в краткой дате Windows (например, / или .).
GetLocaleInfo — API-функция Windows, которая возвращает информацию о локали. В данном случае используется для получения разделителей.
LOCALE_USER_DEFAULT — указывает на текущие настройки локали пользователя.
LOCALE_SDECIMAL, LOCALE_SMONTHOUSANDSEP, LOCALE_SDATE — константы, определяющие тип информации, которую нужно получить:
LOCALE_SDECIMAL — разделитель дробной части числа.
LOCALE_SMONTHOUSANDSEP — разделитель денежной единицы.
LOCALE_SDATE — разделитель даты.
Пример использования:
Код: Выделить всё
Separator STRING(1)
Separator = GetSeparator(1) ! Получить разделитель дробной части числа
MESSAGE('Разделитель дробной части числа: ' & Separator)
P.S. народ, делитесь, кто что успел нарыть. А то пиндосы во всю стараются уронить deepseek
-
- Полимат
- Сообщения: 1810
- Зарегистрирован: 25 Март 2009, 21:55
- Благодарил (а): 24 раза
- Поблагодарили: 10 раз
пзц побаловался :)
Как вы работаете с ними, через виртуалку, докер или другие варианты?
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
пзц побаловался :)
я через браузер. У меня знакомый ставил локально, вполне говорит быстро работает, но у него видяха нВидео 32 гб. Говорит общался через повершелл. Но есть оболочки. Моя видяха 16, по нижней планке проходит. Но обучать дальше прийдется самому.gopstop2007 писал(а): 02 Февраль 2025, 15:12 Как вы работаете с ними, через виртуалку, докер или другие варианты?
пзц побаловался :)
у нового чата есть кнопка Artifacts.
Artifacts — это полные, готовые к запуску фрагменты кода или файлы, которые могут быть использованы для различных задач. Они часто применяются в разработке программного обеспечения для автоматизации процессов, создания прототипов или демонстрации функционала.
Что я умею?
Создавать веб-страницы на основе ваших инструкций.
Писать HTML, CSS и JavaScript код.
Генерировать интерактивные элементы пользовательского интерфейса (UI).
Объединять все части кода в один файл для удобства использования.
Проверять работоспособность созданного кода перед отправкой.
Для чего я нужен?
Я помогаю быстро создавать прототипы веб-страниц, решать задачи по программированию и предоставлять готовые решения, которые можно сразу использовать или модифицировать под свои нужды. Это может быть полезно для:
Разработчиков, которым нужно быстро проверить идею.
Учителей и студентов, изучающих основы веб-разработки.
Дизайнеров, желающих перевести свои макеты в работающий код.
Любого, кто хочет получить готовый результат без лишних усилий.
Artifacts — это полные, готовые к запуску фрагменты кода или файлы, которые могут быть использованы для различных задач. Они часто применяются в разработке программного обеспечения для автоматизации процессов, создания прототипов или демонстрации функционала.
Что я умею?
Создавать веб-страницы на основе ваших инструкций.
Писать HTML, CSS и JavaScript код.
Генерировать интерактивные элементы пользовательского интерфейса (UI).
Объединять все части кода в один файл для удобства использования.
Проверять работоспособность созданного кода перед отправкой.
Для чего я нужен?
Я помогаю быстро создавать прототипы веб-страниц, решать задачи по программированию и предоставлять готовые решения, которые можно сразу использовать или модифицировать под свои нужды. Это может быть полезно для:
Разработчиков, которым нужно быстро проверить идею.
Учителей и студентов, изучающих основы веб-разработки.
Дизайнеров, желающих перевести свои макеты в работающий код.
Любого, кто хочет получить готовый результат без лишних усилий.
пзц побаловался :)
deepseek мне больше зашел. Там можно грузить исходники. Здесь попробовал, по другому:
ответ:написать для языка программирования Clarion класс, чтобы сворачивал программу в трей (панель задач), с методами типа:
cTray CLASS, TYPE, MODULE('myTray.clw'), LINK('myTray.clw')
TRAYDATA LIKE(NOTIFYICONDATA), PRIVATE ! данные о трэе
IconID long(100) ! уникальный ID иконы
TipText CSTRING(64) ! текст для "типчика"
EscHide BYTE ! флаг - по ESC прятаться
MinHide BYTE ! флаг - прятаться при минимизации (ICONIZED)
UsePopup BYTE ! использовать popup по правой кнопке
TrayPopup CSTRING(64), PRIVATE
Init PROCEDURE ! инит надо делать после открытия окна
Kill PROCEDURE
AddIcon PROCEDURE(STRING IconName) ! добавить икону на трэй
ChangeIcon PROCEDURE(STRING IconName) ! изменить икону на трэе
RemoveIcon PROCEDURE ! удалить икону с трэя
ChangeTip PROCEDURE(STRING TipText) ! изменить текст "типчика"
ShowWnd PROCEDURE ! показать окно
HideWnd PROCEDURE ! спрятать окно
TakeEvent PROCEDURE, BYTE ! обработка событий для трэя
END
Код: Выделить всё
<!-- Clarion does not support HTML directly, but here is the equivalent Clarion code for your request -->
CODE
MAP('myTray.clw')
cTray CLASS, TYPE, MODULE('myTray.clw'), LINK('myTray.clw')
TRAYDATA LIKE(NOTIFYICONDATA), PRIVATE ! данные о трэе
IconID LONG(100) ! уникальный ID иконы
TipText CSTRING(64) ! текст для "типчика"
EscHide BYTE ! флаг - по ESC прятаться
MinHide BYTE ! флаг - прятаться при минимизации (ICONIZED)
UsePopup BYTE ! использовать popup по правой кнопке
TrayPopup CSTRING(64), PRIVATE ! текст для контекстного меню
Init PROCEDURE ! инициализация после открытия окна
CLEAR(TRAYDATA)
TRAYDATA.hWnd = THIS.Window.Handle ! Установка HWND окна
TRAYDATA.uID = IconID ! Уникальный ID иконки
TRAYDATA.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP
TRAYDATA.uCallbackMessage = WM_USER + 100 ! Сообщение обратного вызова
STRING(TipText, SIZE(TipText)) = 'Tooltip' ! Текст подсказки
STRING(TRAYDATA.szTip, SIZE(TRAYDATA.szTip)) = TipText
Shell_NotifyIcon(NIM_ADD, ADDRESS(TRAYDATA)) ! Добавление иконки в трей
Kill PROCEDURE
Shell_NotifyIcon(NIM_DELETE, ADDRESS(TRAYDATA)) ! Удаление иконки из трея
AddIcon PROCEDURE(STRING IconName)
LOCAL hIcon : LONG
hIcon = LoadImage(0, IconName, IMAGE_ICON, 0, 0, LR_LOADFROMFILE)
IF hIcon
TRAYDATA.hIcon = hIcon
Shell_NotifyIcon(NIM_MODIFY, ADDRESS(TRAYDATA)) ! Обновление иконки
END
ChangeIcon PROCEDURE(STRING IconName)
AddIcon(IconName)
RemoveIcon PROCEDURE
TRAYDATA.hIcon = 0
Shell_NotifyIcon(NIM_MODIFY, ADDRESS(TRAYDATA))
ChangeTip PROCEDURE(STRING NewTipText)
STRING(TRAYDATA.szTip, SIZE(TRAYDATA.szTip)) = NewTipText
Shell_NotifyIcon(NIM_MODIFY, ADDRESS(TRAYDATA))
ShowWnd PROCEDURE
ShowWindow(THIS.Window.Handle, SW_SHOW)
HideWnd PROCEDURE
ShowWindow(THIS.Window.Handle, SW_HIDE)
TakeEvent PROCEDURE, BYTE
LOCAL Message : LONG
Message = GETMESSAGE()
SELECT Message
CASE WM_LBUTTONDBLCLK
ShowWnd()
CASE WM_RBUTTONDOWN
IF UsePopup THEN
TrackPopupMenu(TrayPopup, TPM_LEFTALIGN, MOUSE_X(), MOUSE_Y(), 0, THIS.Window.Handle, 0)
END
END
END
END MAP
пзц побаловался :)
ради прикола озадачил перевести Сишный код на Клару (народ же переводит философию в математику и программирование):
ответ:
Вот примерный перевод кода на Clarion с использованием WinAPI:
Важные замечания:
1. Для работы с WinAPI функциями были добавлены прототипы
2. Структура PARAMS адаптирована под Clarion
3. Используются CSTRING для работы со строками
4. Обработка диалога через MAP-структуры Clarion
5. Добавлены константы для элементов управления
6. Для вызова функции из DLL используется CALL с адресом
Обратите внимание, что необходимо:
1. Создать ресурсы для диалогового окна (IDD_DIALOG)
2. Проверить соглашение о вызовах для API функций
3. Убедиться в правильности обработки строковых параметров
4. Добавить недостающие константы ошибок (kgERROR_*)
5. Настроить проект для работы с WinAPI
Это базовая структура, которая может потребовать дополнительной настройки в зависимости от версии Clarion и особенностей реализации keygen.dll.
Spoiler
Код: Выделить всё
// keygen.cpp : Defines the entry point for the application.
#include "stdafx.h"
#include "resource.h"
#include "include\aspr_keygen.h"
#define MAX_LOADSTRING 100
#define RegistrationKeyGenerateName "RegistrationKeyGenerate"
typedef DWORD (__stdcall *ASPRegistrationKeyGenerate)(IN OUT PARAMS *Params);
HINSTANCE KeyGenDll;
ASPRegistrationKeyGenerate RegKeyGenerate;
//---------------------------------------------------------------------
// Source Code Template, KeyGen v0.01
BOOL GenerateKey( LPSTR* KeyStr, LPSTR NameStr, DWORD& Res )
{
PARAMS P;
memset(&P, 0, sizeof(PARAMS));
// Registration name
P.RegName = NameStr;
// Mode number (1..15)
P.ModeID = 2;
// Expiration date
P.ExpirationDate.Day = 0;
P.ExpirationDate.Month = 0;
P.ExpirationDate.Year = 0;
// Constant for encryption
P.EncryptionConst = 699935518;
// HardwareID
P.HardwareID = "";
// Signature size in bits
P.SignatureBits = 96;
// Constants from project file
P.C1 =
"AC08B45461D28EB";
P.C3 =
"A93A5FB8C78D04F1";
P.C6 =
"26D6BB434014649375231C68A655B81D314AEAF3CE32C6DC8BD"\
"CBCB9EEDC61EBA3C4A2119685E22205B782C88BFAF21FE98D4"\
"474FBDB1AFA539B05F09EF60DDF5BA8224161942B9582D37DD"\
"D624A97C373E5BB33BFC2335A674E4839D72253BA62B97F0B3"\
"6BCA5B4001353FED5D28FED31FA53C343F381BE121E106F669"\
"5B3CB";
P.C7 =
"1726DAE1BD153379F1FB0F4F2E00C06D39A733B7715D108EF0C"\
"518A11DF528394E37F744E1CEE1B4B411FEAFD7DDE0E281042"\
"A728F85FEDB91C8C2ECECF31873C77D68053D550EB8549FDE2"\
"C1885F40B68E1F0FF3383B747882AA517EB6F9061E23650222"\
"85F1B1BEA91F83E2C4CD66BF0C636FC79B81A738D65D6F5BF8"\
"0234D7";
memset(KeyStr, 0, 100 );
P.RegKey = (LPTSTR)KeyStr; // Buffer for registration key
P.RegKeySize = 100; // Size of a buffer for reg. key
// Generating...
Res = RegKeyGenerate(&P);
if(Res == kgERROR_SUCCESS)
{
memcpy(KeyStr, P.RegKey, P.RealKeySize);
return TRUE;
}
else return FALSE;
}
//---------------------------------------------------------------------
void ProcessRegistration( HWND hwnd )
{
DWORD Res;
char* ResStr;
char KeyStr[256];
char NameStr[256];
int size;
size = GetDlgItemText(hwnd, IDC_REGNAME_EDIT, NameStr, 256);
if (size > 0) NameStr[size] = 0;
memset(&KeyStr, 0, sizeof(KeyStr));
if(GenerateKey( (LPSTR*)KeyStr, (LPSTR)NameStr, Res ) == FALSE)
{
switch (Res)
{
case kgERROR_KG_ERROR : ResStr = "Key generator error!"; break;
case kgERROR_MODE_UNKNOWN : ResStr = "Unknown mode number!"; break;
case kgERROR_REGNAME_ERROR : ResStr = "Incorrect registration name!"; break;
case kgERROR_SIGNATURE_ERROR : ResStr = "Unknown mode signature!"; break;
case kgERROR_BUFFER_TOO_SMALL : ResStr = "Result buffer too small!"; break;
case kgERROR_CONSTANTS_UNDEFINED : ResStr = "Incorrect constants!"; break;
case kgERROR_HARDWAREID_ERROR : ResStr = "Invalid HardwareID key!"; break;
}
MessageBox(hwnd, ResStr, "Error", MB_ICONINFORMATION);
}
else
{
SetDlgItemText(hwnd, IDC_REGKEY_EDIT, KeyStr);
}
}
//---------------------------------------------------------------------
BOOL APIENTRY DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
// Cmd
case WM_INITDIALOG:
SetDlgItemText(hwnd, IDC_REGNAME_EDIT, "Registered User");
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_GENERATE:
ProcessRegistration( hwnd );
break;
case IDC_EXIT:
EndDialog(hwnd, IDC_EXIT);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
}
return FALSE;
}
//---------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow){
// LoadLibrary "keygen.dll"
KeyGenDll = LoadLibrary("keygen.dll");
if(KeyGenDll == NULL)
{
MessageBox(0, "keygen.dll not found!", "Error", MB_ICONSTOP);
return 0;
}
// GetProcAddress "ASPRegistrationKeyGenerate"
RegKeyGenerate = (ASPRegistrationKeyGenerate)GetProcAddress(KeyGenDll, RegistrationKeyGenerateName);
if(RegKeyGenerate == NULL)
{
MessageBox(0, "`ASPRegistrationKeyGenerate` function not found!", "Error", MB_ICONSTOP);
FreeLibrary(KeyGenDll);
return 0;
}
// DialogBox "IDD_DIALOG"
DialogBox(NULL,(LPSTR)MAKEINTRESOURCE(IDD_DIALOG),NULL,(DLGPROC/*WNDPROC*/)DlgProc);
if(KeyGenDll != NULL) FreeLibrary(KeyGenDll);
return 0;
}
Вот примерный перевод кода на Clarion с использованием WinAPI:
Код: Выделить всё
PROGRAM
MAP
END
END
;----------------------------------------------------------
; Структуры данных
;----------------------------------------------------------
PARAMS GROUP,TYPE
RegName LONG
ModeID LONG
ExpirationDate GROUP
Day WORD
Month WORD
Year WORD
END
EncryptionConst LONG
HardwareID LONG
SignatureBits LONG
C1 LONG
C3 LONG
C6 LONG
C7 LONG
RegKey LONG
RegKeySize LONG
RealKeySize LONG
END
DATE_STRUCT EQUATE(PARAMS.ExpirationDate)
;----------------------------------------------------------
; Импорт функций WinAPI
;----------------------------------------------------------
Kernel32 PROCEDURE(LPCSTR),LONG,NAME('LoadLibraryA'),RAW
GetProcAddress PROCEDURE(LONG,LPCSTR),LONG,RAW,PASCAL
FreeLibrary PROCEDURE(LONG),BOOL,RAW,PASCAL
MessageBox PROCEDURE(HWND,LPSTR,LPSTR,LONG),LONG,RAW,PASCAL
GetDlgItemText PROCEDURE(HWND,LONG,LPSTR,LONG),LONG,RAW,PASCAL
SetDlgItemText PROCEDURE(HWND,LONG,LPSTR),BOOL,RAW,PASCAL
DialogBoxParam PROCEDURE(HINSTANCE,LPSTR,HWND,LONG,LONG),LONG,RAW,PASCAL
;----------------------------------------------------------
KeyGenDll LONG
RegKeyGenerate LONG
kgERROR_SUCCESS EQUATE(0)
MAX_LOADSTRING EQUATE(100)
IDD_DIALOG EQUATE(100)
IDC_REGNAME_EDIT EQUATE(101)
IDC_REGKEY_EDIT EQUATE(102)
IDC_GENERATE EQUATE(103)
IDC_EXIT EQUATE(104)
;----------------------------------------------------------
; Прототипы процедур
;----------------------------------------------------------
GenerateKey PROCEDURE(*CSTRING,*CSTRING,*LONG),BOOL
ProcessRegistration PROCEDURE(HWND)
DlgProc PROCEDURE(HWND,ULONG,LONG,LONG),LONG
;----------------------------------------------------------
GenerateKey PROCEDURE(*CSTRING KeyStr, *CSTRING NameStr, *LONG Res)
P LIKE(PARAMS)
C1 CSTRING('AC08B45461D28EB')
C3 CSTRING('A93A5FB8C78D04F1')
C6 CSTRING('26D6BB434014649375231C68A655B81D314AEAF3CE32C6DC8BDCBCB9EEDC61EBA3C4A2119685E22205B782C88BFAF21FE98D4474FBDB1AFA539B05F09EF60DDF5BA8224161942B9582D37DDD624A97C373E5BB33BFC2335A674E4839D72253BA62B97F0B36BCA5B4001353FED5D28FED31FA53C343F381BE121E106F6695B3CB')
C7 CSTRING('1726DAE1BD153379F1FB0F4F2E00C06D39A733B7715D108EF0C518A11DF528394E37F744E1CEE1B4B411FEAFD7DDE0E281042A728F85FEDB91C8C2ECECF31873C77D68053D550EB8549FDE2C1885F40B68E1F0FF3383B747882AA517EB6F9061E2365022285F1B1BEA91F83E2C4CD66BF0C636FC79B81A738D65D6F5BF80234D7')
END
CODE
CLEAR(P)
P.RegName = ADDRESS(NameStr)
P.ModeID = 2
P.EncryptionConst = 699935518
P.SignatureBits = 96
P.C1 = ADDRESS(C1)
P.C3 = ADDRESS(C3)
P.C6 = ADDRESS(C6)
P.C7 = ADDRESS(C7)
P.RegKey = ADDRESS(KeyStr)
P.RegKeySize = 100
Res = CALL(RegKeyGenerate, ADDRESS(P))
IF Res = kgERROR_SUCCESS THEN RETURN TRUE
RETURN FALSE
;----------------------------------------------------------
ProcessRegistration PROCEDURE(HWND hwnd)
Res LONG
KeyStr CSTRING(256)
NameStr CSTRING(256)
CODE
GetDlgItemText(hwnd, IDC_REGNAME_EDIT, NameStr, 256)
KeyStr = ''
IF NOT GenerateKey(KeyStr, NameStr, Res) THEN
CASE Res
OF kgERROR_KG_ERROR
MessageBox(hwnd, 'Key generator error!', 'Error', 40h)
OF kgERROR_MODE_UNKNOWN
MessageBox(hwnd, 'Unknown mode number!', 'Error', 40h)
OF kgERROR_REGNAME_ERROR
MessageBox(hwnd, 'Incorrect registration name!', 'Error', 40h)
OF kgERROR_SIGNATURE_ERROR
MessageBox(hwnd, 'Unknown mode signature!', 'Error', 40h)
OF kgERROR_BUFFER_TOO_SMALL
MessageBox(hwnd, 'Result buffer too small!', 'Error', 40h)
OF kgERROR_CONSTANTS_UNDEFINED
MessageBox(hwnd, 'Incorrect constants!', 'Error', 40h)
OF kgERROR_HARDWAREID_ERROR
MessageBox(hwnd, 'Invalid HardwareID key!', 'Error', 40h)
END
ELSE
SetDlgItemText(hwnd, IDC_REGKEY_EDIT, KeyStr)
END
;----------------------------------------------------------
DlgProc PROCEDURE(HWND hDlg, ULONG uMsg, LONG wParam, LONG lParam)
CODE
CASE uMsg
OF WM_INITDIALOG
SetDlgItemText(hDlg, IDC_REGNAME_EDIT, 'Registered User')
RETURN 1
OF WM_COMMAND
CASE LOWORD(wParam)
OF IDC_GENERATE
ProcessRegistration(hDlg)
OF IDC_EXIT
END(DialogResult, 1)
END
RETURN 1
END
RETURN 0
;----------------------------------------------------------
MAP
WINDOW('Keygen'),AT(,,200,150),SYSTEM,GRAY,DOUBLE
STRING('Name:'),AT(10,10)
ENTRY(IDC_REGNAME_EDIT),AT(50,10,100),USE(?NameEdit)
BUTTON('Generate',IDC_GENERATE),AT(10,40)
STRING('Key:'),AT(10,70)
ENTRY(IDC_REGKEY_EDIT),AT(50,70,100),USE(?KeyEdit)
BUTTON('Exit',IDC_EXIT),AT(10,100)
END
;----------------------------------------------------------
Main PROCEDURE
CODE
KeyGenDll = Kernel32('keygen.dll')
IF KeyGenDll = 0 THEN
MessageBox(0, 'keygen.dll not found!', 'Error', 10h)
RETURN
END
RegKeyGenerate = GetProcAddress(KeyGenDll, 'ASPRegistrationKeyGenerate')
IF RegKeyGenerate = 0 THEN
MessageBox(0, 'Function not found!', 'Error', 10h)
FreeLibrary(KeyGenDll)
RETURN
END
DIALOG(DlgProc, IDD_DIALOG)
FreeLibrary(KeyGenDll)
1. Для работы с WinAPI функциями были добавлены прототипы
2. Структура PARAMS адаптирована под Clarion
3. Используются CSTRING для работы со строками
4. Обработка диалога через MAP-структуры Clarion
5. Добавлены константы для элементов управления
6. Для вызова функции из DLL используется CALL с адресом
Обратите внимание, что необходимо:
1. Создать ресурсы для диалогового окна (IDD_DIALOG)
2. Проверить соглашение о вызовах для API функций
3. Убедиться в правильности обработки строковых параметров
4. Добавить недостающие константы ошибок (kgERROR_*)
5. Настроить проект для работы с WinAPI
Это базовая структура, которая может потребовать дополнительной настройки в зависимости от версии Clarion и особенностей реализации keygen.dll.
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5226
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 12 раз
- Поблагодарили: 63 раза
пзц побаловался :)
Видимо, для использования win api может помочь. Для большинства это не простая задача, прототипировать функции win api и выискивать примеры использования.
У меня тут мысль закралась, может таким способом можно реанимировать топспидовские компиляторы для 64 битной архитектуры...
У меня тут мысль закралась, может таким способом можно реанимировать топспидовские компиляторы для 64 битной архитектуры...
C6/C12, ШВС, tps/btrieve.