beginner needs help please: steinbergs minihost crashes with some plugins

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Doesn't make a difference.

Post

ok, here is the simple code. It uses the first command line argument as plugin filepath, outputs some plugin properties to the console, creates a dialog box, opens the plugineditor, grabs the window content and saves the gui bitmap as png (filename = .\.\plugin.dll.png)

it works with most of my plugins, but not AM Freehand Free.

BTW, I deactivated the error dialog on app crash, cause I want to make sure that the .exe quits in either case without user intervention.

Ah, and the dialog box is created as toolbar and fully transparent, so that the user doesn't see guis popup from nowhere or taskbar icons, when run without console window...

maybe anyone can check, wether it works for his AM Freehand Free?

Code: Select all

// PluginAnalyzer.cpp
#include "stdafx.h"
#include "windows.h"
#include "wincodec.h"
#include "objbase.h"
#pragma comment(lib, "WindowsCodecs.lib")
#include "P:\SDKs\vstsdk2.4\pluginterfaces\vst2.x/aeffectx.h"

typedef AEffect* (*PluginEntryProc) (audioMasterCallback audioMaster);

static VstIntPtr VSTCALLBACK HostCallback (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);
static INT_PTR CALLBACK EditorProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ChildProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

HINSTANCE hInstance = NULL;
HMODULE module = NULL;
PluginEntryProc mainProc = NULL;
AEffect* effect = NULL;
TCHAR effString[256] = {0};
struct MyDLGTEMPLATE: DLGTEMPLATE
{
	WORD ext[3];
	MyDLGTEMPLATE ()
	{
		memset (this, 0, sizeof (*this));
	};
};
TCHAR filename[MAX_PATH] = {0};
int _tmain(int argc, _TCHAR* argv[])
{
	hInstance = GetModuleHandle(0);
	// error mode (we assume some things crashing nevertheless)
	DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
	SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
	strcpy_s(filename, argv[1]);
	// plugin dll laden
	module = LoadLibrary(filename);
	if (!module) return false;
	mainProc = (PluginEntryProc)GetProcAddress((HMODULE)module, "VSTPluginMain");
	if (!mainProc)
		mainProc = (PluginEntryProc)GetProcAddress((HMODULE)module, "main");
	if (!mainProc) return false;
	effect = mainProc(HostCallback);
	if (!effect) return false;
	if (effect->magic != kEffectMagic) return false;
	// init plugin
	effect->dispatcher(effect, effOpen, 0, 0, 0, 0);
	effect->dispatcher(effect, effSetSampleRate, 0, 0, 0, 48000.f);
	effect->dispatcher(effect, effSetBlockSize, 0, 512, 0, 0);
	// properties
	effect->dispatcher(effect, effGetVendorString, 0, 0, effString, 0);
	printf("vendor=%s\n", effString);
	effect->dispatcher(effect, effGetProductString, 0, 0, effString, 0);
	printf("product=%s\n", effString);
	effect->dispatcher(effect, effGetEffectName, 0, 0, effString, 0);
	printf("effect=%s\n", effString);
	printf("build=%u\n", effect->dispatcher(effect, effGetVendorVersion, 0, 0, effString, 0));
	printf("vst=%u\n", effect->dispatcher(effect, effGetVstVersion, 0, 0, effString, 0));
	printf("uid=%X\n", effect->uniqueID);
	printf("version=%u\n", effect->version);
	printf("flags=%X\n", effect->flags);
	printf("numInputs=%i\n", effect->numInputs);
	printf("numOutputs=%i\n", effect->numOutputs);
	printf("numParams=%i\n", effect->numParams);
	// editor
	if ((effect->flags & effFlagsHasEditor) != 0)
	{
		MyDLGTEMPLATE t;	
		t.style = WS_POPUPWINDOW;
		t.cx = 100;
		t.cy = 100;
		DialogBoxIndirect(hInstance, &t, NULL, (DLGPROC)EditorProc);
	}
	// plugin dll entladen
	effect->dispatcher (effect, effClose, 0, 0, 0, 0);
	FreeLibrary ((HMODULE)module);
	return 0;
}
//-------------------------------------------------------------------------------------------------------
VstIntPtr VSTCALLBACK HostCallback (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt)
{
	VstIntPtr result = 0;
	switch (opcode)
	{
		case audioMasterVersion :
			result = kVstVersion;
			break;
	}
	return result;
}
//-------------------------------------------------------------------------------------------------------
INT_PTR CALLBACK EditorProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	RECT rc; 
	int width = 0;
	int height = 0;
	static int i = 0;
	wchar_t pngfilename[MAX_PATH] = {0};

	switch(msg)
	{
		//-----------------------
		case WM_INITDIALOG :
			effect->dispatcher(effect, effEditOpen, 0, 0, hwnd, 0);
			SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE);
			SetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA);
			SetTimer (hwnd, 1, 20, 0);
			if (effect)
			{
				ERect* eRect = 0;
				effect->dispatcher (effect, effEditGetRect, 0, 0, &eRect, 0);
				if (eRect)
				{
					width = eRect->right - eRect->left;
					height = eRect->bottom - eRect->top;
					RECT wRect;
					SetRect (&wRect, 0, 0, width, height);
					AdjustWindowRectEx (&wRect, GetWindowLong (hwnd, GWL_STYLE), FALSE, GetWindowLong (hwnd, GWL_EXSTYLE));
					width = wRect.right - wRect.left;
					height = wRect.bottom - wRect.top;
					SetWindowPos(hwnd, HWND_TOP, 0, 0, width, height, SWP_NOACTIVATE | SWP_NOMOVE);
				}
			}
			break;
		//-----------------------
		case WM_TIMER :
			effect->dispatcher (effect, effEditIdle, 0, 0, 0, 0);
			if (i++>10)
				SendMessage(hwnd, WM_CLOSE, 0, 0);
			break;
		//-----------------------
		case WM_CLOSE :
			KillTimer (hwnd, 1);
			GetClientRect(hwnd, &rc); 
			//create 
			HDC hdcScreen = GetDC(NULL); 
			HDC hdc = CreateCompatibleDC(hdcScreen); 
			HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, rc.right - rc.left, rc.bottom - rc.top); 
			SelectObject(hdc, hbmp);  			
			//Print to memory hdc 
			PrintWindow(hwnd, hdc, PW_CLIENTONLY);  
			//COM WIC save to png
			IWICImagingFactory *pFactory = NULL;
			IWICBitmap* WICBitmap = NULL;
			IWICStream *pFileStream = NULL;
		    IWICBitmapEncoder *pEncoder = NULL;
			IWICBitmapFrameEncode *pFrameEncode = NULL;
			WICRect rect = {0};
			UINT width = 0;
			UINT height = 0;
			HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
			hr = CoCreateInstance(	CLSID_WICImagingFactory,
									NULL,
									CLSCTX_INPROC_SERVER,
									IID_PPV_ARGS(&pFactory));
			hr = pFactory->CreateBitmapFromHBITMAP(hbmp, NULL, WICBitmapIgnoreAlpha, &WICBitmap);
			WICBitmap->GetSize(&width, &height);
			rect.Width = width;
			rect.Height = height;
			hr = pFactory->CreateStream(&pFileStream);
			mbstowcs(pngfilename, filename, strlen(filename)+1);
			wcscat(pngfilename, L".png");
			hr = pFileStream->InitializeFromFilename(pngfilename, GENERIC_WRITE);
			hr = pFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &pEncoder);
			hr = pEncoder->Initialize(pFileStream, WICBitmapEncoderNoCache);
			hr = pEncoder->CreateNewFrame(&pFrameEncode, NULL);
			hr = pFrameEncode->Initialize(NULL);
			hr = pFrameEncode->WriteSource(WICBitmap, &rect);
			hr = pFrameEncode->Commit();
			hr = pEncoder->Commit();
			//release 
			DeleteDC(hdc); 
			DeleteObject(hbmp); 
			ReleaseDC(NULL, hdcScreen);
			effect->dispatcher (effect, effEditClose, 0, 0, 0, 0);
			EndDialog (hwnd, IDOK);
			break;
	}
	return 0;
}

Post

resume() and startProcess() aren't called before opening the editor. Some PlugIns don't initialize before resume() has been called.
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

Even this doesn't help. Am freehand free and some others crash.

Post

I compiled your code (no precompiled headers) and it seems it doesn't crash.
If i remove WS_EX_LAYERED, i can see the gui.

Post Reply

Return to “DSP and Plugin Development”