Winamp/mIRC plugin i C++

Tags:    c++
Skrevet af Bruger #347 @ 26.10.2002
Winamp 2.x vs. mIRC DLL

Denne artikel blev til over mine egne problemer med at lave en .dll fil uden brug af MSVC. Jeg bruger selv freeware programmet Dev-C++ til at kode i. Dev-C++ opfører sig lidt anderledes end MSVC når man laver .dll filer. MSVC finder selv frem til, ud fra .def filen, hvad der skal eksporteres, mens man i Dev-C++ skal angive ved funktionen at den skal eksporteres. Sidst i artiklen kan du se hvordan du trin for trin laver en dll med Dev-C++

DLL filen når den bliver færdig vil ikke være mere en 27 liniers kode så selv nybegyndere ikke bliver håbløst fortabte. Jeg tror selv at alle vil kunne følge med i denne artikel. Hvis du skulle have problemer er du velkommen til at spørge mig på #Udvikleren.dk. Du kan også prøve at sende en mail men der kan ofte gå uger før jeg besvarer e-mails :)


mIRC

Det første vi skal kende er den metode hvorved mIRC modtager oplysninger. Vi slår funktionen op i mIRC hjælp filen. (du kan taste "/help $dll" i mIRC for at komme til DLL siden.)
int __stdcall procname(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
procname er vores funktion (den vi senere kalder med $dll()). data er den værdi vi får tilbage.

Return værdier
0 mIRC skal /halt.
1 mIRC skal fortsætte kørslen.
2 betyder at data er blevet fyldt med en kommando mIRC skal køre, og parms er fyldt med parametrene, hvis der er nogen, til kommandoen.
3 betyder at data er fyldt med resultatet som $dll() skal returnere.

Og en kombination af de to :)
int __stdcall vistekst(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
{
 // Her fylder vi "data" med vores tekst
 strcpy(data, "tekst");
 // DLL filen returner en integer værdi der fortæller hvad mIRC skal gøre.
 return 3;
}
Når vi skal køre vores DLL fil i mIRC skal vi bruge $dll(filename, procname, data).

Winamp

Nu ved vi nok om mIRC til at lave en DLL fil. Nu skal vi finde ud af hvordan vi får oplysninger ud af Winamp. På Winamps udvikler side finder vi alt hvad vi skal bruge. Der er endda allerede lavet et stump kode der kan vise hvilket nummer der spiller. Den kode laver vi vores egen version af.

Når vi skal fortælle vores DLL hvilket program den skal bruge skriver vi:
HWND hwndWinamp = FindWindow("Winamp v1.x", NULL);
Huske at føje til dine include filer. Da vi her arbejder med Win32 API. Funktionen søger efter et program med class'en "Winamp v1.x". Alle winamp versioner ældre end v3 tilhører den class.

Når vi skal hive titlen ud af Winamp gør vi det også med en Win32 API funktion.
int GetWindowText(HWND hWnd, LPTSTR lpString, int nMaxCount);
hWnd er window handleren (hwndWinamp). lpString er den variabel vi lægger titlen i. nMaxCount er det antal tegn der højest skal kopieres.

En sidste funktion til Winamp vi har brug for er:
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
hWnd er window handleren (hwndWinamp). Msg beskriver hvilken type besked der bliver sendt. wParam er en dataparameter. lParam er også en dataparameter.

Herunder er koden til DLL filen jeg prøver at beskrive det meste med comments men resten bliver forklaret bagefter. Princippet i programmet er tage titlen og fjerne " - winamp".
#include 
#include 

// "extern "C" __declspec(dllexport)" er nødvendig med min compiler, men fx. MSVC behøver den ikke
extern "C" __declspec(dllexport) int __stdcall winamp(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
{
 HWND hwndWinamp = FindWindow("Winamp v1.x", NULL);

 // Du kan se mere på winamps udvikler side
 int ret = SendMessage(hwndWinamp, WM_USER, 0, 105);

 // Ovenstående returner tiden i millisekunder eller -1 hvis winamp ikke spiller.
 if(ret != -1)
 {
  char WinampTitle[2048];

  GetWindowText(hwndWinamp, WinampTitle, sizeof(WinampTitle));

  // Længden af titlen uden " - winamp"
  int TitleLenght = strlen(WinampTitle)-9;

  // Løkken løber titlen igennem bagfra og sletter indtil længden passer
  for(int i = strlen(WinampTitle); i >= TitleLenght; i--)
  {
   WinampTitle[i] = '\\0';
  }
  strcpy(data, WinampTitle);
  } else {
  strcpy(data, "Winamp Not Playing");
 }
 return 3;
}
For at fortælle compileren hvad der skal eksporteres skal vi lave en .def fil. Lav en tom fil med filtypenavnet .def. Indsæt følgende tekst i filen.
LIBRARY Winamp_DLL	
DESCRIPTION 'Winamp_DLL.dll'
EXPORTS
winamp

Dev-C++ Instruktioner

1. Opret et nyt "Empty Project" og kald det fx. Winamp_DLL.
2. Opret en ny "Source File" (ctrl + n). Og skriv koden.
3. Gå i Project Options (alt + a).
4. Vælg "Win32 DLL" som type.
5. Slet alt i Compiler og Linker Options
6. I Linker Options skriv: --def "navnet på din .def fil"
7. Nu kan du compile din DLL fil (ctrl + F9).

Bruge vores DLL

Hvis du kopierer din nye DLL fil ind i mIRC mappen kan du skrive:
//echo $dll("dllfilnavn",winamp,_)
Den sidste parameter skal vi ikke bruge, derfor skriver vi "_" (underscore).

Udbygning af DLL filen

Du kan nu selv forsøge at få din dll fil til også at vise hvor meget der er spillet af nummeret. Den oplysning lægger allerede i variablen ret (i millisekunder). Hvis du vil have den fulde længde på nummeret (i sekunder) skriver du:
 int TrackLenght = SendMessage(hwndWinamp, WM_USER, 1, 105);
Du kan finde mange flere funktioner på Winamps udvikler side.

Bemærkninger

Microsoft Visual C++
Jeg bruger ikke selv MSVC. Men jeg ved at man kan undlade "extern "C" __declspec(dllexport)". Og jeg mener at man skal sørge for at kalde sin .def fil det samme som sit projekt. Jeg vil meget gerne have en kommentar fra nogen der bruger MSVC.

Mere..
Jeg planlægger at udgive en artikel om Winamp Plugins hvor jeg vil demonstrere hvordan man kan få mIRC til at samarbejde med Winamp.



Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (4)

User
Bruger #2857 @ 12.03.03 22:13
skodting
User
Bruger #479 @ 18.04.03 23:37
det er da nice nok
User
Bruger #5658 @ 06.06.04 12:52
Udemærket.. men "lidt" svær at få til at virke.
User
Bruger #3308 @ 20.06.04 23:26
Hmm god artikel.... men har ikke lige faaet det til at virke helt inu... men det kommer nok :D

Men du includer 2 filer.... hvad skal man include udover #include <windows.h> ?????
Du skal være logget ind for at skrive en kommentar.