Вопрос № 111534: Как сделать в dll или COM-объекте статическую переменную? Например, есть счётчик, который считает, сколько раз вызвалась ф-ия и возвращает это значение. Загвоздка в том, что если запущено приложение А и приложение B и оба используют эту dll(COM-объек...Вопрос № 111589: Приветствую.
Хотелось бы задать такой вот вопрос по программированию в Делфи. В общем, вот суть вопроса:
Я - начинающий Дельфист. Пишу на Delphi 7. В общем, я хочу создать программку для автозапуска с CD.
Все получается, но не знаю как сд...Вопрос № 111607: Здравствуйте! Я пишу лицензию на программу. Нужно, чтобы на каждом компьютере определялся разный AutoKey(Ключ авторизации, свой для каждого компа). Для этого ищу функцию определения серийника винчестера....Нужно чтобы функция могла определять SATA и ...Вопрос № 111645: По каким правилам компилятор Delphi 7 выполняет выравнивание переменных в сегменте данных....
Вопрос № 111.534
Как сделать в dll или COM-объекте статическую переменную? Например, есть счётчик, который считает, сколько раз вызвалась ф-ия и возвращает это значение. Загвоздка в том, что если запущено приложение А и приложение B и оба используют эту dll(COM-объект), то если приложение А вызвало эту ф-ию 3 раза, последний раз ему вернут 3. После этого, приложение B вызывает ф-ию и ему должно вернуться 4.
Отвечает: Зиновьев Дмитрий Владимирович
Здравствуйте, not used (aka mvp)!
Попробуйте хранить данные в ini-файле
Ответ отправил: Зиновьев Дмитрий Владимирович (статус: 8-ой класс)
Ответ отправлен: 29.11.2007, 12:37 Оценка за ответ: 4
Отвечает: Selya
Здравствуйте, not used (aka mvp)!
Реализуй в dll GetValue() и SetValue()
В SetValue() считай количество вызовов в глобальной переменной в dll (напр. CallCount := CallCount + 1)
А GetValue() возвращай это значение (Result := CallCount)
А само значение CallCount dll-ка должна хранить или в ini, или в реестре
Ответ отправил: Selya (статус: 1-ый класс)
Ответ отправлен: 29.11.2007, 12:46 Оценка за ответ: 4
Отвечает: PavelGM
Здравствуйте, not used (aka mvp)!
Факически вам нужен обмен данными между процессами. Классический способ для этого Memory-mapped файл (он для этого и придуман) - он будет один для всех ваших процессов - в нем и храните (кстати реестр, по некоторым данным, организован по этой же технологии - так что вариант - использование реестра). Но нельзя хранить объекты, только простые структуры (и никаких "длинных" String, либо Ansi, либо PChar). И не забудьте взаимоисключения добавить (Mutex) - все таки процессы разные, а то данные попортите.
Ответ отправил: PavelGM (статус: Студент)
Ответ отправлен: 29.11.2007, 16:39 Оценка за ответ: 3 Комментарий оценки: баян. Всё-таки Вам статус позволяет заглянуть в мини-форум, прежде чем отправить ответ
Вопрос № 111.589
Приветствую.
Хотелось бы задать такой вот вопрос по программированию в Делфи. В общем, вот суть вопроса:
Я - начинающий Дельфист. Пишу на Delphi 7. В общем, я хочу создать программку для автозапуска с CD.
Все получается, но не знаю как сделать, чтобы по нажатию кнопки, расположенной на форме, открыть файл exe. :(
Подскажите, пожалуйста, как это сделать, я буду очень рад.
Георгий.
Отвечает: Vas177
Здравствуйте, Чечин Георгий Александрович!
В секции uses добавить ShellAPI
Эта функция запускает Блокнот:
ShellExecute(Handle, nil, 'c:windows
otepad.exe', nil, nil, SW_SHOWNORMAL);
Ответ отправил: Vas177 (статус: 2-ой класс)
Ответ отправлен: 29.11.2007, 17:23 Оценка за ответ: 4 Комментарий оценки: Очень хорошо! Коротко и ясно!
Отвечает: Degtyarev Anton
Здравствуйте, Чечин Георгий Александрович!
В раздел uses нужно прописать имя модуля shellapi.
После этого можно воспользваться функцией:
ShellExecute(Handle, nil, ′c:program_name.exe′, ′′,′c:′, SW_SHOW);
у неё 6 параметров:
1. Главное окно. Здесь мы указываем Handle - окно своей программы, но можно и nil.
2. Указатель на строку, которая говорит, что надо делать. Рекомендую устанавливать nil. Возможны варианты: open (для открытия программы), print (для распечатки документов) или explore (для просмотра директории).
3. Полный путь или просто имя запускаемого файла. Желательно указывать полный путь.
4. Параметры, которые надо передать в программу.
5. Директория по умолчанию, в которой должна работать программа.
6. Команда отображения. Команд очень много, но чаще всего используется SW_SHOW для нормального отображения.
--------- Знаете для чего нужен Яndex? для проверки работы интернета
Ответ отправил: Degtyarev Anton (статус: 3-ий класс)
Ответ отправлен: 29.11.2007, 17:31 Оценка за ответ: 4 Комментарий оценки: Спасибо большое, и попутного ветра тебе, Дегтярев Антон!
Отвечает: Yumark
Здравствуйте, Чечин Георгий Александрович!
Я делал так:
корне КД кладётся файл autorun.inf. Вот его содержимое
[autorun]
ICON=autorunIcon.ico
OPEN=autorunindex.htm
создаётся папка Autorun, в которой лежит файл index.htm, в котором присутствуют строки (для запуска программ из текущего каталога):
<table width="100%">
<tr>
<td width="18%"><a href="Far1705.exe"><img SRC="install.gif" width="144" height="33" BORDER="0" active ></a></td>
</tr>
</table>
плюс в этой папке должна лежать картинка - install.gif (там просто слово - Установить)
при нажатии на эту картинку запускается (в данном случае) Far1705.exe
Надеюсь мой опыт вам поможет!
Ответ отправил: Yumark (статус: 2-ой класс)
Ответ отправлен: 29.11.2007, 17:36 Оценка за ответ: 5 Комментарий оценки: Ой, спасибо, хорошо! Супер! просто слов нет!
Отвечает: Сычёв Павел Алексеевич
Здравствуйте, Чечин Георгий Александрович!
В принципе есть процедура ShellExecute, через нее можно запустить не только exe.
Пример
ShellExecute(Application.Handle, 'open',PChar(path_to_exe), nil, nil, SW_SHOWNORMAL);
где path_to_exe=путь к exe файлу.
Если интиресно, посмотрите описание в Help
Ответ отправил: Сычёв Павел Алексеевич (статус: 1-ый класс)
Ответ отправлен: 29.11.2007, 18:49 Оценка за ответ: 4 Комментарий оценки: Спасибо. Большое спасибо. Хорошо. Очень хорошо. Спасибо огромнейшее. :)
Отвечает: Selya
Здравствуйте, Чечин Георгий Александрович!
uses
ShellApi;
...
begin
// Запуск файла
ShellExecute(Handle, nil, 'c:windowscalc.exe', nil, nil, SW_SHOW);
// Просмотр каталога
ShellExecute(Handle, nil, 'c:windows', nil, nil, SW_SHOW);
// Ссылка на сайт
ShellExecute(Handle, nil, 'http://www.site.ru', nil, nil, SW_SHOW);
Ответ отправил: Selya (статус: 1-ый класс)
Ответ отправлен: 30.11.2007, 09:00 Оценка за ответ: 4 Комментарий оценки: Спасибо. Огромное спасибо. А если еще и заработает это все дело, то вообще цены не будет твоему ответу. В общем, СПАСИБО...
Вопрос № 111.607
Здравствуйте! Я пишу лицензию на программу. Нужно, чтобы на каждом компьютере определялся разный AutoKey(Ключ авторизации, свой для каждого компа). Для этого ищу функцию определения серийника винчестера....Нужно чтобы функция могла определять SATA и IDE винчестеры. Помогите найти пожалуйста
Copyright:
Собственное написание (Осипов Евгений Анатольевич)
Дата: 23 мая 2002 г.
Присутствует неточность в топике "Как получить инфу о жестком диске?". Неточность заключается в том, что функция "GetVolumeInformation" выдает совершенно разный номер диска под системами 9х и NT. Я долго бился над этой проблемой т. к. в своей программе привязываются к номеру в своей программе для определения какой диск вставил пользователь. Па
ру раз задавал этот вопрос в форумах, но ответа так и не получил. Но недавно я нашел решение этой проблемы. Вот код моей функции для корректного определения серийного номера диска под любой ОС:
Code: function SirealNumberDisk(disk: string): string; // Определяем серийный номер диска
var VolumeName : array [0..MAX_PATH-1] of Char; FileSystemName : array [0..MAX_PATH-1] of Char; VolumeSerialNo : DWord; MaxComponentLength : DWord; FileSystemFlags
: DWord;
function GetReplaceCDNumber(num: String): String; var i, len: Integer; begin Result:= ''; len:= Length(num); if len <> 8 then exit; for i:= 1 to (len div 2) do begin Dec(len); Result:= Result + num[len ]; Result:= Result + num[len + 1]; Dec(len); end; end;
begin GetVolumeInformation(PChar(disk), VolumeName, MAX_PATH, @VolumeSerialNo, MaxComponentLe
ngth, FileSystemFlags, FileSystemName, MAX_PATH); Result:= IntToHex(Integer(VolumeSerialNo), 8); if Win32Platform <> VER_PLATFORM_WIN32_NT then Result:= GetReplaceCDNumber(Result); end;
procedure TForm1.Button1Click(Sender: TObject); begin Label1.Caption:= SirealNumberDisk('f:'); end;
Автор: Alex&Co
Сайт: http://alex-co.com.ru
Приложение:
Ответ отправил: Selya (статус: 1-ый класс)
Ответ отправлен: 30.11.2007, 09:10 Оценка за ответ: 5 Комментарий оценки: СПАСИБО!
Вопрос № 111.645
По каким правилам компилятор Delphi 7 выполняет выравнивание переменных в сегменте данных.
Отправлен: 29.11.2007, 23:06
Вопрос задал: Ddogg (статус: Посетитель)
Всего ответов: 2 Мини-форум вопроса >>> (сообщений: 6)
Отвечает: Boriss
Здравствуйте, Ddogg!
Хотите стать экспертом? Тогда делайте в таких случаях примерно такое:
1) В меню Проект выбираем пункт Опции
2) Там находим закладку Компоновщик
3) На панели Файл распределения отмечаем Детально
4) Нажимаем Ok
5) Выполняем компиляцию (Ctrl+F9)
6) В файле проекта находим файл с именем, подобным, Project1.map, а в нем детальную информацию
И 4-й класс Вам гарантирован :) (со временем ...)
--------- Вывод - то место в тексте, где вы устали думать
Ответ отправил: Boriss (статус: Профессор) Россия, Саранск Организация: mte WWW:Программирование на Паскале ---- Ответ отправлен: 30.11.2007, 08:30 Оценка за ответ: 3 Комментарий оценки: Фактически это уход от ответа.
Отвечает: Selya
Здравствуйте, Ddogg!
Обычно, когда класс располагается в памяти, то между полями остаются небольшие пространства, несодержащие никакой информации. Оказывается можно избавиться от таких участков памяти и соответственно Ваше приложение будет меньше расходовать оперативной памяти.
Но сначала обратимся к основам типов данных, используемых в Delphi, и детально рассмотрим - сколько байт памяти занимает каждый тип данных:
1 байт - boolean, char and byte
2 байт - smallInt, word, wordbool
4 байт - string, pointers, longint, integer
Теперь давайте посмотрим на объявление класса в нашем исходном коде:
TMyClass = class
private
field1: char;
field2: longint;
field3: boolean;
field4: string;
field5: byte;
field6: integer;
public
procedure proc1;
end;
теперь просуммируем байты, которы занимает каждый тип данных. По идее должно получиться 15 байт, но на самом деле это не так. Реальный размер, занимаемый данным экземпляром класса будет составлять 24 байта, т. е. 4 байта на каждое поле. Почему ? Потому что поумолчанию в Delphi, по правилам оптимизации, каждое поле располагается от предыдущего со сдвигом на 4 байта: field1 занимает 1 байт, поидее поле field2 должно следовать сразу же за field1, но по правилам оптимизации, остаются 3 байта не содержащие никакой
информации, а следовательно напрасно потерянные. А если бы field2 был бы длиной в 1 байт или 2 байта, то он был бы помещён сразу же за полем field1, потому что это не нарушает правил оптимизации.
Какой же напрашивается вывод ? А если изменить порядок объявления переменных в классе ? Я просто сгруппировал переменные по их размеру (байтовому): вместе все однобайтовые, соответственно вместе все двухбайтовые и т.д.
Вот так стал выглядеть наш класс:
TMyClass = class
private
field1: char;
field3: boolean;
field5: byte;
field2: longint;
field4: string;
field6: integer;
public
procedure proc1;
end;
С такой организацией классы, его длина стала 16 байт (сэкономили 8 байт на каждом экземпляре данного класса). Конечно же это не большая экономия памяти, но в тех случая, когда класс инициализируется многократно либо класс довольно велик, то такая экономия довольно ощутима.
Ответ отправил: Selya (статус: 1-ый класс)
Ответ отправлен: 30.11.2007, 09:14 Оценка за ответ: 2 Комментарий оценки: ответ неправильный