26. marts 2005 - 18:33Der er
42 kommentarer og 1 løsning
Kan man også hente sine billeder fra en DLL
Hej.
Nu har jeg fået lavet en dll-fil med nogle procedurer samt en masse billeder... Har fundet frem til at "køre" procedurerne med eks. procedure VisForm;external'project2.dll'; det virker fint..
I mit hoved-projekt (med .exe filen), har jeg en masse "tomme" TImages. Kan det lade sig gøre at hente bitmap fra et TImage i dll-filen?
noget ala Form1.Image1.Bitmap := DLLFORM.Image1.Bitmap ? :)
hej. jeg har muligvis ikke forklaret det ordentligt :)
Hvis man har to almindelige forms i sit projekt kan man jo ret nemt gøre det med noget lign
for cc:=0 to 17 do for c:=0 to 17 do if form1.p.canvas.pixels[x+c,y+cc]<>form2.image1.Canvas.Pixels[c,cc] then form1.p.canvas.pixels[x+c,y+cc]:=form2.image1.Canvas.Pixels[c,cc]; (findes sikkert en mere rigtig metode, men det virker..)
Vil gerne vide, om det kan lade sig gøre at hente billedet fra formen i en dll-fil, istedet for blot at kopiere det fra en ALM form..
det kan godt lade sig gøre ... ikke noget problem...
men... det ville jo være lettere at loade billederne i dll-filen vha. en TImageList og så overføre den til din hovedfil.... Bitmap billederne kommer så ind i din EXE fil som en TImageList som du så kan håndtere som du vil... også det der med "form1.p.canvas.pixels"
Hvis du fortæller mig nøjagtig hvordan du vil have det, så kan jeg godt sende dig noget kode...
fed nok :) Programmet skulle gerne gøre det som det første når hoved-formen oprettes med FormCreate. På hoved-formen har jeg omkring 10 billeder i forskellige størrelser, som jeg gerne vil hente udefra. Ligesom hvis man ville bruge DLL filen som "skin" til sit program. :)
Du må meget gerne sende noget kode. min mail-adresse er post@mbsnet.dk.. er nok nemmere med kode end forklaring, hvis det er bøvlet :) På forhånd tak, mbs.
============================================ .... public StringList : TstringList; ...... end;
implementation
...
Procedure TForm1.ImportSmallBitmapImages; var bmp :TBitmap; F: Textfile; s :string; i:integer; begin setcurrentdir(FilePath); Assignfile(F,'ListOfAllBMPImages.ini'); StringList := TStringlist.Create; reset(F); bmp := TBitmap.Create; i := 0; try while not Eof(F) do begin Readln(F,s); bmp := TBitmap.Create; bmp.Height := 75; bmp.Width := 100; bmp.LoadFromFile(s); StringList.InsertObject(i,s,TObject(bmp)); inc(i); end; except on exception do MessageDlg('An error occured during the loading of Bitmap files.' + #13#10 + 'The error has occured while using the file "ListOfAllBMPImages.ini"',mtError, [mbOk], 0); end; bmp.Free; end;
//DLL filen defineres på følgende måde:
function GetBitmap(ParentApplication: TApplication; ParentForm: TForm; var StringList : TStringList;FilePath:shortstring): integer; stdcall;export;
I ovenstående eksempel har jeg liggende navnene på de bitmap billeder jeg er interesseret i, liggende i en fil med navn "ListOfAllBMPImages.ini", som jeg så henter ind og bruger til at loade bitmap billederne ind i en Tstringlist...
- jeg kan allerede se nu at jeg har glemt nogle variable definitioner etc. men da jeg ikke ved hvilket niveau du er på, så må du lige sige til hvis du har spørgsmål... det meste giver sig selv
Har prøvet lidt frem og tilbage, og det ser lovende ud. Dog kan jeg ikke helt få det til at køre. Er det ikke blot filnavnene man overfører med metoden? Hvis nu det er et enkelt billede, som man på forhånd har defineret på en form i DLL filen, og man gerne vil overføre det som TBitmap til EXE filen..? (sådan at man slipper for at have billederne liggende som seperate filer) Jeg kan godt leve med at have filerne liggende, men det kunne da være sejt at de var smidt ind i DLL filen, og man kunne have et helt skin i en enkelt fil. Men du fortjæner point for indsatsen. Smid lige et svar, så du kan få dem. .)
1) mht. TStringList: nej, det er faktisk et helt billede man overfører via TstringList og IKKE kun filnavnene - det troede jeg også først, men billedet (bitmap billedet) er med i TStringList...
2) Jeg er ikke helt klar over hvad du mener med at ligge alle billederne (skins) i en dll fil... Hvis du mener at du vil have billederne lagt ind i DLL filen "fast", så DLL filen bliver kompileret med billederne i, (så du ikke behøver at bruge de "rå" billeder mere - nu ligger de i DLL filen) så kan du gøre det ved at ligge et antal Image komponenter på en form i DLL filen. Brug dernæst "Picture" til at vælge billedet du vil have kompileret ind i DLL filen. Billedet i Image filen kan du så få sendt til exe filen ved at bruge ovennævnte metode...
1) "Picture" er placeret over til højre i Object Inspector for TImage komponenten
2) "Billedet i Image filen " .. jeg mener billedet i TImage komponenten
3) Sig til hvis du har nogle spørgsmål mht. at du ikke kan få det til at virke - at hente DLL filer ind i EXE filer og få overført variable mellem dem kan godt drille ret så meget...
Når du bruger en DLL fil i en exe fil kand er godt komme et ekstra program "ikon" nede i processlinien (linien nederst på skærmen)...
linket herunder forklarer hvordan man fjerner det - og det forklarer også hvorfor du skal have "ParentApplication: TApplication; ParentForm: TForm" med i din DLL fil definiton...
Jep, billederne ligger nemlig "fast", og er kompileret med dll-filen (TImage's)..
Din metode ser ud til at fungere som jeg håbede (med en slags streng-konvertering undervejs.. :) Jeg sidder og bøvler lidt rundt i det, og jeg er ude i noget Access Violation at 0x00000000.. når jeg fra EXE filen forsøger at kalde GetBitmap funktionen. her er min kode... - har nok fået spaddet det i stykker :)
DLL PROJEKTET: ... uses ... dllform in 'dllform.pas' {dllform1}; ... function GetBitmap(ParentApplication: TApplication; ParentForm: TForm; var StringList : TStringList;FilePath:shortstring): integer; stdcall;export; begin //burde der ikke stå et eller andet her..? end; exports GetBitmap;
DLL-FORMEN: public StringList : TstringList; ... procedure Tdllform1.FormCreate(Sender: TObject); begin StringList:=TStringlist.Create; StringList.InsertObject(1,'test',TObject(i1.Picture.Bitmap)); end;
EXE-FORMEN: function GetBitmap(ParentApplication: TApplication; ParentForm: TForm; var StringList : TStringList;FilePath:shortstring): integer; external'data/test.dll';
implementation
procedure TForm1.KnapClick(Sender: TObject); var StringList:TStringList; begin StringList := TStringlist.Create; //mangler sikkert noget her GetBitmap(application,nil,StringList,ExtractFilePath(Application.ExeName));//her går den i kage Image1.Picture.Bitmap := TBitmap(StringList.objects[1]); end;
thanks mester! nu kommer den igennem GetBitmap funktionen uden problemer, men den laver en Access Violation at address 005F392B in module... Read of address 5C6B6668.. når jeg kalder:
det er et eller andet med at bitmap billedet enten ikke er loadet ordentlig eller ikke er blevet overfoert fra DLL til EXE
proev lige at send dit projekt til mig paa mail friis_@esenet.dk - fjern underskaar i mail adresssen (underskaar skrevet for at undgaa Spam...), saa kigger jeg paa det...
HUSK "stdcall;" når du kalder en dll-fil - det har du glemt i din exe-fil...
husk også at eksportere funktionen - det mangler i DLL filen. Dvs.
exports GetBitmap;
Ret funktionen GetBitmap til:
Procedure GetBitmap(ParentApplication: TApplication; ParentForm: TForm; var StringList : TStringList); stdcall;export; begin Application:=ParentApplication; stscr2:=Tstscr2.Create(ParentForm); StringList := stscr2.StringList; end;
Da du ikke bruger FilePath til noget kan du lige så godt slette den. Du bruger heller ikke funktionens "result" til noget, så ud med den...
Jeg kan se at du bruger en anden delphi version end mig, så muligvis der er problemer med "Formstyle: fsStayOnTop", "Bordestyle:bsNone" samt "DefaultMonitor:dmActiveForm" - men hvis ovenstående virker så behøver du jo ikke ændre på tingene...
en sidste ting... husk at sikre dig at det er den seneste kompileret dll fil du bruger og ikke en gammel dll fil du har liggende som exe filen henviser til... du har mange forskellige DLL filer liggende i den rar fil du sendte...
JA! så virker det - total sejt :) Havde først prøvet med exports GetBitmap; men forsøgte at deaktivere den med "//".. Tror det var det med stdcall som fik det til at virke. der kan man bare se. Jeg bruger Delphi 6, og umiddelbart kører det, men sjovt nok opstår der en access violation når jeg senere lukker programmet. mystisk :) men nu kan programmet det, det skal. tusind tak, mbs.
hmmm... har du rette function inde i exe filen til procedure og fjernet det der filepath deklaration? - og også rettet dll definitonen inde i exe filen??
hvis det stadig driller, så send mig projektet en gang til - dog helst kun med een DLL fil... det andet er lidt forvirrende...
så har jeg sendt pr mail igen, efter at have prøvet med procedure osv.. Denne gang med een dll-fil, selvom de gerne skulle være identiske i første rar fil :) Hvis vi efterhånden er ude i noget med flere points, siger du bare til.
jeg har omdøbt startscreen.dll til dllfil.dll og så flyttet den til den anden mappe. Men har du ikke fået en fejl lidt efter man lukker programmet. noget med too many concequtive exceptions.. Programmet virker også fint her med dll-filen. Først når programmet lukkes melder den fejl.. Men det er nok noget jeg kan prøve mig frem og tilbage med, for at få væk, håber jeg :)
Altså... jeg fik ingen fejl - heller ikke efter at programmet blev lukket - programmet var stabilt...
Derimod tror jeg det er farligt at omdøbe DLL-filen som du gør - prøv at lade være med at omdøbe filen og bare behold det samme navn - alstå "startscreen.dll" og prøv så og se om det ikke virker....
Prøv evt. at fejl checke ved at vælge Project|Options|Linker og vælg herinde "include TD32..." samt "Include remote..." - gør det samme med exe filen... det gør at du kan debugge dll filen - HUSK HUSK at fjern det igen når du er færdig da det gør dll filen ca. dobbelt så stor - hvis ikke mere...
Desuden - tjek Run|Parameters|Host Application - er det korrekt det der står der? - det kan jeg nemlig ikke svarer på...
det giver samme resultat her. for sidste gang.. hehe... har jeg sendt mit projekt via mail. denne gang har jeg ændret exe-koden til, at den skal tilslutte sig den ny-kompilerede dllsource\startscreen.dll istedet for den omdøbte dllfil.dll.. Prøv at starte med blot at køre project1.exe. Hvis den ikke melder fejl, synes jeg det er total mystisk :)
Hvis du gaar op i Run|Parameters|Host Application og sletter det der staar der (altsaa ved DLL projektet) - eller endnu bedre flytter dit projekt saa den sti der staar der bliver simplificeret... saa tror jeg du kan faa det til at koere...
Det er det ENESTE jeg aendrer - og saa koerer det !! Hvis jeg ikke aendre det, saa crasher programmet som du naevner...
nope. har ellers forsøgt at flytte det hele ud i roden af mit drev, samt slette og ændre "parameters" mm, men jeg bliver ved met at møde "to many concequtive exceptions" lidt efter programmet lukkes. Også selvom intet er defineret under parametre... det er flad. Har også prøvet at bytte rundt på mapperne med projektet og indstille parametre derefter, men det vil bare ikke køre uden at gå ned :) prøv eventuelt at tilbage-mail den version, som du har fået til at køre, for at se om det også kører på min maskine. Bare en lidt "dummy" måde at få hjælp på, jeg ved det godt :)=
ok - der gaar lige tre kvater - sender det til dig kl. ca. 15.30...
I mellemtiden kan du proeve at laegge en billedfil mere ind i TstringList'en - indimellem kan det godt hjaelpe... Men du skal bare ligge den ind - du skal ikke kalde billedfilen i exe filen...
har lige lavet et helt nyt "dll-wizard" projekt (project1.dll) og ændret exe-source til at benytte denne. I dette nye projekt at jeg oprettet to billeder, som du beskriver. Får stadig samme fejl, så det må næsten være noget i exe-projektet, som forårsager fejlen?
vil bare lige meddele, at programmet virker fint, når det kompileres med Delphi 5, som jeg netop har installeret.. åbenbart problemer med delphi6 og dll-filer.. mbs
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.