Old 10th September 2014, 14:36   #1
piotreek7
Junior Member
 
Join Date: Mar 2014
Posts: 4
Winamp can't be closed with my plugin written in C++/WinApi

I have written a Winamp plugin with WinApi.

When I'm closing Winamp, GUI (both Winamp's and my plugin's windows) is disappearing... but I can still see Winamp.exe in Windows TaskManager.

After deleting gen_mood.dll (my plug-in file) from Winamp's plug-ins directory, everything is OK - I can close Winamp correctly.

Here is my minimal code. Can someone tell me what is wrong? I'm using Visual Studio 2013 and Winamp 5.666.

gen_mood.cpp:

code:
#include "stdafx.h"
#include <windows.h>
#include "gen_mood.h"

// these are callback functions/events which will be called by Winamp
int init(void); void config(void); void quit(void); void makeSetlist();
using namespace std;


// this structure contains plugin information, version, name... // GPPHDR_VER is the version of the winampGeneralPurposePlugin (GPP) structure
winampGeneralPurposePlugin plugin = {

GPPHDR_VER, // version of the plugin, defined in "gen_mood.h"
PLUGIN_NAME, // name/title of the plugin, defined in "gen_mood.h"
init, // function name which will be executed on init event
config, // function name which will be executed on config event
quit, // function name which will be executed on quit event
0, // handle to Winamp main window, loaded by winamp when this dll is loaded
0 // hinstance to this dll, loaded by winamp when this dll is loaded

};

// event functions follow
MSG Komunikat;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HWND hwnd;
int init() {

HFONT hNormalFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
LPCWSTR ClassName = L"Class name";
WNDCLASSEX wc;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = plugin.hDllInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&wc);
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, ClassName, L"Name", WS_OVERLAPPED, 100, 100, 100, 100, plugin.hwndParent, NULL, plugin.hDllInstance, NULL);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);

while (GetMessage(&Komunikat, NULL, 0, 0))
{
TranslateMessage(&Komunikat);
DispatchMessage(&Komunikat);
}

return 0;
}

void config() {}
void quit() {}

// This is an export function called by winamp which returns this plugin info. // We wrap the code in 'extern "C"' to ensure the export isn't mangled if used in a CPP file.
extern "C" __declspec(dllexport) winampGeneralPurposePlugin * winampGetGeneralPurposePlugin() {

return &plugin;

}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}



gen_mood.h:

code:
#ifndef gen_mood_h
#define gen_mood_h
#include <windows.h>

// plugin version (don't touch this)
#define GPPHDR_VER 0x10

// plugin name/title (change this to something you like)
#define PLUGIN_NAME "Mood"


// main structure with plugin information, version, name...
typedef struct {

int version; // version of the plugin structure
char *description; // name/title of the plugin
int(*init)(); // function which will be executed on init event
void(*config)(); // function which will be executed on config event
void(*quit)(); // function which will be executed on quit event
HWND hwndParent; // hwnd of the Winamp client main window (stored by Winamp when dll is loaded)
HINSTANCE hDllInstance; // hinstance of this plugin DLL. (stored by Winamp when dll is loaded)

} winampGeneralPurposePlugin;


#endif //gen_mood_h

piotreek7 is offline   Reply With Quote
Old 10th September 2014, 14:49   #2
DrO
 
Join Date: Sep 2003
Posts: 27,873
it's most because of the message pump you've got in the plug-ins init(..) method. i'm pretty certain you don't need it (especially at that point since it's potentially never going to exit that method) and that's the best reason for the closing issue.

also you're not handling the case when GetMessage(..) can return -1 on error (see http://msdn.microsoft.com/en-gb/libr...=vs.85%29.aspx)

so i'd remove that part since Winamp's main window is running a message pump which should work for anything you create.
DrO is offline   Reply With Quote
Old 10th September 2014, 15:14   #3
piotreek7
Junior Member
 
Join Date: Mar 2014
Posts: 4
Thank You very much! That was the point!
I have deleted
while (GetMessage(&Komunikat, NULL, 0, 0))
{
TranslateMessage(&Komunikat);
DispatchMessage(&Komunikat);
}
and now everything works!
piotreek7 is offline   Reply With Quote
Reply
Go Back   Winamp & SHOUTcast Forums > Developer Center > Winamp Development

Tags
c++, plugin, winapi

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