ВНИМАНИЕ! Наша конференция посвящена космической тематике и компьютерным играм. Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!
|
» Delphi. Вы задаете вопрос, мы отвечаем. | страница 1 |
|
|
|
Канал Игры Мечты: «Delphi. Вы задаете вопрос, мы отвечаем.» |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
Собственно вот какое предложение, так как ЖК это, в первую очередь "Ж", а потом "К", то пусть будет тут. Если у кого есть вопросы или вы долго искали ответ на какой-то вопрос и, таки нашли: просьба оставлять тут. Только просьба не оставлять ответы на вопросы, которые можно довольно легко найти в и-нете. Пусть это будут умные вопросы.
ЗЫ: Просьба темку пока не бить, а решить надо-ли по окончанию сентября.
_________________ WARNING: By reading this post you accept that this post is genius.
Последний раз редактировалось: NRG (12:25 09-09-2008), всего редактировалось 1 раз |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
как сделать коллекцию объектов определённого класса или разных если есть такая возможность?
_________________ This is what you get ...
(c) Radiohead |
|
|
Криптон
1011 EGP
       Рейтинг канала: 3(44) Репутация: 164 Сообщения: 2667 Откуда: Москва Зарегистрирован: 05.04.2008
 |
|
Sh.Tac. : |
как сделать коллекцию объектов определённого класса или разных если есть такая возможность?
|
Что вы понимаете под "коллекцией"? Если объект класса TCollection (или его наследника), то без глубинной переработки кода такие коллекции могут работать только с классом TCollectionItem и его наследниками. Конечно, есть вариант создать наследника TCollectionItem со свойством, ссылающимся на объект нужного класса, это достаточно просто. Такой вариант вас интересует?
Последний раз редактировалось: Криптон (17:12 05-09-2008), всего редактировалось 1 раз |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Кроме упомянутого Криптоном TCollection, есть еще TObjectList, TObjectQueue, TObjectStack. Способов дофига, вопрос в том, какой смысл ты вкладываешь в понятие "коллекция".
_________________ У меня бисера не доxеpа.
Последний раз редактировалось: Shirson (19:37 05-09-2008), всего редактировалось 1 раз |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
Самый примитивный - это самописные списки.
Код: |
PFIFOOneSide=^RFIFOOneSize;
RFIFOOneSide=record
Object:TObject // или вообще Pointer
Next:PFIFOOneSide;
end;
Ну и работать с ними:
TEnumObjectProc=procedure (Obj:TObject);
procedure EnumObjectsFrom(FIFO:PFIFOOneSide; Proc:TEnumObjectProc);
begin
while FIFO<>nil do begin
Proc(FIFO.Object);
FIFO:=FIFO.Next;
end;
end;
Ну и выделение удаление памяти
|
_________________ WARNING: By reading this post you accept that this post is genius. |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
Распишу один классный прикольчик. В И-нете вроде такого не было...
Довольно часто приходится делать навороченный интерфейс и мы все пользуемся закладками(TPageControl). Иногда на разных закладках идут разные по смыслу вещи и хочется их разрабатывать отдельно. Да и код становится не читабельным. Вот давайте рассмотрим как можно легко и просто разнести разные закладки в разные модули.
Идея основана на том, что каждая закладка в дизаинтайме это отдельная форма. То есть при разработке вы работаете с ней как с обыкновенной формой, а при запуске приложения она выглядит как закладка. Делается это довольно просто. Я приведу код и дам некоторые пояснения, применение данному подходу можите найти сами.
Код: |
type
TMyForm=class(TForm)
private
procedure CMTextChanged(var Message:TMessage); message CM_TEXTCHANGED;
public
constructor Create(AOwner:TComponent);
end;
implementation
constructor TMyForm.Create(AOwner:TComponent);
begin
Inherited Create(AOwner);
If AOwner is TTabSheet Then Begin
// Если владелец - Вкладка, будем делать вид, что формы нет.
Self.Parent:=AOwner;
Self.BorderStyle:=bsNone;
Self.Align:=alClient;
TTabSheet(AOwner).Caption:=Self.Caption;
End;
end;
procedure TMyForm.CMTextChanged(var Message:TMessage);
begin
// А это чтоб при изменении свойства Caption менялся текст на закладке.
inherited;
If Parent is TTabSheet Then TTabSheet(Parent).Caption:=Caption;
end; |
Ну и применение, тут без кода не обойдешься... Делается пустая закладка и выполняется код:
Код: |
TMyForm.Create(Sheet); |
_________________ WARNING: By reading this post you accept that this post is genius. |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Warstone, вопрос чисто из интереса - а что мешает использовать фреймы? Т.е. дизайнерим вид закладки на отдельной форме и ложим на закладку фрейм с данной формой. И viola, совсем без кода
_________________ У меня бисера не доxеpа. |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
То что на закладку надо что-то ложить. А в моем случае при развитии ещё и драг-дроп получается красивый... Когда вы можите вытащить форму из закладок и она будет "как настоящая" и обратно дропануть ее. (Появится новая закладка) Вообще очень удобно и не жрет почти ничего, так как не пересоздается (Хотя тут, конечно, надо VCL почитать, у них форма пересоздается по каждому чиху, а не через Get/SetWindowLong). В случае-же с фреймами у тебя полюбому будет пересоздаваться или форма или закладка. (Это можно обойти, но извратом типа кеширования форм/фреймов)
_________________ WARNING: By reading this post you accept that this post is genius. |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Если DnD всяке, тогда да. А так, фрейм самое простое решение.
P.S. Используя VCL не стоит задумываться на кешированием форм. Идеология не та
_________________ У меня бисера не доxеpа. |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
Shirson : |
А так, фрейм самое простое решение.
|
Тут есть ещё 1 идея: Сначала ты делал формы, потом заказчик сказал "многа форм, нада что-то делать" Ну и все... А так... Все эти формы в закладки, а сам разрабатывай дальше. Работы на час.
Скоро выложу работу ехе с большим роличеством ресурсов и возможностью их ужать.
_________________ WARNING: By reading this post you accept that this post is genius. |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
Итак преамбула: Мы делаем игрушку и хотим чтоб все ресурсы (картинки, графика и т.д.) лежали в одном ехе. Тут придется освоить несколько техник, в частности нам понадобятся:
Использование unrar.dll (Компонент работы с dll и саму dll можно скачать с www.rarlab.com)
Работа с ресурсами
Загрузка dll «из памяти»
Итак приступим: У нас будет 2 ресурса: unrar.dll и data.rar, где unrar.dll — это библиотека распаковщика, а data.rar — это архив с нашими данными. Так как мы гонимся за уменьшением размера ехе, то unrar.dll желательно тоже упаковать каким-нибудь ASPack'ом(www.aspack.com)
Создаем ресурсы
Итак, создаем main.rc фаил с следующим содержанием:
Код: |
DLL UNRAR unrar.dll
RAR DATA data.rar |
Немного надо рассказать о rc файлах. Это файлы «комманд» для компилятора ресурсов. Формат у них такой: <ТИП> <НАЗВАНИЕ> <СОДЕРЖАНИЕ>, где
ТИП — тип ресурсов, может быть Icon, RCData, да и просто любой.
НАЗВАНИЕ — Это то, как называется ресурс.
СОДЕРЖАНИЕ — фаил где этот ресурс находится. (Или просто название файла, если он находится в одной с rc файлом папки или полный путь)
На самом деле формат файла гораздо сложнее, но нам пока хватит и этого.
Теперь нам надо его скомпилировать. Запускаем cmd.exe(Пуск->Выполнить) там переходим в папку с нашим rc файлом и выполняем следующую комманду:
У нас появится main.RES в этой-же папки. Собственно все, ресурсный фаил мы создали. Подключить его можно командой компилятору {$R main.res} в основном проекте или в любом модуле.
Запускаем unrar.dll
Смысл этого действия запустить и с инициализировать unrar.dll. Есть 2 способа: простой и сложный. Простой заключается в сохранении этого файла на диске и потом его загрузки. Сложный метод заключается в том, что мы не будем выгружать dll на диск, а будем сразу инициализировать ее в памяти.
Простой метод (кликните здесь для просмотра)
Простой путь довольно тупой и я просто представлю код выгрузки dll на диск:
Код: |
var
ResInfo:THandle;
Resource:THandle;
ResLen:Cardinal;
Data:Pointer;
PLen:Cardinal;
S:String;
F:File;
begin
PLen:=GetTempPath(0, nil);
SetLength(S, PLen+1);
S[PLen]:=#0;
GetTempPath(PLen, @S[1]);
ResInfo:=FindResource(HInstance, 'UNPACK', 'DLL');
ResLen:=SizeofResource(HInstance, ResInfo);
Resource:=LoadResource(HInstance, ResInfo);
Data:=LockResource(Resource);
AssignFile(F, S);
Rewrite(F, 1);
BlockWrite(F, Data^, ResLen);
CloseFile(F);
UnlockResource(Resource);
FreeResource(Resource);
end; |
Дальше надо загрузить ее через LoadLibrary и через GetProcAddress настроить адреса процедур.
|
Сложный метод (кликните здесь для просмотра)
Как оказалось все сложное уже решено до нас, или "все уже украдено до нас" (С) Народная мудрость.
Вам надо всего-то сходить по ссылке: http://www.basegraph.com/bg/tutorials/eng_tutor_dlltools/dlltools.html и забрать оттуда DLLTools. Из этого архива нам нужен только 1 фаил. DLLLoader.pas
Его подключаете к проекту и код быстро преобразуется в ещё более простой чем "простой метод", а именно:
Код: |
var
dll:TResourceStream;
obj:TDLLLoader;
begin
obj:=TDLLLoader.Create;
dll:=TResourceStream.Create(HInstance, 'UNPACK', 'DLL');
obj.Load(dll);
dll.Free;
|
Дальше надо настраивать адреса процедур через: obj.FindExport();
Однако, TDFUnRar работает с LoadLibrary и GetProcAddress, что делать? Так как пока никто не придумал как грузить дллки так, чтоб процесс был зквивалентен LoadLibraryA(W), то мы делаем как умеем.
Цель: заставить GetProcAddress и LoadLibrary "скушать" нашу длл.
Идея: Идея не нова, она называется сплайсинг АПИ функций. Кому интересно, подробная статья лежит на wasm.ru ( тут) Я-же просто приведу код:
Cкрытый текст (кликните здесь для просмотра)
Код: |
unit APIHook;
interface
uses Windows, SysUtils, Classes, DLLLoader;
procedure LoadResourceDll(Instance: THandle; ResName: PChar; ResType: PChar; DllName:String='');
procedure SetHookState(Value:Boolean);
implementation
type
RProcInfo=record
Module:THandle;
Entry:Pointer;
OldCode:Array [0..5] of Byte;
InjectCode:Array[0..5] of Byte;
Name:String;
end;
RDLLInfo=record
Obj:TDLLLoader;
Name:String;
Loaded:Cardinal;
end;
PDLLInfo=^RDLLInfo;
TDLLLoaderList=class
Private
RelockedInfo:Array of RProcInfo;
RILen:Cardinal;
DLLInfo:Array of RDLLInfo;
RDILen:Cardinal;
FIsActive:Boolean;
public
constructor Create;
destructor Destroy;
property IsActive:Boolean read FIsActive write FIsActive;
procedure AddDLLLoaderAs(Who:TDLLLoader; DllName:String);
end;
var
DLLManager:TDLLLoaderList;
procedure LoadResourceDll(Instance: THandle; ResName: PChar; ResType: PChar; DllName:String='');
var
dll:TResourceStream;
obj:TDLLLoader;
RName:String;
begin
if DllName='' Then DllName:=ResName;
RName:=ResName;
obj:=TDLLLoader.Create;
dll:=TResourceStream.Create(Instance, RName, ResType);
obj.Load(dll);
dll.Free;
DLLManager.AddDLLLoaderAs(obj, UpperCase(DllName));
end;
procedure SetHookState(Value:Boolean);
begin
DLLManager.IsActive:=Value;
end;
function NewLoadLibraryA(lpLibFileName: PAnsiChar): HMODULE; stdcall;
var
Written:Cardinal;
S:String;
begin
If not DLLManager.FIsActive Then Begin
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[0].Entry, @DLLManager.RelockedInfo[0].OldCode, 6, Written);
Result:=LoadLibraryA(lpLibFileName);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[0].Entry, @DLLManager.RelockedInfo[0].InjectCode, 6, Written);
End Else Begin
S:=lpLibFileName;
S:=UpperCase(S);
For Written:=0 to DLLManager.RDILen-1 do begin
If DLLManager.DLLInfo[Written].Name=S then begin
Result:=Cardinal(@DLLManager.DLLInfo[Written]);
Inc(DLLManager.DLLInfo[Written].Loaded);
Exit;
end;
end;
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[0].Entry, @DLLManager.RelockedInfo[0].OldCode, 6, Written);
Result:=LoadLibraryA(lpLibFileName);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[0].Entry, @DLLManager.RelockedInfo[0].InjectCode, 6, Written);
End;
end;
function NewLoadLibraryW(lpLibFileName: PWideChar): HMODULE; stdcall;
var
Written:Cardinal;
S:String;
begin
If not DLLManager.FIsActive Then Begin
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[1].Entry, @DLLManager.RelockedInfo[1].OldCode, 6, Written);
Result:=LoadLibraryW(lpLibFileName);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[1].Entry, @DLLManager.RelockedInfo[1].InjectCode, 6, Written);
End Else Begin
S:=lpLibFileName;
S:=UpperCase(S);
For Written:=0 to DLLManager.RDILen-1 do begin
If DLLManager.DLLInfo[Written].Name=S then begin
Result:=Cardinal(@DLLManager.DLLInfo[Written]);
Inc(DLLManager.DLLInfo[Written].Loaded);
Exit;
end;
end;
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[1].Entry, @DLLManager.RelockedInfo[1].OldCode, 6, Written);
Result:=LoadLibraryW(lpLibFileName);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[1].Entry, @DLLManager.RelockedInfo[1].InjectCode, 6, Written);
End;
end;
function NewLoadLibraryExA(lpLibFileName: PAnsiChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
var
Written:Cardinal;
S:String;
begin
If not DLLManager.FIsActive Then Begin
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[2].Entry, @DLLManager.RelockedInfo[2].OldCode, 6, Written);
Result:=LoadLibraryExA(lpLibFileName, hFile, dwFlags);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[2].Entry, @DLLManager.RelockedInfo[2].InjectCode, 6, Written);
End Else Begin
If ((dwFlags AND LOAD_LIBRARY_AS_DATAFILE) <> LOAD_LIBRARY_AS_DATAFILE) Then Begin
S:=lpLibFileName;
S:=UpperCase(S);
For Written:=0 to DLLManager.RDILen-1 do begin
If DLLManager.DLLInfo[Written].Name=S then begin
Result:=Cardinal(@DLLManager.DLLInfo[Written]);
Inc(DLLManager.DLLInfo[Written].Loaded);
Exit;
end;
end;
End;
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[2].Entry, @DLLManager.RelockedInfo[2].OldCode, 6, Written);
Result:=LoadLibraryExA(lpLibFileName, hFile, dwFlags);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[2].Entry, @DLLManager.RelockedInfo[2].InjectCode, 6, Written);
End;
end;
function NewLoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; stdcall;
var
Written:Cardinal;
S:String;
begin
If not DLLManager.FIsActive Then Begin
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[3].Entry, @DLLManager.RelockedInfo[3].OldCode, 6, Written);
Result:=LoadLibraryExW(lpLibFileName, hFile, dwFlags);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[3].Entry, @DLLManager.RelockedInfo[3].InjectCode, 6, Written);
End Else Begin
If ((dwFlags AND LOAD_LIBRARY_AS_DATAFILE) <> LOAD_LIBRARY_AS_DATAFILE) Then Begin
S:=lpLibFileName;
S:=UpperCase(S);
For Written:=0 to DLLManager.RDILen-1 do begin
If DLLManager.DLLInfo[Written].Name=S then begin
Result:=Cardinal(@DLLManager.DLLInfo[Written]);
Inc(DLLManager.DLLInfo[Written].Loaded);
Exit;
end;
end;
End;
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[3].Entry, @DLLManager.RelockedInfo[3].OldCode, 6, Written);
Result:=LoadLibraryExW(lpLibFileName, hFile, dwFlags);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[3].Entry, @DLLManager.RelockedInfo[3].InjectCode, 6, Written);
End;
end;
function NewGetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
var
Written:Cardinal;
S:String;
begin
If not DLLManager.FIsActive Then Begin
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[4].Entry, @DLLManager.RelockedInfo[4].OldCode, 6, Written);
Result:=GetProcAddress(hModule, lpProcName);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[4].Entry, @DLLManager.RelockedInfo[4].InjectCode, 6, Written);
End Else Begin
If (hModule>=Cardinal(@DLLManager.DLLInfo[0]))AND(hModule<=Cardinal(@DLLManager.DLLInfo[DLLManager.RDILen])) then begin
Result:=PDLLInfo(Pointer(hModule))^.Obj.FindExport(lpProcName);
Exit;
end;
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[4].Entry, @DLLManager.RelockedInfo[4].OldCode, 6, Written);
Result:=GetProcAddress(hModule, lpProcName);
WriteProcessMemory(GetCurrentProcess, DLLManager.RelockedInfo[4].Entry, @DLLManager.RelockedInfo[4].InjectCode, 6, Written);
End;
end;
constructor TDLLLoaderList.Create;
type
PPointer=^Pointer;
var
i:Integer;
Readed:Cardinal;
begin
Inherited;
RILen:=5;
SetLength(RelockedInfo, RILen);
RelockedInfo[0].Name:='LoadLibraryA'+#0;
RelockedInfo[0].Module:=LoadLibrary('kernel32.dll');
RelockedInfo[0].Entry:=GetProcAddress(RelockedInfo[0].Module, @RelockedInfo[0].Name[1]);
RelockedInfo[0].InjectCode[0]:=$68;
PPointer(@RelockedInfo[0].InjectCode[1])^:=@NewLoadLibraryA;
RelockedInfo[0].InjectCode[5]:=$C3;
RelockedInfo[1].Name:='LoadLibraryW'+#0;
RelockedInfo[1].Module:=LoadLibrary('kernel32.dll');
RelockedInfo[1].Entry:=GetProcAddress(RelockedInfo[1].Module, @RelockedInfo[1].Name[1]);
RelockedInfo[1].InjectCode[0]:=$68;
PPointer(@RelockedInfo[1].InjectCode[1])^:=@NewLoadLibraryW;
RelockedInfo[1].InjectCode[5]:=$C3;
RelockedInfo[2].Name:='LoadLibraryExA'+#0;
RelockedInfo[2].Module:=LoadLibrary('kernel32.dll');
RelockedInfo[2].Entry:=GetProcAddress(RelockedInfo[2].Module, @RelockedInfo[2].Name[1]);
RelockedInfo[2].InjectCode[0]:=$68;
PPointer(@RelockedInfo[2].InjectCode[1])^:=@NewLoadLibraryExA;
RelockedInfo[2].InjectCode[5]:=$C3;
RelockedInfo[3].Name:='LoadLibraryExW'+#0;
RelockedInfo[3].Module:=LoadLibrary('kernel32.dll');
RelockedInfo[3].Entry:=GetProcAddress(RelockedInfo[3].Module, @RelockedInfo[3].Name[1]);
RelockedInfo[3].InjectCode[0]:=$68;
PPointer(@RelockedInfo[3].InjectCode[1])^:=@NewLoadLibraryExW;
RelockedInfo[3].InjectCode[5]:=$C3;
RelockedInfo[4].Name:='GetProcAddress'+#0;
RelockedInfo[4].Module:=LoadLibrary('kernel32.dll');
RelockedInfo[4].Entry:=GetProcAddress(RelockedInfo[4].Module, @RelockedInfo[4].Name[1]);
RelockedInfo[4].InjectCode[0]:=$68;
PPointer(@RelockedInfo[4].InjectCode[1])^:=@NewGetProcAddress;
RelockedInfo[4].InjectCode[5]:=$C3;
For i:=0 to RILen - 1 do begin
ReadProcessMemory(GetCurrentProcess, RelockedInfo[i].Entry, @RelockedInfo[i].OldCode, 6, Readed);
WriteProcessMemory(GetCurrentProcess, RelockedInfo[i].Entry, @RelockedInfo[i].InjectCode, 6, Readed);
end;
RDILen:=0;
FIsActive:=False;
end;
destructor TDLLLoaderList.Destroy;
var
i:LongWord;
begin
IsActive:=False;
For i:=0 to RILen-1 do FreeLibrary(RelockedInfo[i].Module);
For i:=0 to RDILen-1 do DLLInfo[i].Obj.Free;
SetLength(RelockedInfo, 0);
SetLength(DLLInfo, 0);
Inherited;
end;
procedure TDLLLoaderList.AddDLLLoaderAs(Who:TDLLLoader; DllName:String);
begin
Inc(RDILen);
SetLength(DLLInfo, RDILen);
DLLInfo[RDILen - 1].Obj:=Who;
DLLInfo[RDILen - 1].Name:=DllName;
DLLInfo[RDILen - 1].Loaded:=0;
end;
initialization
DLLManager:=TDLLLoaderList.Create;
finalization
DLLManager.Free;
end.
|
|
И теперь загрузка Dll превращается в ещё более приятное занятие:
Код: |
LoadResourceDll(HInstance, 'UNPACK', 'DLL', 'unrar.dll');
SetHookState(True); |
После этого можно использовать LoadLibrary('unrar.dll') и GetProcAddres() с хендлом, возвращенным LoadLibrary, чего мы и добивались
|
Вместо заключения
Собственно вот и все. Дальше вы настраиваете компонент TDFUnrar на свежевыгруженную dll'ку и работаете с архивом. Архив можно так-же выгрузить или заставить unrar.dll считать что он выгружен. Как это сделать — разговор отдельной статьи.
ЗЫ: Спасибо Shirson за наводку на сложный метод. Иначе я-б его писал сам.
Недописано, надо ещё метод перехвата АПИ для unrar.dll чтоб скормить ей наш архив.
_________________ WARNING: By reading this post you accept that this post is genius.
Последний раз редактировалось: Варсик (23:04 09-09-2008), всего редактировалось 3 раз(а) |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Есть утилита, которая колбасит dll в pas Всмысле превращает dll в часть static компиляции.
Так и называватся dll2pas.
_________________ У меня бисера не доxеpа.
Последний раз редактировалось: Shirson (16:16 09-09-2008), всего редактировалось 1 раз |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
За наводку спасибо... Там есть DLLLoader.pas... Я хотел делать свой, но раз есть... Правда оттуда надо убрать Inflate сжатие, так как ИМХО надо предоставлять возможность сжимать самим, чем хочется. Перепишу DLLLoader для работы с ресурсами и воткну как "сложный" путь.
добавлено спустя 8 минут:
Вообще нашел статью на королевстве Дельфи: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1294
Человек там пытается доступным образом объяснить что он делает, но если скачать его "переделки" (Переделанный DLLLoader.pas) то вы увидите там вызов библиотеки zlib. Я, конечно, всегда знал что на королевстве Дельфи сидят изверги, но чтоб для распаковки одной длл(unrar) использовать другую длл(zlib32), которая будет-таки внешней... Это помоему клиника. Так что советую пользоваться оригинальным unit'ом, ссылка на который, благо присутствует в статье.
_________________ WARNING: By reading this post you accept that this post is genius.
Последний раз редактировалось: Варсик (16:59 09-09-2008), всего редактировалось 2 раз(а) |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
zlib не внешняя, а вполне внутренняя. Т.е. подкоючив юнит zlib, больше ничего не нужно, никаких внешних частей это при работе не потребует.
Я использую её в своём формате контейнера для игровых ресурсов и она работает, не привлекая внешних модулей.
_________________ У меня бисера не доxеpа.
Последний раз редактировалось: Shirson (19:00 09-09-2008), всего редактировалось 1 раз |
|
|
Варсик
545 EGP
    Рейтинг канала: 4(81) Репутация: 117 Сообщения: 4041 Откуда: Москва Зарегистрирован: 22.12.2002
 |
|
Пардон, с gzip'ом спутал. Но все-равно смешно... Если вы включаете в ехе zlib зачем ещё один архиватор?
_________________ WARNING: By reading this post you accept that this post is genius. |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Warstone : |
Пардон, с gzip'ом спутал. Но все-равно смешно... Если вы включаете в ехе zlib зачем ещё один архиватор?
|
Нуууу.... а чёрт его знает Народ иногда чудит, а может мы чего не понимаем
_________________ У меня бисера не доxеpа. |
|
|
бухой джедай
183 EGP
  Рейтинг канала: 2(19) Репутация: 70 Сообщения: 7906 Предупреждений: 1 Откуда: Одесса:) Зарегистрирован: 08.09.2007
 |
|
вы 2 зверя с дельфином ) я вас ели ели понимаю , а что скажет человек который на компиль смотрит третий раз в жизни но желает научится ??
_________________ Так Добрый вечер...Превед с большого Бодуна...
Магистр Непросыхаемость...
Злобный Рецедивист... |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Он скажет "я на компиль смотрю третий раз в жизни, но желаю научиться".
И мы ему всячески поможем в этом
_________________ У меня бисера не доxеpа.
Последний раз редактировалось: Shirson (21:24 09-09-2008), всего редактировалось 1 раз |
|
|
бухой джедай
183 EGP
  Рейтинг канала: 2(19) Репутация: 70 Сообщения: 7906 Предупреждений: 1 Откуда: Одесса:) Зарегистрирован: 08.09.2007
 |
|
не я боюсь поглядев на выше написаное ( не написано оно ладно и хорошо руки к компилю так и тянутся ) он скорее всего выделить паку компиля и сделаит делит
_________________ Так Добрый вечер...Превед с большого Бодуна...
Магистр Непросыхаемость...
Злобный Рецедивист... |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Значит не судьба.
Если у человека фобия перед выпускными экзаменами, когда он только начал ходить в школу, отсутствие разговоров о последнем классе тут ничем не поможет.
_________________ У меня бисера не доxеpа. |
|
|
|
|
|
Канал Игры Мечты: «Delphi. Вы задаете вопрос, мы отвечаем.» |
|
К списку каналов | Наверх страницы |
Цитата не в тему: Я расслабился уже у тебя в профиле. (Romeo-must-die)
|
» Delphi. Вы задаете вопрос, мы отвечаем. | страница 1 |
|