Old 31st August 2010, 18:58   #1
akayrak
Junior Member
 
Join Date: Aug 2010
Posts: 2
Winamp Embedded Window Plug-in Example

Hi guys,
I really did not understand how to create a plugin which is an external window from winamp but works and opens with winamp. Can anyone explain or point an article to me?
Thanks in advance

[edit - DrO 15/09/2010]
See http://nunzioweb.com/daz/gen_embedwnd/ for example plug-in source and download
akayrak is offline   Reply With Quote
Old 1st September 2010, 07:57   #2
siam6606
Junior Member
 
Join Date: May 2010
Posts: 42
The best of the best example is the DrO's gen_wa2dlg...
But I don't know the URL to download it...
siam6606 is offline   Reply With Quote
Old 1st September 2010, 08:21   #3
DrO
 
Join Date: Sep 2003
Posts: 27,880
hmm, i'm not sure i've got a copy of that project myself though i know it's out of date and needs to be refreshed (especially to show how to properly insert items into the Winamp menus). will try to sort something out over the next few days (is a good thing i'm doing some updates of my site so i can allocate the time to it).

here's the old links... http://forums.winamp.com/showthread....hreadid=154650 (gen_wa2dlg) and http://forums.winamp.com/showthread.php?t=178052 (gen_craig) but they're poorly documented and really i wouldn't suggest using them as is since they're not fully compatible with newer client releases (breaks unicode taskbar text and the menu issue if in there is unreliable).

plus we're 6-7 years on from when i first did them so i should be able to make a better example now anyway

-daz
DrO is offline   Reply With Quote
Old 3rd September 2010, 19:58   #4
akayrak
Junior Member
 
Join Date: Aug 2010
Posts: 2
Anything else? Cause these are really old. Is there any new document or sample plug-in?
akayrak is offline   Reply With Quote
Old 3rd September 2010, 20:56   #5
DrO
 
Join Date: Sep 2003
Posts: 27,880
you could work through a recent copy of wa_ipc,h and manually find all of the relevant apis if you want to but otherwise there's no other examples that i'm aware off at the moment. alas documentation of most thnigs to do with Winamp has generally been poor as you're now finding.

-daz
DrO is offline   Reply With Quote
Old 14th September 2010, 19:39   #6
DrO
 
Join Date: Sep 2003
Posts: 27,880
i've not forgotten about this, just a bit pressed on time (as i've 25+ of my plug-ins to still update due to other reasons) and need to work out how to resolve a quirk with going from classic skin -> modern skin -> closing winamp -> restarting winamp -> classic skin (causes the height and width to use the modern skin width instead of the classic width) - am trying to find a decent solution without too much menu / api hooking...

[edit - 1hr later]
just fixed the size not being preserved in the above scenario from what i can tell so now just need to get the comments in the source finished off - it won't be 100% but it should be understandable for the most parts

-daz
DrO is offline   Reply With Quote
Old 15th September 2010, 14:02   #7
DrO
 
Join Date: Sep 2003
Posts: 27,880
i've now finished of v1.0 of the Winamp Embedded Window Plug-in Example which can be found at http://nunzioweb.com/daz/gen_embedwnd/

and now i've got to update some of my plug-ins as this new code is a lot better than my own older codebase, heh

-daz
DrO is offline   Reply With Quote
Old 17th September 2010, 19:49   #8
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: On the streets of Kings County, CA.
Posts: 2,930
Send a message via Skype™ to thinktink
Small bug

I found a small UI bug. I don't know if it's with the example plugin or if it's a Winamp 5.581 bug since I'm not aware of another plugin that uses the embedded window right now.

If you close the example embedded window from the close X [button] on the window itself instead of un-checking it from the context menu, when you reopen the menu, the option for the example window still shows as checked. If you click on it after the Window comes back. If you close the window from the context menu it behaves normally. It's as if the check mark of context menu for the embedded window isn't being updated to reflect the current state of the example window when you close the window outside the context menu.

It does this on both my box at work and at home both running Windows XP Home with the latest version of Winamp installed. My box at home does have modern skin support installed but I don't use it. I don't know if that's relevant or not but I mention it just in case it is.
thinktink is offline   Reply With Quote
Old 17th September 2010, 22:19   #9
DrO
 
Join Date: Sep 2003
Posts: 27,880
Quote:
Originally Posted by thinktink View Post
It's as if the check mark of context menu for the embedded window isn't being updated to reflect the current state of the example window when you close the window outside the context menu.
oops, you're correct. will get that fixed at the start of next week - i should have caught that but i tended to do the testing via the menu / shortcut as i was coding it over vnc (will teach me to do that, heh). thanks for finding the bug

as for other windows using the embedded window, the media library, the jtfe / queue manager window are about it (and AVS + Milkdrop) though none of them use the example code (though it's based more off the gen_ml handling then my over-coded jtfe version).

-daz
DrO is offline   Reply With Quote
Old 19th September 2010, 14:09   #10
DrO
 
Join Date: Sep 2003
Posts: 27,880
just released v1.1 which should fix the update issue when clicking the close button (1 line fix to get the update function called *shrugs* ).

-daz
DrO is offline   Reply With Quote
Old 9th February 2011, 22:39   #11
Danya Lukin
Junior Member
 
Join Date: Jan 2011
Posts: 9
Hey Daz, what's the post compilation command that runs lng_generator.exe?
What is that executable anyways, does it just copy the dll, or does it have other important function?

And when i compile the project (windows 7, visual stoduio 2010) it doesnt give out any errors, but the plugin is not recognized.
Danya Lukin is offline   Reply With Quote
Old 10th February 2011, 05:03   #12
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: On the streets of Kings County, CA.
Posts: 2,930
Send a message via Skype™ to thinktink
Quote:
Originally Posted by Danya Lukin View Post
And when i compile the project (windows 7, visual stoduio 2010) it doesnt give out any errors, but the plugin is not recognized.
Double check to make sure that your plugin's primary export function is not name mangled and is using the __cdecl calling convention.
thinktink is offline   Reply With Quote
Old 10th February 2011, 08:07   #13
DrO
 
Join Date: Sep 2003
Posts: 27,880
Quote:
Originally Posted by Danya Lukin View Post
what's the post compilation command that runs lng_generator.exe?
What is that executable anyways, does it just copy the dll, or does it have other important function?
it generates a language file from the plug-in which can then be passed onto language pack authors so they can translate aspects of the plug-in as needed - basicially any new plug-in created should be doing this as seeing as localisation support has been in Winamp since 2007 (when 5.5 was released), there's no real excuse to not just target that as a minimum Winamp version especially as we're almost 4years since that release.

the command is in the post-build section of the project.

-daz
DrO is offline   Reply With Quote
Old 13th February 2011, 21:08   #14
Danya Lukin
Junior Member
 
Join Date: Jan 2011
Posts: 9
thanks alot thinkthink!!
i guess Visual studio converted the convetions to sdtcall and i didnt know i had to change that..
its working now!

But there is a different problem - the dll is recognized, but when you click on the plugin in the gen plugins list, it only opens the config dialog, not the window, while the dll that came with the source code worked fine and the window opened...
what could be wrong?
Danya Lukin is offline   Reply With Quote
Old 13th February 2011, 22:05   #15
DrO
 
Join Date: Sep 2003
Posts: 27,880
the config option doesn't open the embedded window. you need to check it's not set to hidden in the main right-click menu for the option to open the window.

also, i'm not sure why VS would have converted the function calling convention as __cdecl is the default (at least with all of the versions i've used upto VS2008).

-daz
DrO is offline   Reply With Quote
Old 13th February 2011, 23:25   #16
Danya Lukin
Junior Member
 
Join Date: Jan 2011
Posts: 9
Yess, the window works now!
Sorry for bothering so much, but i have another problem. I converted the gen_plugin to a dsp plugin by changing struct types and the function (keeping everything from the original gen plugin), and it all compiled correctly, but if i go to the dps plugins list in the preferences of winamp and either try to close the plugin or switch to a different one, or uninstall, it just makes winamp not respond. I guess i must have some quit procedure taht is special about the DSP plugin as opposed to a GEN?

Im attaching the file that i actually modified (txt is actually .cpp)
And in the header embedwnd.h i just changed one line:
from: extern winampGeneralPurposePlugin plugin;
to: extern winampDSPModule plugin;

Whats worse, im looking at the code of the program and i dont see where exactly the window is ACTUALLY created. Where is the createwindowEx function? and the PIXELFORMATDESCRIPTOR? how do I use the window, specifically setting it up for opengl?
could you explain whats going on?

thanks a million!

Danya
Attached Files
File Type: txt gen_embedwnd.txt (16.6 KB, 630 views)
Danya Lukin is offline   Reply With Quote
Old 14th February 2011, 06:27   #17
DrO
 
Join Date: Sep 2003
Posts: 27,880
you cannot use this example for a dsp plug-in, not without removing most of what is adds as it heavily relies upon subclassing Winamp which DSP's do not lend themselves to work with (as they are able to be dynamically unloaded and so breaks the subclass chain leading to what you're seeing).

the SendMessage(..) call to the embedwnd api in init(..) is where the window is created which is then doing the CreateWindowEx(..) inside of winamp.exe itself. as long as you have a valid HWND (as is obtained) then there shouldn't be a problem doing anything else - excluding not using this example as a DSP / VIS plug-in (or any plug-in type which allows for dynamic unloading).

-daz
DrO is offline   Reply With Quote
Old 14th February 2011, 18:42   #18
Danya Lukin
Junior Member
 
Join Date: Jan 2011
Posts: 9
Oh, i see...
I created a working window in a separate dsp plugin (based of the example dsp in the sdk) but is there a way to skin the window the same way as you did in the gen embedded window plugin?
Danya Lukin is offline   Reply With Quote
Old 14th February 2011, 19:23   #19
DrO
 
Join Date: Sep 2003
Posts: 27,880
you can do it as long as you remove all of the stuff done via subclassing which then just leaves it without the proper means to integrate into the main right-click menu and will have some issues when doing classic->modern and back again if Winamp is closed in middle of that.

the main aim of the example is as a basic for gen / ml plug-ins as they're the ones more likely to need to be in a skinned window, though the basic usage of the embedwnd api is available to all plug-ins, like how the vis plug-ins use it.

-daz
DrO is offline   Reply With Quote
Old 31st July 2012, 03:40   #20
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: On the streets of Kings County, CA.
Posts: 2,930
Send a message via Skype™ to thinktink
I am currently working on getting my embed framework to automatically emulate what the the example gen window plugin is doing as far as showing and hiding the window from the inserted menu command and accelerator trapping. So far it's going ok. However there seems to be a small snafu:
code:
...
else if(message == WM_WINDOWPOSCHANGING)
{
/*
if extra_data[EMBED_STATE_EXTRA_REPARENTING] is set, we are being reparented by the freeform lib, so we should
just ignore this message because our visibility will not change once the freeform
takeover/restoration is complete
*/
WINDOWPOS *windowPos = (WINDOWPOS*)lParam;
embedWindowState *state=(embedWindowState *)GetWindowLongPtr(embedWnd,GWLP_USERDATA);
if (state && /*Looky here-->*/ state->reparenting /*<---Looky here*/ && !GetParent(embedWnd))
{
// this will reset the position of the frame when we need it to
// usually from going classic->modern->close->start->classic
SetWindowPos(embedWnd, 0, 0, 0, width, height,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE |
SWP_NOSENDCHANGING | SWP_ASYNCWINDOWPOS);
}
}
...



However, "reparenting" is not defined as a member of "embedWindowState" inside of wa_ipc.h:
code:
...
typedef struct
{
HWND me; //hwnd of the window

#define EMBED_FLAGS_NORESIZE 0x1
// set this bit to keep window from being resizable

#define EMBED_FLAGS_NOTRANSPARENCY 0x2
// set this bit to make gen_ff turn transparency off for this window

#define EMBED_FLAGS_NOWINDOWMENU 0x4
// set this bit to prevent gen_ff from automatically adding your window to the right-click menu

#define EMBED_FLAGS_GUID 0x8
// (5.31+) call SET_EMBED_GUID(yourEmbedWindowStateStruct, GUID) to define a GUID for this window

#define SET_EMBED_GUID(windowState, windowGUID) { windowState->flags |= EMBED_FLAGS_GUID; *((GUID *)&windowState->extra_data[4])=windowGUID; }
#define GET_EMBED_GUID(windowState) (*((GUID *)&windowState->extra_data[4]))

int flags; // see above

RECT r;
void *user_ptr; // for application use
int extra_data[64]; // for internal winamp use
} embedWindowState;
...



Am I missing something? Do I have the wrong header?
thinktink is offline   Reply With Quote
Old 31st July 2012, 07:15   #21
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: On the streets of Kings County, CA.
Posts: 2,930
Send a message via Skype™ to thinktink
Nevermind, found a work-around:
code:
state->extra_data[62]
thinktink is offline   Reply With Quote
Old 31st July 2012, 10:45   #22
DrO
 
Join Date: Sep 2003
Posts: 27,880
code:
#ifdef __cplusplus
class ifc_window;
#endif

typedef struct embedWindowState embedWindowState;

#define FFC_CREATEEMBED 0 // param = (LPARAM)(ifc_window*)windowParent; return 1 to terminate creation.
#define FFC_DESTROYEMBED 1

typedef int (CALLBACK *FFCALLBACK)(embedWindowState* /*windowState*/, INT /*eventId*/, LPARAM /*param*/);

typedef struct embedWindowState
{
HWND me; //hwnd of the window

#define EMBED_FLAGS_NORESIZE 0x1
// set this bit to keep window from being resizable

#define EMBED_FLAGS_NOTRANSPARENCY 0x2
// set this bit to make gen_ff turn transparency off for this window

#define EMBED_FLAGS_NOWINDOWMENU 0x4
// set this bit to prevent gen_ff from automatically adding your window to the right-click menu

#define EMBED_FLAGS_GUID 0x8
// (5.31+) call SET_EMBED_GUID(yourEmbedWindowStateStruct, GUID) to define a GUID for this window

#define EMBED_FLAGS_FFCALLBACK 0x10
// 5.55+

#define SET_EMBED_GUID(windowState, windowGUID) { windowState->flags |= EMBED_FLAGS_GUID; *((GUID *)&windowState->extra_data[4])=windowGUID; }
#define GET_EMBED_GUID(windowState) (*((GUID *)&windowState->extra_data[4]))

int flags; // see above

RECT r;
void *user_ptr; // for application use

union
{
#pragma warning(push)
#pragma warning(disable:4201)
#pragma pack(push, 1)
struct
{
struct embedWindowState *link;
intptr_t attached;
intptr_t padding1[2]; //2-3
GUID guid; // 4-7
#ifdef _WIN64
intptr_t guidpadding;
#endif
FFCALLBACK callback;
intptr_t padding2[52]; // 9-60
intptr_t hostcount; // 61
intptr_t reparenting; // 62
#ifdef __cplusplus
ifc_window *wasabi_window;
#else
void *wasabi_window; // ifc_window *
#endif
};
#pragma warning(pop)
#pragma pack(pop)
intptr_t extra_data[64]; // for internal winamp use
};
} embedWindowState;

there's stuff in there i've no idea about (mainly the FF* stuff). though clearly no one has bothered to use the example as that should have been caught (so yay, i wasted a few more hours of my life doing that *grumble* ).

-daz
DrO is offline   Reply With Quote
Old 31st July 2012, 16:18   #23
thinktink
Forum King
 
thinktink's Avatar
 
Join Date: May 2009
Location: On the streets of Kings County, CA.
Posts: 2,930
Send a message via Skype™ to thinktink
Thanks.

And even though I may not be able to compile the example plugin directly myself, both the compiled plugin itself and the plugin's source code you have provided still has helped greatly and I believe is worth it.

btw, do you know if there's going to be an updated version of the SDK anytime soon? If not, no worries.
thinktink is offline   Reply With Quote
Old 31st July 2012, 16:22   #24
DrO
 
Join Date: Sep 2003
Posts: 27,880
there's pretty much nothing of importance on any additions to the sdk for a long time (at most is some random wasabi stuff) so there's generally not too much different between the last one and me posting the above and the other odd snippets over the last 2 years. i had started on trying to make sure everything is ok with the installer to be able to run off a new sdk but just haven't had the time to finish that off.

-daz
DrO is offline   Reply With Quote
Old 27th October 2013, 18:36   #25
mikenakis
Junior Member
 
Join Date: Oct 2013
Posts: 2
DrO, the page http://nunzioweb.com/daz/gen_embedwnd/index.html linked from page http://nunzioweb.com/daz/featured.html does not exist anymore. Using archive.org I was able to see an old version of the page, but archive.org does not have the zip file. Is there any chance of you fixing this? Thanks in advance!
mikenakis is offline   Reply With Quote
Old 27th October 2013, 18:44   #26
DrO
 
Join Date: Sep 2003
Posts: 27,880
it'll be included in the coming SDK update once i've done a code review of it and applied some fixes to it from since it was released.
DrO is offline   Reply With Quote
Reply
Go Back   Winamp & SHOUTcast Forums > Developer Center > Winamp Development

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump