Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need some DLL explanations :)

Status
Not open for further replies.

Ante0

Programmer
Apr 19, 2007
98
SE
Hi, I made a plugin for a mp3 player that I made.
the dll code looks like this:

Code:
library CallMSNDLL;

uses
  SysUtils,
  Classes,
  Windows,
  Messages,
  uFMOD;

{$R *.res}

function CurrentPlay(ARTIST:string) : string; Export;
var
 handleMSN:THandle;
 structCopy:TCopyDataStruct;
 stringBuffer:array [0..127] of WideChar;
begin
 FillChar(stringBuffer,SizeOf(stringBuffer),#0);
 StringToWideChar('\0Music\0'+'1'+'\0'+'{0}  **AntePlug1.0**'+'\0'+ARTIST+'\0'+'WMContentID'+#0,@stringBuffer[0],128);

 FillChar(structCopy,SizeOf(TCopyDataStruct),#0);
 with structCopy do
 begin
   cbData:=SizeOf(stringBuffer);
   dwData:=$547;
   lpData:=@stringBuffer[0];
 end;

 handleMSN:=FindWindowEx(0,0,'MsnMsgrUIManager',nil);
 while handleMSN <> 0 do
 begin
   SendMessage(handleMSN,WM_COPYDATA,0,Integer(@structCopy));

   handleMSN:=FindWindowEx(0,handleMSN,'MsnMsgrUIManager',nil);
 end;
end;

Exports CurrentPlay;

begin
end.

What it does is simply change the Personal message in MSN to what song I'm listening to in my mp3player.

This is how it calls the dll from inside the mp3player

Code:
procedure DllMessage; external 'CallMsnDLL.dll'

and in for example the play button code I have

Code:
CurrentPlay(ExtractFileName(MediaPlayer1.FileName));

Now, what I want to do to call the DLL from a button instead of including it when the program starts.
So I could remove the .dll without the mp3player complaining about it when I start the program.
Like, instead of using procedure DllMessage; external 'CallMsnDLL.dll'
it should search for the dll and if it doesnt find it, it wont use CurrentPlay(ExtractFileName(MediaPlayer1.FileName)); in the play button...

Anyone has any ideas or snippets about this?

Please write here if you need any more information :)
 
Look up dynamically loading DLLs. If you find the DLL then you:
1) allow the user to access that function
2) assign the address of the DLL's function to your procedure/function. Then you call the function like normal.
 
Ante, have a look at Loadlibrary and GetProcAddress functions.

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Hello, and thanks.
I tried something with LoadLibrary and GetProcAddress.
But each time I compliled and ran I got a error about ExplicitTop property not existing.
I don't have the code here. I'm at work right now, but I googled GetProcAddress and the code seemed to work.
See if I remember it by heart...
In type I added

TCurrentPlay = function (ARTIST: string): String;

Code:
var
 LibHandle  : THandle;
 CurrentPlay: TCurrentPlay;
begin
 LibHandle := LoadLibrary('MSNPLUG1.0.DLL');
 try
  if LibHandle <> 0 then
  @CurrentPlay := GetProcAddress(LibHandle, 'CurrentPlay');
  if not (@CurrentPlay = nil) then
   CurrentPlay('Test');
 finally
  FreeLibrary(LibHandle); 
end;
end;

Now I start to wonder... Maybe I have to put a handle in TCurrentPlay in type..
Well I can't see anything else wrong with it.
 
Ante,

GetProcaddress gives you a pointer to a function/procedure NOT an object.

so :

Code:
var
 LibHandle  : THandle;
 CurrentPlay: function CurrentPlay(ARTIST:string) : string;// mimic exact syntax here
begin
 LibHandle := LoadLibrary('MSNPLUG1.0.DLL');
 try
  if LibHandle <> 0 then
  @CurrentPlay := GetProcAddress(LibHandle, 'CurrentPlay');
  if not (@CurrentPlay = nil) then
   CurrentPlay('Test');
 finally
  FreeLibrary(LibHandle); 
end;

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Oh, I see :)
I will try this once I get home.
I will also try to find more info about DLLs...
Anyone know a good place to start looking? :)
 
Wow, it works now.
Something strange though, the ExplicitTop error seems to be on my Playlist form, not the main form.
and when I remove the DLL code from my project it doesn't complain, only when I have it in.
What I had to do was remove Listbox1.Align := alClient and put in alNone instead. then it works like a charm.
Strange it is, anyone care to look deeper into this? :)
I will to, thank you all!! :D
 
One thing I forgot to say:

you are passing strings between your app and the dll, one the restrictions that apply is that you only can pass shortstrings (255 chars). is this the case?

modify:
function CurrentPlay(ARTIST:Shortstring) : Shortstring; Export;

if you need more than 255 chars, you'll need to use Pchars.

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
I only use ExtractFilename(Mediaplayer1.filename);
So it shouldn't use more than 255 chars.
Or did you mean I have to use ShortString?

I got it to work after some modifying.
Like instead of

var
LibHandle : THandle;
CurrentPlay: function CurrentPlay(ARTIST:string) : string;// mimic exact syntax here

I had to put

CurrentPlay: function (ARTIST:string) : string;

Or else it complained about the function not having any result :)
One thing though, it doesnt seem to care about

Code:
if LibHandle <> 0 then

If I remove the dll from my app dir I get an access error when I press on my play button.
Though, it should skip the rest of the code if the dll doesn't exist, but it doesn't seem to.
LibHandle is 0 when nothing is loaded, right?

And I dont want to Raise any error messages, because I want it to work without the dll in the app dir.

Other than that it works like a charm :)

thanks for your help, again ;)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top