![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() |
-=CHE@TER=- |
![]()
Сообщение
#1
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,371 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 318 раз(а) ![]() |
Delphi programs in API.
На английском. Очень подробно всё описано, плюс есть исходные коды готовых юнитов. Например SmallUtil, в котором есть все частоиспользуемые подпрограммы, и который в размере меньше, чем SysUtils (автор так утверждает - я не проверял). |
![]() ![]() |
-=CHE@TER=- |
![]()
Сообщение
#2
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,371 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 318 раз(а) ![]() |
В Си есть такая замечательная функция, как sprintf(), которая позволяет формировать строчку со всякими '%s', '%03d' и прочим. Эта функция есть в msvcrt.dll, однако, я не люблю эту библиотеку, так как на чистой Windows 98 SE у меня её не было - она ставится только с какой-нибудь программой, да и вообще, в ядро системы не входит.
Зато в ядро системы входит wsprintf(). К сожалению, в Delphi она криво объявлена, в результате чего ей нельзя пользоваться. Как мы помним, у всех таких функций может быть разное количество аргументов - это, оказывается, решается ключевым словом "varargs": CODE function wsprintf2(Output: PChar; Format: PChar): Integer; cdecl; varargs; external 'user32.dll' name {$IFDEF UNICODE}'wsprintfW'{$ELSE}'wsprintfA'{$ENDIF}; Вот такое объявление (я его уже не помню где нашёл в Интернете) - работает. cdecl, как мы помним, говорит о том, что в отличие от stdcall, вызываемая функция не знает сколько параметров сложено на стек, так что об их снятии со стека после работы функции должна позаботиться вызывающая сторона, что в данном случае логично. Нужно только помнить пару вещей: 1) В MSDN настоятельно не рекомендуют пользоваться этой функцией (небезопасна, если криво используется), но в Windows 7 и ниже она есть (в Windows 98 есть только wsprintfA). 2) В этой функции ограничение на 1025 байт для ANSI и 1025*2 для UNICODE буфера - т.е. если строчка больше, то она просто будет отрезана. 3) Она поддерживает далеко не все возможности, которые есть в sprintf (кажется, с дробными числами не работает - см. MSDN). Пример использования (S - переменная типа String): CODE // максимальный размер буфера SetLength(S, 1025); // отрезаем по границе - сколько реально было использовано SetLength(S, wsprintf2(PChar(S), '%03d - %s', 45, PChar('Hello World!'))); P.S. Да, в Delphi есть FmtStr(), но она подключается вместе с SysUtils и ещё кучей мусора, что для небольших программ на WinAPI просто неприемлемо. |
![]() ![]() |
Упрощённая версия | Сейчас: 30th April 2025 - 21:16 |