Avatar billede hermandsen Juniormester
22. april 2006 - 19:47 Der er 10 kommentarer og
2 løsninger

Messages på tværs af exe- og dll-filer, samt hook på Winamp

Hej Eksperter

Jeg er gået i gang med et større projekt hvor jeg bl.a. skal kunne hente filnavne ud fra en aktiv playliste i Winamp.

Jeg har haft gang i Winamp's SDK http://www.winamp.com/nsdn/winamp/sdk/ (Delphi oversættelse på http://home.no.net/nxs/winamp.wiki ), og det fungerer fremragende.

Desværre understøtter Winamp's SDK ikke at kunne hente playlist-filnavne fra eksterne applikationer. Derfor lavede jeg et Winamp-plugin som kunne hente disse, men hvordan får jeg den nu til at sende filnavnene videre til mit program, eller får mit program til at hente filnavnet gennem min Winamp-dll?

Ekstra spørgsmål:
Kan nogen gennemgå opsætningen af en hook, da jeg godt kunne tænke mig at holde øje med hvornår Winamp skifter til næste track?

//hermandsen
Avatar billede tuxic Nybegynder
22. april 2006 - 20:52 #1
Der er flere måder. En named pipe fx. Eller at bruge et FileHandle (enten via en fysisk fil i filsystemet eller via en memorymapped fil).
Avatar billede hermandsen Juniormester
22. april 2006 - 22:11 #2
>>tuxic
Er det noget du kan forklare nærmere om?
Avatar billede hermandsen Juniormester
23. april 2006 - 07:12 #4
Jeg er ikke sikker på om de to metoder er så relevante for mit projekt. Tror desværre jeg skal gøre brug af Winamp's API (måske har jeg misforstået noget ?).

Jeg har dog fundet en metode til at sende strenge fra mit plugin, til hovedprogrammet:
http://delphi.about.com/od/windowsshellapi/a/wm_copydata.htm
Dermed er første problem løst, men jeg mangler stadig at finde ud af hvordan jeg holder øje med track-skifte i Winamp.
Avatar billede tuxic Nybegynder
23. april 2006 - 10:08 #5
Jeg kan også have misforstået det. Jeg troede du ville sende beskeder fra Winamp (loaded  dll eller lignende som du selv har skrevet) til en anden process/applikation (som du også selv har skrevet). Til det formål burde named pipes virke fint.
Avatar billede hermandsen Juniormester
23. april 2006 - 21:15 #6
Det er selvfølgelig rigtigt.

Mit største problem lige nu, er at finde ud af hvordan jeg henter events ud af Winamp... (?)
Avatar billede tuxic Nybegynder
23. april 2006 - 21:29 #7
Kender jo ikke lige så meget til WinAmp plugins (desværre det virker spændende nok; ah men man jo har jo ikke uendeligt meget tid).

Kan http://forums.winamp.com/showthread.php?s=0c4c7fb117d6776f13d7dd9532c6e04b&threadid=243284
bruges?
Avatar billede hermandsen Juniormester
23. april 2006 - 22:01 #8
Ja, det er i hvert fald hen i den rigtige retning...

Jeg har fundet ud af jeg skal bruge IPC_CB_MISC og IPC_CB_MISC_STATUS for at få at vide at status har ændret sig, men hvordan er det nu lige man laver det som callback i Delphi.

For neden har jeg noget C-kode der skulle være egnet til funktionen.
Hvis bare du kan give mig metode-hovedet (som den skal stå under interface), samt opsætningen der skal til for at Winamp bruger callback'en, så kan jeg selv klare resten! :)
Så vidt jeg husker er det noget med GetWindowLong, SetWindowLong og CallWindowProc. Noget du kan hjælpe med?

LRESULT CALLBACK MyWinampWnd(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp) {
    if(config_enabled = 1) {
        if(lp == IPC_CB_MISC && wp == IPC_CB_MISC_STATUS) {
            if(SendMessage(hwnd, WM_WA_IPC, 0, IPC_ISPLAYING) == 1 && !SendMessage(hwnd, WM_WA_IPC, 0, IPC_GETOUTPUTTIME)) {
                char* file = (char*)SendMessage(hwnd, WM_WA_IPC, SendMessage(hwnd, WM_WA_IPC, 0, IPC_GETLISTPOS), IPC_GETPLAYLISTTITLE);
                // only output if a valid file was found

                if(file) {
                    MessageBox(hwnd, file, "file", 0);
                    MessageBox(hwnd, oldfile, "oldfile", 0);
                    if (strcpy(file, &oldfile) != 0) {
                        oldfile = (char*)SendMessage(hwnd, WM_WA_IPC, SendMessage(hwnd, WM_WA_IPC, 0, IPC_GETLISTPOS), IPC_GET_PREVIOUS_PLITEM);

                        MessageBox(hwnd,"File doesnt equal oldfile","file",0);
                    }
                // or do something else that you need to do
                }
            }
        }
    }
}
Avatar billede hermandsen Juniormester
23. april 2006 - 22:27 #9
Weeeeeeee!!!!!
Jeg har noget der virker!!! :)

var
  Plugin: WinampGeneralPurposePlugin = (
    Version: $10;
    Description: 'Testing';
    Init: Init;
    Config: Config;
    Quit: Quit;
    hwndParent: 0;
    hDllInstance: 0;
  );
  WinampProc: Pointer;
  WinAMP_WND: HWND;

function Init: Integer;
begin
  Plugin.Description := App_Name + Version;

  WinAMP_WND := plugin.hwndParent;

  WinampProc := Pointer(SetWindowLong(WinAMP_WND, GWL_WNDPROC, Integer(@HookWinampWnd)));

  Result := 0;
end;

function HookWinampWnd(Handle: HWND; Msg: Integer;
  wParam, lParam: Longint): LRESULT;
var
  Status: Integer;
  S: String;
  if (lParam = IPC_CB_MISC) and (wParam = IPC_CB_MISC_STATUS) then
  begin
    Status := SendMessage(WinAMP_WND, WM_WA_IPC, 0, IPC_ISPLAYING);
    case Status of
      0: S := 'Stopped';
      1: S := 'Playing';
      3: S := 'Paused';
    else
      S := 'Unknown';
    end;
    MessageBox(WinAMP_WND, PChar(S), 'caption', MB_ICONINFORMATION + MB_OK);
  end;

  Result := CallWindowProc(Pointer(WinampProc), Handle, Msg, wParam, lParam);
end;

Godt nok får jeg vist min MessageBox to gange, men det vil jeg så rode lidt videre med... :)

Smid lige et svar hvis du vil have en del i pointene.
Avatar billede tuxic Nybegynder
24. april 2006 - 08:52 #10
Najs at du fik det til at virke!
Avatar billede hermandsen Juniormester
24. april 2006 - 10:07 #11
Du får lidt for besværet, da jeg selv lavede løsningen. Håber det er fint! :)
Avatar billede tuxic Nybegynder
24. april 2006 - 10:14 #12
Det er helt fint! 30 pt står fint mål med min indsats. 30/200 virker også som den helt rigtige vægt af min indsats ifht din.
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester