Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi 2

Автор: RomanTim
Дата сообщения: 06.06.2006 10:49
George_Lucky
Стоит или нет - решать тебе, попробуй перевести один проект, потом другой - а там уже определишься, с семеркой они живут вместе без проблем.

Глюков хватает - не меньше чем в 7й, на достаточно сложных COM-библиотеках на мой взгляд работает менее стабильно, память жрет с удовольствием.

С другой стороны (наверное) более корректная поддержка современногол WinAPI, на мой взгляд IDE стала намного удобнее, .NET на паскале (но только 1.1)

С переходом вроде никаких проблем не было - разве что в сторонних компонентах, которые уже не развиваются, пришлось дефайны на новую версию добавить.
Автор: reenoip
Дата сообщения: 06.06.2006 13:07
Существует ли способ установить (именно "установить", а не запустить/остановить) свою службу в обход консольной команды /install? Т.е. программным путём?
Автор: EVD
Дата сообщения: 06.06.2006 13:32
reenoip
Функция CreateService из WinApi
Автор: Betorgon
Дата сообщения: 06.06.2006 16:50
Можно ли сделать так что-бы при использования холста(Canvas) в Delphi при изменения чего либо на нём не было мигания?
Автор: reenoip
Дата сообщения: 06.06.2006 16:52
EVD, замечательно. А можно пример для Delphi?
А то всё, что я нашёл, - относительно С ((
Автор: RomanTim
Дата сообщения: 06.06.2006 20:31
Betorgon
Если для рисования на контроле в его Paint (OnPaint) то можно завести TBitmap, рисовать на него тогда, когда картинка меняется, а в Paint делать
Canvas.Draw(X, Y, bmp);

reenoip
Смотри в модуле SvcMgr - TServiceApplication.RegisterServices, можно даже в отладке пройтись, если отладочные DCU включить
Автор: FireZone
Дата сообщения: 06.06.2006 20:43
reenoip
Попробуй так:
Код: uses ... winsvc ...
...
function InstallService(filename, svcname, svcdisplayname: string): boolean;
var
hSCM, hService: THandle;
begin
result:= false;

hSCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if hSCM <> 0 then
try
hService:= CreateService(
hSCM, PChar(svcname), PChar(svcdisplayname), SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL, PChar(filename), nil, nil, nil, nil, nil);
if (hService <> 0) then
try
result := true
finally
CloseServiceHandle(hService)
end
finally
CloseServiceHandle(hSCM)
end
end;
Автор: 0315
Дата сообщения: 07.06.2006 02:40
???
создаю файл: file of string[64]
записываю в него строку, всё нормально
пытаюсь считать в переменную (s64: string[64])
выдаёт ошибку:[Error] Unit1.pas(238): Incompatible types
в чём прикол?
Автор: ShIvADeSt
Дата сообщения: 07.06.2006 03:37
0315

Цитата:
???
создаю файл: file of string[64]
записываю в него строку, всё нормально
пытаюсь считать в переменную (s64: string[64])
выдаёт ошибку:[Error] Unit1.pas(238): Incompatible types
в чём прикол?

Прикол в том, что у тебя на 10 строке стоит неправильный параметр, который вводит в заблуждение компилятор.
А если по сути, то дай кусок, как пишешь и как читаешь.
Кстати File of string[64] - это маньячество? если тебе надо просто в файл текс тписать то TextFile тип который тебе надо.
Автор: FireZone
Дата сообщения: 07.06.2006 04:22
0315

Цитата:
в чём прикол?
В том, что компилятор считает string[64] и string[64] разными типами. Надо делать примерно так:
Код: type
TStr64 = string[64];
var
f: file of TStr64;
s64: TStr64;
Автор: George_Lucky
Дата сообщения: 07.06.2006 11:02
RomanTim
Спасибо за совет!
Автор: 0315
Дата сообщения: 08.06.2006 03:18

Цитата:
Кстати File of string[64] - это маньячество? если тебе надо просто в файл текс тписать то TextFile тип который тебе надо.


Согласен, что маньячество, но мне помимо ввода текста в файл, необходимо изменять его в нужной строке с нужной позиции... Если кто подскажет способ легче, буду очень признателен.

FireZone спасибо за совет надо будет попробовать.
Автор: Butcher
Дата сообщения: 08.06.2006 08:11
0315
по-моему, намного удобнее работать с текстовыми файлами посредством TStringList.
Автор: RomanTim
Дата сообщения: 08.06.2006 08:12
0315

Цитата:
Согласен, что маньячество, но мне помимо ввода текста в файл, необходимо изменять его в нужной строке с нужной позиции... Если кто подскажет способ легче, буду очень признателен.

Можно грузить файл в StringList, а после изменения сохранять обратно на диск.
Получаешь свободный доступ к строкам, которые к тому же могут быть разной длины (вдруг пригодится). Есть, правда, ограничение - та строка, которая одно целое с точки зрения программы, не может содержать перевод строки.
Автор: Aladdinych
Дата сообщения: 08.06.2006 08:25
У меня есть приложение написанное на Delphi 5 и в нем компоненты работающие с базой данных Interbase. Это прежде всего TTable и TQuery.
Мне нужно написать DLL, Функции из которой вызывались бы из приложения и чтобы изнутри таких функций можно было обращаться к компонентам TTable и TQuery созданным в основном приложении. Как получить к ним доступ из DLL?
Как это сделать?

Автор: FireZone
Дата сообщения: 08.06.2006 09:32
Aladdinych

Цитата:
Как это сделать?

Объявлять callback функции и передавать указатели на них в твою dll, чтобы она их вызывала. А напрямую обращение делать нельзя.

Добавлено:
Напиши подробнее, что должна делать dll с этими компонентами, и я накидаю примерчик с коллбэками.
Автор: Aladdinych
Дата сообщения: 09.06.2006 07:29
Моя dll это что-то вроде плаггина.
Есть основная программа. И мне надо заложить на будущее средство для расширения ее возможностей за счет вызова внешних модулей.
В основной программе есть датасеты. Мне надо:
1. Вызвать из Dll процедуру, которая выдает на экран форму для заполнения.
2. Пользователь ее заполняет, а по кнопке ОК
3. обновляются данные в датасетах (добавляются, удаляются, модифицируются записи). При этом датасеты есть объекты созданные в основной программе
4. После чего соответствующую процедуру можно выгрузить из памяти.
И как это сделать?
Автор: ArtemiyUO
Дата сообщения: 09.06.2006 07:46
ну можно примерно так
в длл объявляеш тип
type
TPShowFrm = procedure (param : integer);

у себя в длл объявляеш переменную для хранения ссылки на функцию

var
ShowFrmPrc : TPShowFrm;

Потом у тебя должна быть какаето функция иницилизации ДЛЛ. она должна быть стандартная для всех плюгинов и апликуха о ней знает, например

procedure INIT(PShowFrmPrc : TPShowFrm);
begin
ShowFrmPrc := PShowFrmPrc;
end;


а в основной программе у тебя есть процедура которая выводит твой справочник или выполняет любые другие действия, например
procedure ShowList (param : integer); //она должна быть объявлена так же как и указатель ..на неё в длл
begin
//какието действия
end;

все теперерь при подключении плюгина ты импортируеш из длл стандартную функцию иницилизации, передавая ДЛЛке указатель на функцию ядра.
Init(ShowList) или Init(@ShowList)
так можно передавать указатели на любое кол-во стандартных методов ядра, типо твое апи.

Когда тебе надо из длл вызвать функцию из основной програмы ты просто пишеш.
ShowFrmPrc(param) и вызывается процедура ShowList

Вообщем я думаю идея ясна - передать в длл указатели на функции ядра.
А вообще если поискать в инете то можно и без всего этого обойтись если воспользоваться функцией MethodAddress(), только там для меня не совсем прозрачна проблема разных адресных пространств.
Автор: OXDBA
Дата сообщения: 09.06.2006 10:09

Цитата:
В основной программе есть датасеты. Мне надо:
1. Вызвать из Dll процедуру, которая выдает на экран форму для заполнения.
2. Пользователь ее заполняет, а по кнопке ОК
3. обновляются данные в датасетах (добавляются, удаляются, модифицируются записи). При этом датасеты есть объекты созданные в основной программе

Плагин это конечно хорошо, но зачем датасеты в основной программе?
ИМХО гораздо логичнее из основной программы вызвать плагин редактирвания, который
выполнит все действия, включая сохранение, а обратно вернет только результат(True/False). Представь, что твой плагин будет вызываться из двух программ, тогда тебе прийдется два раза писать код для сохранения данных.
У меня реализация следующая - в основной программе коннект к базе и визуализация только по чтению. Все редактирование находится в плагинах(dll) куда передается только хэндл на DataBase.


Автор: boban1
Дата сообщения: 09.06.2006 10:49
у вас нет код 'Hardware monitor'?
Автор: ArtemiyUO
Дата сообщения: 09.06.2006 11:42
что ты понимаеш под "у вас нет кода хардваре монитор"? по яснее выражай плиз свои желания и вопросы.
Автор: FireZone
Дата сообщения: 09.06.2006 13:10
Aladdinych
Цитата:
В основной программе есть датасеты. Мне надо:
1. Вызвать из Dll процедуру, которая выдает на экран форму для заполнения.
2. Пользователь ее заполняет, а по кнопке ОК
3. обновляются данные в датасетах (добавляются, удаляются, модифицируются записи). При этом датасеты есть объекты созданные в основной программе
Насколько я тебя понял, всё оказывается проще, чем я думал. Делаешь обычную длл-ку с формой и делаешь в ней примерно такую функцию:
Код: type
TMyDataRec = record
field1: Integer;
field2: shortstring;
end;
// Функция выводит форму на экран и не завершается, пока форма не будет закрыта
// Если была нажата кнопка ОК, то возвращается истина, а в переменной Data введенные данные
function InputData(var Data: TMyDataRec): Boolean; stdcall;
begin
result := false;
with TMyForm.Create(nil) do
try
if ShowModal = mrOk then begin
Data.field1 := StrToInt(Edit1.Text);
Data.field2 := Edit2.Text;
result := true
end
finally
Free
end
end;
Автор: STEEL
Дата сообщения: 11.06.2006 20:58
Есть формочка, borderstyle := none, systemmenu := false
на формочке панелька.. со свойством dock, automatic, необходимо чтобы рисовалась только панелька, в тот момент когда я её перетаскиваю.. у неё появляется заголовок 8( От которого далее не избавиться. Вобщем нужна плавающая по рабочему столу панелька без системного меню. Или форма без заголовка, которую можно перетаскивать

Добавлено:
Также интересует алгоритм, когда по вводу несколькоих символов и нажатию на TAB известная команда дописывается, например как в виндовом коммандоре или любой POSIX
Автор: OOD
Дата сообщения: 11.06.2006 23:58
Как вписать путь к ехе и имя сервиса в функции для написания сервиса?:


Код:
Функции для создавания и удаления NT Services.
Можно создать NT Service от текущее приложение. Параметры:
1. CreateNTService(ExecutablePath,ServiceName: String)
ExecutablePath - Полный путь к изполнимого файла от которого создавается NT Service
ServiceName - Имя сервиза которое отобразится в Service Control Manager
Результат:
true - если операциая завершена успешно
false - если есть ошибка. Можно произвести call то
GetLastError чтобы информироваться об естество ошибки
2. DeleteNTService(ServiceName: String):boolean;
ServiceName - имя сервиза подлежающии удаления
Результат:
true - если операциая завершена успешно
false - если есть ошибка. Можно произвести call то GetLastError чтобы
информироваться об естество ошибки

Зависимости: WinSVC, Windows
Автор: Alex Kantchev, stoma@bitex.bg
Copyright: Собственное написание
Дата: 19 июня 2002 г.
***************************************************** }

// CreateNTService(ExecutablePath,ServiceName: String)
// ExecutablePath - Полный путь к изполнимого файла от
// которого создавается NT Service
// ServiceName - Имя сервиза которое отобразится
// в Service Control Manager Результат:
//Результат:
// true - если операциая завершена успешно
// false - если есть ошибка. Можно произвести
// call то GetLastError чтобы информироваться об
// естество ошибки

function CreateNTService(ExecutablePath, ServiceName: string): boolean;
var
hNewService, hSCMgr: SC_HANDLE;
// Rights: DWORD;
FuncRetVal: Boolean;
begin
FuncRetVal := False;
hSCMgr := OpenSCManager(nil, nil, SC_MANAGER_CREATE_SERVICE);
if (hSCMgr <> 0) then
begin
//Custom service access rights may be built here
//we use GENERIC_EXECUTE which is combination of
//STANDARD_RIGHTS_EXECUTE, SERVICE_START, SERVICE_STOP,
//SERVICE_PAUSE_CONTINUE, and SERVICE_USER_DEFINED_CONTROL
//You can create own rights and use them as shown in the
//commented line below.

//Rights := STANDARD_RIGHTS_REQUIRED or SERVICE_START or SERVICE_STOP
// or SERVICE_QUERY_STATUS or SERVICE_PAUSE_CONTINUE or
// SERVICE_INTERROGATE;

hNewService := CreateService(hSCMgr, PChar(ServiceName), PChar(ServiceName),
STANDARD_RIGHTS_REQUIRED, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
PChar(ExecutablePath), nil, nil, nil, nil, nil);
CloseServiceHandle(hSCMgr);
if (hNewService <> 0) then
FuncRetVal := true
else
FuncRetVal := false;
end;
CreateNTService := FuncRetVal;
end;

Запуск сервиса :

procedure StartService(ServiceName: string);
var

schService,
schSCManager: Dword;
p: PChar;
begin

p := nil;
schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if schSCManager = 0 then
RaiseLastWin32Error;
try
schService := OpenService(schSCManager, PChar(ServiceName),
SERVICE_ALL_ACCESS);
if schService = 0 then
RaiseLastWin32Error;
try
if not Winsvc.startService(schService, 0, p) then
RaiseLastWin32Error;
finally
CloseServiceHandle(schService);
end;
finally
CloseServiceHandle(schSCManager);
end;
end;
Автор: myxa0
Дата сообщения: 12.06.2006 06:42
Нужно заполнить канву image'а правильными шестиугольниками (со сторонами одинаковой длины), и затем отследить над каким шестиугольником находится мышь.
Долно получиться что-то типа этого:

\ /\ /\ /\
\ / \ / \ / \
| | | |
| | | |
/ \ / \ / \ /
/ \/ \/ \/
| | |
| | |
\ / \ / \ / \
\/ \/ \/ \


Мне кажется здесь мне дольше будут отвечать, чем, если создать отдельную тему.


С заполнением я разобрался, но как отследить над каким шестиугольником находится мышь?

Вот как я заполнил канву (в edit3 находится длина ребра, edit2-кол-во шестиугольников в ширину, edit1-кол-во в высоту):


Код:
for i:=0 to strtoint(edit1.Text)-1 do
begin
for j:=0 to strtoint(edit2.Text)-1 do
begin
t:=strtoint(edit3.Text)*((j div 2));
Image.canvas.Polygon (
[Point(strtoint(edit3.Text) div 2+(strtoint(edit3.Text)*i)+strtoint(edit3.Text)*j div 2 -t, strtoint(edit3.Text)*j-strtoint(edit3.Text)*j div 4),
Point(strtoint(edit3.Text)+strtoint(edit3.Text)*i+strtoint(edit3.Text)*j div 2-t,strtoint(edit3.Text) div 4+strtoint(edit3.Text)*j-strtoint(edit3.Text)*j div 4),
Point(strtoint(edit3.Text)+strtoint(edit3.Text)*i+strtoint(edit3.Text)*j div 2-t,(strtoint(edit3.Text) div 4)*3 +strtoint(edit3.Text)*j-strtoint(edit3.Text)*j div 4),
Point (strtoint(edit3.Text) div 2+strtoint(edit3.Text)*i+strtoint(edit3.Text)*j div 2-t,strtoint(edit3.Text)+strtoint(edit3.Text)*j-strtoint(edit3.Text)*j div 4),
point(strtoint(edit3.Text)*i+strtoint(edit3.Text)*j div 2-t,(strtoint(edit3.Text) div 4)*3+strtoint(edit3.Text)*j-strtoint(edit3.Text)*j div 4),
point(strtoint(edit3.Text)*i+strtoint(edit3.Text)*j div 2-t,strtoint(edit3.Text) div 4 + strtoint(edit3.Text)*j-strtoint(edit3.Text)*j div 4)]);
end;
end;
Автор: RomanTim
Дата сообщения: 12.06.2006 09:01
OOD
Выдержка из MSDN (вообще крайне полезно пользоваться первоисточниками):
SC_HANDLE CreateService(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName,
LPCTSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCTSTR lpBinaryPathName,
LPCTSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCTSTR lpDependencies,
LPCTSTR lpServiceStartName,
LPCTSTR lpPassword
);
lpServiceName
[in] Pointer to a null-terminated string that specifies the name of the service to install. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. Forward-slash (/) and back-slash (\) are invalid service name characters.
lpDisplayName
[in] Pointer to a null-terminated string that contains the display name to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the service control manager. Display name comparisons are always case-insensitive.

Автор: OOD
Дата сообщения: 12.06.2006 09:14
RomanTim
Первоисточник работает, но как указать пусь у exe файлу , который в дальнейшем будет использоваться и запускаться вот этого понять не могу

Добавлено:
вот пример использования:


Код:
procedure TForm1.Button1Click(Sender: TObject);
var
tmpS: string;
begin
tmpS := 'Delphi_Service_' + Application.Title;
if (CreateNTService(Application.ExeName, tmpS)) then
MessageDlg('Service ' + tmpS + ' has been successfully created!',
mtInformation, [mbOK], 0)
else
MessageDlg('Unable to create service ' + tmpS + ' Win32 Error code: ' +
IntToStr(GetLastError), mtWarning, [mbOK], 0);
end;
Автор: RomanTim
Дата сообщения: 12.06.2006 11:37
OOD
CreateService устанавливает в систему сервис, исполнимый файл которого задается параметром lpBinaryPathName, этот исполнимый файл должен уметь вести себя как сервис (в делфи в New есть спеиальный тип проекта - Service Application), lpServiceName - имя сервиса, по которому его идентифицирует система (оно же название ключа в реестре), lpDisplayName - отображаемое имя сервиса.
А вот приложение-сервис в свою очередь уже может запускать то, что ему вздумается например через CreateProcess. Задавать какое приложение должно запускаться можно, например, через конфигурационный файл.
Автор: Ramazan
Дата сообщения: 13.06.2006 06:54
В процессе разработки проекта, состоящего из основной программы и нескольких динамически подключаемых DLL столкнулся с исключением "Unknown software exception 0eedfade in module XXX at YYY" в момент вызова LoadLibrary. Исследование показало, что ошибка возникает при загрузке одной DLL из другой.
Проект и библиотеки компилируются с базовыми run-time пакетами, интерфейсные модули не изменялись. Ошибка проявилась внезапно, как обычно говорится - "до этого все работало"
В связи с этим вопрос: чем это может быть вызвано В ПРИНЦИПЕ?
Автор: greenpc
Дата сообщения: 13.06.2006 07:17
Ramazan
сама LoadLibrary не может давать ошибку.
из нелпа

Return Values

If the function succeeds, the return value is a handle to the module.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.

примерчик....

var
DLLInstance : THandle;
begin
DLLInstance := LoadLibrary(PChar('MyFirstDLL.dll'));
if (DLLInstance = 0) then begin
MessageDlg('Невозможно загрузить DLL', mtError, [mbOK], 0);
Exit;
end;

расшифровка кода ошибки :

char Buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),Buf,sizeof(Buf),NULL);
ShowMessage(Buf);

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: Событие STFilter(DBGridEh) ???


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.