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

» Вопросы по Delphi (до версии 2009) - часть 6

Автор: Frodo_Torbins
Дата сообщения: 15.05.2011 21:20
R3Pa4eK
Откуда такой странный способ декларации импортируемых функций? В справке правильный вариант описан иначе:
Цитата:
You can import a routine under a different name from the one it has in the library. If you do this, specify the original name in the external directive:

Код: external stringConstant1 name stringConstant2;

where the first stringConstant gives the name of the library file and the second stringConstant is the routine's original name.
Автор: Frodo_Torbins
Дата сообщения: 15.05.2011 21:33
R3Pa4eK
Да, нужно прочитать в какой-нибудь книжке, как в делфи правильно делается импорт функций. Или обратится в раздел Фриланс.

О, пока писал пост уже превратился в "del"
Автор: R3Pa4eK
Дата сообщения: 15.05.2011 21:39
Frodo_Torbins
Зачем мне обработка сообщений в течение заданного времени? Мне надо запустить .exe и ожидать ее завершения, чтобы программа была активной.
Автор: Frodo_Torbins
Дата сообщения: 15.05.2011 22:44
R3Pa4eK
На самом деле эти две задачи очень похожи, но если исходный код вам об этом не говорит, то лучше не берите в голову.
Исправление импорта библиотек помогло?
Автор: R3Pa4eK
Дата сообщения: 16.05.2011 15:37
Frodo_Torbins
Не могу понять, как обойтись без result? И как узнать с какого процесса была запущена библиотека?

Добавлено:
Вот , теперь вроде все должно работать:
[more]
library InnoExec;

uses
Windows, SysUtils;

var
_QUIT: Boolean;

{$R *.res}

const
MAX_PATH = 260;
TH32CS_SNAPPROCESS = $00000002;
INVALID_HANDLE_VALUE = -1;
PROCESS_TERMINATE = $0001;
_PM_REMOVE = 1;
STARTF_USESHOWWINDOW = 1;
NORMAL_PRIORITY_CLASS = $00000020;

type
TProcessEntry32 = record
dwSize: DWORD;
cntUsage: DWORD;
th32ProcessID: DWORD;
th32DefaultHeapID: DWORD;
th32ModuleID: DWORD;
cntThreads: DWORD;
th32ParentProcessID: DWORD;
pcPriClassBase: Longint;
dwFlags: DWORD;
szExeFile: array[0..MAX_PATH] of Char;
end;

_TMsg = record
hWnd: HWND;
msg: Word;
wParam: Word;
lParam: LongWord;
Time: TFileTime;
pt: TPoint;
end;

TProcessInformation = record
hProcess: THandle;
hThread: THandle;
dwProcessId: DWORD;
dwThreadId: DWORD;
end;

TStartupInfo = record
cb: DWORD;
lpReserved: Longint;
lpDesktop: Longint;
lpTitle: PChar;
dwX: DWORD;
dwY: DWORD;
dwXSize: DWORD;
dwYSize: DWORD;
dwXCountChars: DWORD;
dwYCountChars: DWORD;
dwFillAttribute: DWORD;
dwFlags: DWORD;
wShowWindow: Word;
cbReserved2: Word;
lpReserved2: Byte;
hStdInput: THandle;
hStdOutput: THandle;
hStdError: THandle;
end;

//Çàïóñê ôàéëà è îæèäàíèÿ åãî çàâåðøåíèÿ
function _CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle;
external 'CreateToolhelp32Snapshot@kernel32.dll stdcall';
function _Process32First(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
external 'Process32First@kernel32.dll stdcall';
function _Process32Next(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
external 'Process32Next@kernel32.dll stdcall';
function _OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle;
external 'OpenProcess@kernel32.dll stdcall';
function _TerminateProcess(hProcess: THandle; uExitCode: UINT): BOOL;
external 'TerminateProcess@kernel32.dll stdcall';
function _CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';
function _PeekMessage(var lpMsg: _TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax,
wRemoveMsg: UINT): BOOL; external 'PeekMessageA@user32.dll stdcall';
function _TranslateMessage(const lpMsg: _TMsg): BOOL; external 'TranslateMessage@user32.dll stdcall';
function _DispatchMessage(const lpMsg: _TMsg): Longint; external 'DispatchMessageA@user32.dll stdcall';
function _CreateProcess(lpApplicationName: PChar; lpCommandLine: PChar; lpProcessAttributes, lpThreadAttributes: DWORD;
bInheritHandles: BOOL; dwCreationFlags: DWORD;
lpEnvironment: PChar; lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
var lpProcessInformation: TProcessInformation): BOOL;
external 'CreateProcessA@kernel32.dll stdcall';
/////////////////////////////////////////////////////////////////

procedure _Application_ProcessMessages;
var
Msg: _TMsg;
begin
if not _PeekMessage(Msg, 0, 0, 0, _PM_REMOVE) then
Exit;
_TranslateMessage(Msg);
_DispatchMessage(Msg);
end;

function _KillProcess(ProcessID: DWORD): Boolean;
var
hProcess: THandle;
begin
hProcess:= _OpenProcess(PROCESS_TERMINATE, False, ProcessID);
Result:= _TerminateProcess(hProcess, 0);
_CloseHandle(hProcess);
end;

function _ArrayCharToString(ArrayChar: array of Char): string;
var
i: Integer;
str: string;
begin
for i:= 0 to MAX_PATH do
if (ArrayChar[i]) <> #0 then
str:= str + ArrayChar[i]
else Break;
Result:= str;
end;

function _ProcIsRunning(Process: string; ProcessID: DWORD): Boolean;
var
Snap: THandle;
pe32: TProcessEntry32;
begin
Result:= False;
if Pos('\', Process) > 0 then Process:= ExtractFileName(Process);
Snap:= _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Snap = INVALID_HANDLE_VALUE then Exit;
pe32.dwSize:= SizeOf(pe32);
if _Process32First(Snap, pe32) then
while _Process32Next(Snap, pe32) do
begin
if pe32.th32ProcessID = ProcessID then
if (LowerCase(_ArrayCharToString(pe32.szExeFile)) = LowerCase(Process)) then
begin
Result:= True;
Break;
end;
if _QUIT then Break;
_Application_ProcessMessages;
end;
_CloseHandle(Snap);
end;

function _CreateProcessInInnoSetup(const EXEName, Parameters, DestDir: string; const Show: Word;
TerminateChild: Boolean): BOOL stdcall;
var
PI: TProcessInformation;
SI: TStartupInfo;
ProcessId: DWORD;
ProcessName: string;
CmdLine: string;
begin
_QUIT:= False;
CmdLine:= '"' + EXEName + '" ' + Parameters;
SI.cb:= SizeOf(SI);
SI.dwFlags:= STARTF_USESHOWWINDOW;
SI.wShowWindow:= Show;
try
Result:= _CreateProcess('', PChar(CmdLine), 0, 0, False, NORMAL_PRIORITY_CLASS,
'', PChar(DestDir), SI, PI);
except
end;
if Result then
begin
ProcessName:= ExtractFileName(EXEName);
ProcessId:= PI.dwProcessId;
_CloseHandle(PI.hProcess);
_CloseHandle(PI.hThread);
while _ProcIsRunning(ProcessName, ProcessID) do;
if _QUIT and TerminateChild then _KillProcess(ProcessID);
end;
end;

exports _CreateProcessInInnoSetup;

begin
end.
[/more] Но при вызове функции - ошибка. Как исправить? Выручайте.
Автор: Frodo_Torbins
Дата сообщения: 16.05.2011 22:23
Какая ошибка? И какая у вас версия делфи?
Автор: R3Pa4eK
Дата сообщения: 17.05.2011 16:21
Frodo_Torbins
[more=Вот такая ошибка...] [/more][


Цитата:
И какая у вас версия делфи?

7-я

Добавлено:
Вызов библиотеки произвожу вот так:

function _CreateProcessInInnoSetup(const EXEName, Parameters, DestDir: string; const Show: Word; TerminateChild: Boolean):BOOL; external '_CreateProcessInInnoSetup@files:InnoExec.dll stdcall';
Автор: Frodo_Torbins
Дата сообщения: 17.05.2011 21:32
R3Pa4eK
Я не в курсе как производится вызов библиотеки в скриптах инно, но в исходниках на делфи он производится так:
Код: function _CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; stdcall; external 'kernel32.dll' name 'CreateToolhelp32Snapshot';
Автор: ShIvADeSt
Дата сообщения: 18.05.2011 01:57
Frodo_Torbins
R3Pa4eK
Мне одному кажется или на самом деле эти вопросы не совсем относятся к типовым вопросам (аля ФАК) по Дельфи? ИМХО нужно либо найти в моем разделе топик по инносетапу или создать и назвать что то типа вызов функций инносетапа из приложений Дельфи. Так как здесь подобные вопросы немного не в тему.
Автор: Aladdinych
Дата сообщения: 18.05.2011 15:12
Помогите плз.
Разбираюсь с работой одного компонента.
Он является наследником TGraphicControl.
Как выяснить последовательность выполнения методов и событий при создании компонента? Того, что сидит в теле конструктора недостаточно для понимания.
Например как прорисовывается объект, на какие процедуры передается управление, когда объект попадает в фокус.
Как можно протарассировать компонент?

Добавлено:
Речь идет о Delphi 7

Добавлено:
еще уточнение, где задается какие и в какой последовательности будут запускаться методы компонента когда запускается приложение содержащее этот компонент.
Автор: AlekXL
Дата сообщения: 18.05.2011 19:13
Aladdinych
Идешь в файл, где объявлен компонент(вероятно Controls.pas). Вызываешь окно списка функций( есть Gexperts, CnWizards)
Вводить туда частичное имя нужной функции, например для отрисовки обычно используются Paint и WM_PAINT. Анализируешь

Цитата:
Например как прорисовывается объект, на какие процедуры передается управление, когда объект попадает в фокус.
В фокус могут попасть компоненты, у которых есть окно,типо TEdit, TButton и так далее. У TGraphicControl не своего окна, он отрисовывается в окне и на Canvas родителя. Так что в фокус попасть он не может - лишь его Parent может.
Если нужно как-то особенно отрисовывать наследник TGraphicControl, когда его Parent в фокусе, нужно в процедуре отрисовки включить проверку


Код: if Parent.Focused then begin
// special painting
end
else begin
//not focused Paining
end;
Автор: Aladdinych
Дата сообщения: 19.05.2011 11:25
попробовал оттрассировать и выяснил, что при запуске приложения первым делом управление передается методу mousemove этого объекта. посткольку он наследник TgraphicControl, посмотрел справку - оказывается на него передается автоматически управление при поступлении от ОС сообщения WM_MOUSEMOVE. А вот при клике на объекте почему-то автоматически вызывается метод Paint. Не нашел в справке условий по которому он срабатывает.
Автор: AlekXL
Дата сообщения: 19.05.2011 16:29

Цитата:
попробовал оттрассировать и выяснил, что при запуске приложения первым делом управление передается методу mousemove этого объекта.

это скорей всего неверно

Цитата:
Не нашел в справке условий по которому он срабатывает.

блин. Windows посылает сообщение WM_PAINT, когда окну нужно перерисоваться, сначала VCL диспетчирует его в процедуру WMPaint, а далее в Paint. Ставишь бряк на Paint, и видишь в Call Stack <приблизительный> стек вызова процедур(нужно компилировать с флагом Use Debug DCUs и Stack Frames)

Цитата:
Не нашел в справке условий по которому он срабатывает.
Такие вещи в справке не пишутся, иначе объем документации по VCL был бы не мешьше объема исходного кода VCL
Зачем вам это вообще знать? Во многом знании много печали.
Если у тебя конкретная задача, озвучь, а так... Судя по твоим вопросам ты новичок в Windows и Delphi программировании, и за ручку провести тебя до уровня спеца - такое никто тебе не предложит (бесплатно)
Автор: delover
Дата сообщения: 20.05.2011 06:31
Ребят, эт не в качестве рекламы, а просто хочу поделиться радостью. RegExpr - может остаться без работы )))). Шутка конечно, но в ней большая доля истины. Посмотрите кому не сложно компонентик, я его выложил на:
http://cc.embarcadero.com/Item/28316
(Simply refactor)

При конвертировании 3000 html файлов моя программка делала это за 15 минут. Я уходил курить. Так что отладочка того что нужно конвертить заняла чуть больше недели. Если бы я использовал другой инструмент и выполнение было бы немного дольше, то потратил бы 2 недели. Самого компенетна, всмысле без программного кода хватает почти на 100%, а нетривиальные вещи стали гораздо легче в выполнении.
Автор: R3Pa4eK
Дата сообщения: 20.05.2011 14:17
Как можно узнать с какого процесса запущена библиотека (dll)?

Добавлено:
И как прервать работу WaitForSingleObject и завершить все запущенные им процессы?
Автор: delover
Дата сообщения: 20.05.2011 19:31
R3Pa4eK
JCL папка bin файл ToolHelpViewer исходники рядом.
Автор: DeZepTup
Дата сообщения: 21.05.2011 00:53
R3Pa4eK
http://lmgtfy.com/?q=%D0%BA%D0%B0%D0%BA+%D0%BF%D1%80%D0%B5%D1%80%D0%B2%D0%B0%D1%82%D1%8C+%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%83+WaitForSingleObject+%D0%B7%D0%B0%D0%B2%D0%B5%D1%80%D1%88%D0%B8%D1%82%D1%8C+%D0%B7%D0%B0%D0%BF%D1%83%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B8%D0%BC+%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D1%8B
Автор: ZBEP
Дата сообщения: 23.05.2011 18:09
Здравствуйте!
Есть Access база с 1 таблицей и двумя полями.
Необходимо с помощью SQL заполнить все пустые ячейки символом "-"
Сам запрос в Access работает:

Код: UPDATE Таблица SET Поле1= "-" WHERE ISNULL(Поле1)
Автор: R3Pa4eK
Дата сообщения: 23.05.2011 18:28
Как закрыть процесс, начатый в CreateProcess? Например, при нажатии на определенную кнопку, из моей библиотеки должна вызываться функция, которая закроет все процессы, запущенные в CreateProcess. Но она почему-то не хочет работать. В чем моя ошибка?
[more=Код моей библиотеки]
library InnoExec;

uses
Windows, SysUtils;

procedure Application_ProcessMessages;
var
Msg: TMsg;
begin
if not PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
Exit;
TranslateMessage(Msg);
DispatchMessage(Msg);
end;

var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: AnsiString;

function _CreateProcess(EXEName: PAnsiChar; Parameters: PAnsiChar; Show: Word): BOOL; stdcall;
begin
CmdLine := '"' + EXEName + '" ' + Parameters;
FillChar(StartInfo, SizeOf(StartInfo), #0);
with StartInfo do
begin
cb := SizeOf(StartInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := Show;
end;
Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(EXEName)),StartInfo,ProcInfo);
if Result then
begin
while WaitForSingleObject(ProcInfo.hProcess, 10) <> WAIT_OBJECT_0 do
Application_ProcessMessages;
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end
end;

//процедура, которая вызывается при нажатии на кнопку...
procedure CloseProcess; stdcall; export;
begin
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;

exports _CreateProcess;
exports CloseProcess;

begin
end.
[/more]
Автор: volser
Дата сообщения: 23.05.2011 21:31
R3Pa4eK
Не надоело? Может пора мозг включать?
Автор: XCV81
Дата сообщения: 24.05.2011 09:42
я новичек в delphi, поэтому прошу строго не судить за "элементарный" вопрос, хочу реализовать следующее:
Есть ini файл в нем секция [Options] (из нее параметры я успешно считал), и кроме этой секции возможно наличие одной и более секций [Edit1], [Edit2] и т.д. в каждой секции 2 параметра "name" и "comand".
Как сделать чтобы программа проверяла наличие таких секций и при обнаружении оных создавала в форме кнопку с соответствующим именем и командой?
ЗЫ: Использую Delphi 2 (не знаю почему но он мне больше понравился) сабж брал тут: http://forum.ru-board.com/topic.cgi?forum=35&topic=45160&start=380 , может подскажет кто где взять нормальный установщик, а то там портабельная версия и она у меня все время вылетает с ошибкой после запуска проекта. И еще, в поисках решения вышеописанной задачи попытался использовать "SectionExists" для определения существования секции, на что получил ответ "Undeclared identifer ", uses: Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, inifiles; Я чего-то забыл подключить? или 2 delphi не знает такого?
Автор: ShIvADeSt
Дата сообщения: 24.05.2011 10:56
XCV81

Цитата:
я новичек в delphi, поэтому прошу строго не судить за "элементарный" вопрос

Это

Цитата:
Как сделать чтобы программа проверяла наличие таких секций и при обнаружении оных создавала в форме кнопку с соответствующим именем и командой?

Не элементарный вопрос. Если еще создать кнопку не сильно сложно
MyButton := TButton.Create(Form1) // как то так
то дальше придется основные параметры задавать ручками, а команду присваивать исходя из инишки - это куча условий.
Поэтому лучше вначале разобраться с более простыми вещами, а потом плавно перейти к рантайм создаваемым компонентам.
Вместо Дельфи 2 советую использовать как минимум Дельфи 3 (по крайней мере на ней гораздо больше работает из хелпа, чем на Д2).
И еще - не видно как ты пытаешься вызвать SectionExists, поэтому трудно что то конкретное сказать
Автор: XCV81
Дата сообщения: 24.05.2011 13:26

Цитата:
не видно как ты пытаешься вызвать SectionExists


if IniFile.SectionExists('Edit1') then
ShowMessage('Раздел присутствует')
end;

если раздел найден то показываем соответствующее сообщение
Автор: KrgUser
Дата сообщения: 24.05.2011 14:07
Насколько я понял, из кода, написанного на Delphi7, можно вызывать методы из dll, написанной на C#, с помощью COM Interop интерфейсы. Был бы благодарен за ссылки на толковые руководства. Спасибо
Автор: vintage 1
Дата сообщения: 25.05.2011 15:08
Здравствуйте РЕБЯТА
Пожалуйста объясните как создать свою DLL + правильно её прописать в скрипте от Inno Setup?
Автор: XCV81
Дата сообщения: 25.05.2011 17:08

Цитата:
объясните как создать свою DLL

какую?

Цитата:
правильно её прописать в скрипте от Inno Setup?

что значит прописать? некоторые длл просто копируются и потом используются программами для которых предназначены, а если тебе надо зарегить ее в винде... тогда:
[Run]
Filename: "{sys}\regsvr32.exe"; Parameters: "/s ""put_k_dll_posle_ustanovki\tvoya_dll.dll""";

не знаю как кто, но я не понял толком о чем вы спрашивали
Автор: vintage 1
Дата сообщения: 25.05.2011 17:43
XCV81

Цитата:
какую?

Любую например SREP.exe мне надо чтобы она была в dll - формате (SREP.dll)


Цитата:
что значит прописать?

Прописать где то [more=так]function ISSRepExtract(var OveralPct:integer;PctOfTotal:double; InName, OutFile: string; DeleteInFile:boolean; callback: longword):BOOL; external 'ISSrepExtract@files:ISDone.dll stdcall';
или в простую функцию.
[/more]


Цитата:
некоторые длл просто копируются и потом используются программами для которых предназначены

Вот а как сделать?


Цитата:
а если тебе надо зарегить ее в винде... тогда

спасибо.
Автор: R3Pa4eK
Дата сообщения: 25.05.2011 21:06
Помогите плиз. Не нашел примеров по использованию DirectX в Delphi. Мне надо загрузить изображения(в самых разных форматах) .
Автор: V1s1ter
Дата сообщения: 25.05.2011 22:50
R3Pa4eK
Если я правильно понял Вам нужна связка DelphiX+ImageEn
DelphiX - работа с DirectX
http://www.micrel.cz/Dx/
ImageEn - загрузка изображения(в самых разных форматах)
http://www.hicomponents.com/
Автор: ShIvADeSt
Дата сообщения: 26.05.2011 03:17
vintage 1

Цитата:
Любую например SREP.exe мне надо чтобы она была в dll - формате (SREP.dll)

Вы вначале прочитайте в разница между исполняемым модулем и динамически подключаемой библиотекой. То что у них заголовок MZ не означает, что ЛЮБОЙ ехешник превращается с помощью магических действий в библиотеку. Берете читаете про функции, про вызовы функций, потом делаете простейшую библиотеку и приложение, которое ее вызывает, и только после этого начинаете писать библиотеку под InnoSetup.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


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