VDJPedia



 Plugins_SDKv8_Example4

Back to Plugin SDK8

Basic Plugin using SDK v8 (with custom Skin Interface)



Here is an example to start developping a plugin "MyPlugin8". We use the class "CMyPlugin8" to define our object but you can use what you want. The file "Main.cpp" is the caller of your object "CMyPlugin8" and is the entry point to communicate with VirtualDJ.
We also use the VDJINTERFACE_SKIN in this example to draw an advanced interface. If you need a more complexe interface, please use VDJINTERFACE_DIALOG instead.

For this example, you need to include the following file from the SDK v8 in your project: vdjPlugin8.h (basic common base-class for all plugins)
You can use other compiler but please find one example of Visual C++ project for this project on a PC. It will generate a .dll file
For the case of this example, please copy all the files in the same folder.

MyPlugin8.h:
#pragma once

#include "vdjPlugin8.h"


#include <stdio.h>

#if (defined(VDJ_WIN))
#include "resource.h"
#elif (defined(VDJ_MAC))
#include <string>
#include <fstream>
#define sprintf_s snprintf
#endif

class CMyPlugin8 : public IVdjPlugin8
{
public:
HRESULT VDJ_API OnLoad();
HRESULT VDJ_API OnGetPluginInfo(TVdjPluginInfo8 *infos);
ULONG VDJ_API Release();
HRESULT VDJ_API OnGetUserInterface(TVdjPluginInterface8 *pluginInterface);
HRESULT VDJ_API OnParameter(int id);
HRESULT VDJ_API OnGetParameterString(int id, char *outParam, int outParamSize);

protected:
typedef enum _ID_Interface
{
ID_SLIDER_1
} ID_Interface;

typedef struct _TRESOURCEREF
{
#if (defined(VDJ_WIN))
int id;
char *type;
#elif (defined(VDJ_MAC))
std::string name;
#endif
} TRESOURCEREF;


private:
//VDJ_WINDOW hWndParent;
float m_Dry;
float m_Wet;

HRESULT LoadFileFromResource(TRESOURCEREF ref, DWORD& size, void*& data);
};


MyPlugin8.cpp:
#include "MyPlugin8.h"

//-----------------------------------------------------------------------------
HRESULT VDJ_API CMyPlugin8::OnLoad()
{
m_Dry = 0.0f;
m_Wet = 0.0f;

//HRESULT hr;
//double qRes;
//hr = GetInfo("get hwnd",&qRes);
//if(hr!=S_OK) hWndParent=NULL;
//else hWndParent = (VDJ_WINDOW) (int) qRes;

DeclareParameterSlider(&m_Wet,ID_SLIDER_1,"Dry/Wet","D/W",1.0f);

OnParameter(ID_SLIDER_1);

return S_OK;
}
//-----------------------------------------------------------------------------
HRESULT VDJ_API CMyPlugin8::OnGetPluginInfo(TVdjPluginInfo8 *infos)
{
infos->PluginName = "MyPlugin8";
infos->Author = "Atomix Productions";
infos->Description = "My first VirtualDJ 8 plugin";
infos->Version = "1.0";
infos->Flags = 0x00;
infos->Bitmap = NULL;

return S_OK;
}
//---------------------------------------------------------------------------
ULONG VDJ_API CMyPlugin8::Release()
{
delete this;
return 0;
}
//---------------------------------------------------------------------------
HRESULT VDJ_API CMyPlugin8::OnGetUserInterface(TVdjPluginInterface8 *pluginInterface)
{

pluginInterface->Type = VDJINTERFACE_SKIN;

// this following code is just an example and needs to be adapted to your project.
TRESOURCEREF rcXML;
TRESOURCEREF rcPNG;

#if (defined(VDJ_WIN))
rcXML.id = IDR_SKINXML; // as defined in resource.h
rcPNG.id = IDR_SKINPNG; // as defined in resource.h
rcXML.type = "GUI";
rcPNG.type = "GUI";
#elif (defined(VDJ_MAC))
rcXML.name = "FX_GUI.xml";
rcPNG.name = "FX_GUI.png";
#endif

DWORD xmlsize=0;
void* xmldata=NULL;
LoadFileFromResource( rcXML, xmlsize, xmldata);
pluginInterface->Xml = static_cast<char*>(xmldata);

DWORD pngsize=0;
void* pngdata=NULL;
LoadFileFromResource( rcPNG, pngsize,pngdata);
pluginInterface->ImageBuffer = pngdata;
pluginInterface->ImageSize = pngsize;

return S_OK;
}
//---------------------------------------------------------------------------
HRESULT VDJ_API CMyPlugin8::OnParameter(int id)
{
switch(id)
{
case ID_SLIDER_1:
m_Dry = 1 - m_Wet;
break;
}

return S_OK;
}
//---------------------------------------------------------------------------
HRESULT VDJ_API CMyPlugin8::OnGetParameterString(int id, char *outParam, int outParamSize)
{
switch(id)
{
case ID_SLIDER_1:
sprintf_s(outParam,outParamSize,"+%.0f%%", m_Wet*100);
break;
}

return S_OK;
}
//----------------------------------------------------------------------------
HRESULT CMyPlugin8::LoadFileFromResource(TRESOURCEREF ref, DWORD& size, void*& data)
{

#if (defined(VDJ_WIN))

if (ref.id==0 || ref.type==NULL)
return S_FALSE;

HRSRC rc = FindResourceA(hInstance, MAKEINTRESOURCEA(ref.id), ref.type);
HGLOBAL rcData = LoadResource(hInstance, rc);
size = SizeofResource(hInstance, rc);
data = LockResource(rcData);

#elif (defined(VDJ_MAC))

if (ref.name.empty())
return S_FALSE;
CFBundleRef bundle = (CFBundleRef)hInstance;
CFStringRef resourceName = CFStringCreateWithCString(kCFAllocatorDefault, ref.name.c_str(), kCFStringEncodingUTF8);
if (!resourceName)
return S_FALSE;
CFURLRef url = CFBundleCopyResourceURL(bundle, resourceName, NULL, NULL);
CFRelease(resourceName);
if (!url)
return S_FALSE;

char filePath[1024];
bool success = CFURLGetFileSystemRepresentation(url, TRUE, (UInt8*)filePath, 1024);
CFRelease(url);

if (!success)
return S_FALSE;

std::ifstream dataFile(filePath, std::ios::binary);
if (dataFile.is_open())
{
dataFile.seekg(0,std::ios::end);
size = (DWORD)dataFile.tellg();
data = new char[size];
dataFile.seekg(0,std::ios::beg);
dataFile.read((char*)data,size);
dataFile.close();
}

#endif

return S_OK;
}


Main.cpp:
#include "MyPlugin8.h"

HRESULT VDJ_API DllGetClassObject(const GUID &rclsid,const GUID &riid,void** ppObject)
{
if (memcmp(&rclsid,&CLSID_VdjPlugin8,sizeof(GUID))==0 && memcmp(&riid,&IID_IVdjPluginBasic8,sizeof(GUID))==0)
{
*ppObject=new CMyPlugin8();
}
else
{
return CLASS_E_CLASSNOTAVAILABLE;
}

return NO_ERROR;
}


FX_GUI.xml:
<Skin name="MyPlugin8" version="8" width="220" height="200" >
<Copyright>Atomix Productions </copyright>

<textzone visibility="get_deck 'master' ? false : true">
<size width="51" height="14"/>
<pos x="115" y="10"/>
<text font="arial" size="13" weight="bold" color="#898989" align="left" format="DECK `get_deck`"/>
</textzone>

<textzone visibility="get_deck 'master' ? true : false">
<size width="51" height="14"/>
<pos x="115" y="10"/>
<text font="arial" size="13" weight="bold" color="#898989" align="left" format="MASTER"/>
</textzone>

<button action="effect active">
<tooltip>Activate Effect</Tooltip>
<size width="15" height="15"/>
<pos x="11" y="8"/>
<up x="+0" y="+0"/>
<selected x="+0" y="+200"/>
<over x="+0" y="+200"/>
<overselected x="+0" y="+200"/>
<down x="+0" y="+200"/>
</button>

<button action="effect_show_gui" >
<Tooltip>Close</tooltip>
<pos x="189" y="7"/>
<size width="19" height="18"/>
<up x="+0" y="+0"/>
<over x="+0" y="+200"/>
</button>

<button action="effect_dock_gui" >
<Tooltip>Dock Effect</tooltip>
<pos x="166" y="6"/>
<size width="19" height="18"/>
<up x="+0" y="+0"/>
<over x="+0" y="+200"/>
</button>

<slider action="effect slider 1" orientation="round" >
<pos x="31" y="49" width="37" height="37"/>
<clipmask x="5" y="425"/>
<fader>
<pos x="5" y="235" nb="25" nbx="5" smooth="true"/>
</fader>
</slider>

<textzone >
<size width="51" height="14"/>
<pos x="23" y="89"/>
<up x="+0" y="515"/>
<text font="arial" size="14" weight="bold" color="white" align="center" action="get_effect_slider_text 1"/>
</textzone>

</Skin>


FX_GUI.png:





Back to Plugin SDK8