PDA

View Full Version : Adding items to po-up menus


Wahoo747
30th November 2000, 00:00
Ok, i've written a plug-in (kinda) for winamp. Nothing big, just a shuffle. Or, a "smart shuffle" as it were. Right now its just a tiny exe that runs windowless. You execute it, it pulls the current winamp playlist, reorders it, and re-loads it. It would be cool if i could add this "Smart Shuffle" to the right-click menu for the playlist. I've seen other plugins do this, and i was wondering if someone could help me with this on last bit. I'm capeable of converting it to a DLL on my own whenever i get this figured out i think.

Wahoo

Wahoo747
30th November 2000, 00:01
Umm, i'm developing in VB, by the way. i know, it sucks, whatever.

puzzled
5th December 2000, 09:08
Well, doing such in VB is easier said than done. Here's pretty much a checklist of what needs to happen:

* API code creates new menu entries
* Subclass newly added menu entries for user events
* React to events

The hardest of them all is the second. This requires you to subclass outside of your applications initial process, a task which VB cannot do by itself. Languages such as C and Pascal however can. Last i checked the only known functional method for this was to use an addon library written specially for VB known as SpyWorks. Spyworks is a great tool but is expensive. Check www.desaware.com (http://www.desaware.com) for more info. There are currently no free libraries that this can be acomplished with in VB that i know of. However, you are free to look.

To actually add the menu, you can use the 'AppendMenu' API call with some other calls to successfully add your menu to the winamp popup menu. After adding the menu and subclassing it, responding to the events should be a snap.

I hope that helped somewhat.

-puzzled

reaction
14th December 2000, 23:59
I'm also attempting to create a menu in winamp using vb. I was just wondering what other API functions may be needed. I believe I already know how to

Staro
19th December 2000, 18:04
If you want to add some Items to the popup menu, your program has to run as an plugin-dll (simply because you need to be in the same thread).

Look at the "Win32 Progammer's Reference" (win32.hlp)
for more details.

i don't use VB but Delphi. I think it would be similar:

To create a DLL, see this page:
http://www.stnd.de/programming/gentut/gentut.html
(it's an example of an generalplugin)

If you are able to run your plugin in winamp, you have to watch all windowsmessages. To do this you will need to manipulate the event-handler of winamp (don't worry, it's easier than it sounds).

First, get the handle of Winamp:
hwndWinamp := FindWindow('Winamp v1.x',nil);

Then you MUST save (and never, NEVER delete this) the old address of the event-handler (at startup):
WinampProc := GetWindowLong(hwndWinamp, GWL_WNDPROC);
and now you can set your own event-handler, that will winamp use (simply tell him the address):
setWindowLong(hwndWinamp, GWL_WNDPROC, Integer(@myWinampProc));

You see, winamp will now use my own function "myWinampProc".
Of course you must write this function as follows (use the EXACT parameterlist):

function TMainForm.myWinampProc(Handle:HWND; Msg:integer; wParam, lParam:LongInt): LongInt; StdCall;
begin
// do something before Winamp gets the messages
Result := CallWindowProc(Pointer(WinampProc), hwndWinamp, Msg, wParam, lParam);
// do something after Winamp has got the messages
end;

You have successfully route the eventhandler trough your program!
In this function, you can test all incoming Messages, if your programm needs something to do. (i.e. you need to react to the menu commands, but this will explained later).


------
Now we are prepared to add an item to the popup menu:
in this function you have to wait for the windows message WM_INITMENUPOPUP, so simply create a case-structure:

case Msg of
begin
WM_INITMENUPOPUP:
// here you will create a new item
end;

To create a new item, you will use the windows function insertMenuItem, which needs a handle to the Menu, a position number, a flag and the information about the item.
First, we have to create the information about this new item (the structure MENUITEMINFO will help you).

Declare a variable
mii: MENUITEMINFO;
and fill it with information:
We will need to set the type, state, ID and the caption, so we will fill mii :

mii.fMask := MIIM_TYPE or MIIM_STATE or MIIM_ID ;
mii.fType := MFT_STRING;
mii.fState := MFS_ENABLED;
mii.wID := 12345 // use some number, but remember this value
To add an string as the caption, you need to declare a variable:
MenuCaption: array[0..255] of char;
MenuCaption := 'Smart Shuffle';
mii.dwTypeData := MenuCaption;
mii.cch := Length(MenuCaption);
mii.cbSize := Length(mii);

Now you must create the item to the popupmenu:
insertMenuItem(wParam, Position, true, mii);

where wParam contains the handle of the menu (you got this as a parameter), and Position is the Position in the menu (starts with 0).

Ok, this was hard, so here is the complete source:

hwndWinamp := FindWindow('Winamp v1.x',nil);
WinampProc := GetWindowLong(hwndWinamp, GWL_WNDPROC);
setWindowLong(hwndWinamp, GWL_WNDPROC, Integer(@myWinampProc));


function TMainForm.myWinampProc(Handle:HWND; Msg:integer; wParam, lParam:LongInt): LongInt; StdCall;
begin
case Msg of
begin
WM_INITMENUPOPUP:
begin
mii.fMask := MIIM_TYPE or MIIM_STATE or MIIM_ID ;
mii.fType := MFT_STRING;
mii.fState := MFS_ENABLED;
mii.wID := 12345
MenuCaption: array[0..255] of char;
MenuCaption := 'Smart Shuffle';
mii.dwTypeData := MenuCaption;
mii.cch := Length(MenuCaption);
mii.cbSize := Length(mii);
insertMenuItem(wParam, Position, true, mii);
end;
end;

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

case Msg of
begin
WM_COMMAND:
begin
if LoWord(wParam) = 12345 then
doYourShuffleProcedureOrSomethingElse;
end;
end;
end;


That was it:
The last few lines wait till somebody clicked your new menu item...

pinterpeti
15th September 2004, 16:57
Hi! I've created a new menu item in the main window's popup menu, but I can't figure it out how to assign a shortcut to this menu item. I've searched trough the WinAMP' forums but I haven't find any help.I've done a lot of search on the internet too, without any usable piece of source code. So if anybody can help me it would be very good.By the way I'm using delphi to make a general plugin. Another thing: how can I add a new menuitem into the playlist's menu.(I know that there is an example by DrO,but it's in C and I can't translate it to Delphi code)
Thanks!

P.S.:I almost forgot one thing: how can I get the currently selected item's filename from the WinAMP playlist(not the currently playing,but the one that has the cursor on it)

[Edit --> DJ Egg]
Moved from Tech Support to Winamp Dev.
Tip: don't revive ancient threads. Start a new one, and link to the old one(s) if needs be.

Joel
15th September 2004, 20:56
Well, since we are talking about pure API, coudln't be hard the translations among languages.
See the sdk about IPC_GETPLAYLISTFILE

saivert
17th September 2004, 06:33
I think you would have to download a COM object kinda thing to develop plugins i VB. It was a plugin proxy (written in C) which loaded your VB plugin as a COM object and then you had access to Winamp through the proxy plugin.

Re: Delphi

Instead of using STND's tutorial for a General Purpose Plugin you can download my Winamp SDK for delphi which includes examples of all 6 (yes six!!) plugin types:

- General Purpose
- Visualization
- Input
- Output
- DSP
- Media Library

It will be avaiable on a separate thread I'm starting for it, soon...


- I won't buy this record... it is scratched.
- Huh!? (Pointing out something in the pocket parlor).
- Ohh.. I won't buy this tobacconist.. it is scratched.