Este ejemplo fue sacado de uno de los usuarios que utilizan BCX. Este Programita utiliza el Control Windows Media Player y lo pone en un form.
El codigo es el siguiente:
// *************************************************************
// Created with BCX -- The BASIC To C Translator (ver 5.11a)
// BCX (c) 1999 - 2006 by Kevin Diggins
// *************************************************************
// Translated for compiling with a C Compiler
// *************************************************************
#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif
#include <windows.h> // Win32 Header File
#include <windowsx.h> // Win32 Header File
#include <commctrl.h> // Win32 Header File
#include <mmsystem.h> // Win32 Header File
#include <shellapi.h> // Win32 Header File
#include <shlobj.h> // Win32 Header File
#include <richedit.h> // Win32 Header File
#include <wchar.h> // Win32 Header File
#include <objbase.h> // Win32 Header File
#include <ocidl.h> // Win32 Header File
#include <winuser.h> // Win32 Header File
#include <olectl.h> // Win32 Header File
#include <oaidl.h> // Win32 Header File
#include <ole2.h> // Win32 Header File
#include <oleauto.h> // Win32 Header File
#include <conio.h>
#include <direct.h>
#include <ctype.h>
#include <io.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <setjmp.h>
#include <time.h>
#include <stdarg.h>
#include <process.h>
// ***************************************************
// Compiler Defines
// ***************************************************
// C++
#if defined( __cplusplus )
#define overloaded
#define C_EXPORT EXTERN_C __declspec(dllexport)
#define C_IMPORT EXTERN_C __declspec(dllimport)
#else
#define C_EXPORT __declspec(dllexport)
#define C_IMPORT __declspec(dllimport)
#endif
// Open Watcom defs
#if defined( __WATCOM_CPLUSPLUS__ ) || defined( __TINYC__ )
#define atanl atan
#define sinl sin
#define cosl cos
#define tanl tan
#define asinl asin
#define acosl acos
#define log10l log10
#define logl log
#define _fcloseall fcloseall
#endif
// Borland C++ 5.5.1 defs - bcc32.exe
#if defined( __BCPLUSPLUS__ )
// ===== Borland Libraries ==========
#include <dos.h>
#pragma comment(lib,"import32.lib")
#pragma comment(lib,"cw32.lib")
// ==================================
#endif
// Microsoft VC++
#ifndef DECLSPEC_UUID
#if (_MSC_VER >= 1100) && defined ( __cplusplus )
#define DECLSPEC_UUID(x) __declspec(uuid(x))
#else
#define DECLSPEC_UUID(x)
#endif
#endif
#include <oaidl.h>
#if !defined( __LCC__ )
// *************************************************
// Instruct Linker to Search Object/Import Libraries
// *************************************************
#pragma comment(lib,"oleaut32.lib")
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"winspool.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"odbc32.lib")
#pragma comment(lib,"odbccp32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"comdlg32.lib")
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"version.lib")
#else
#pragma lib <oleaut32.lib>
#pragma lib <uuid.lib>
#pragma lib <winspool.lib>
#pragma lib <shell32.lib>
#pragma lib <ole32.lib>
#pragma lib <odbc32.lib>
#pragma lib <odbccp32.lib>
#pragma lib <winmm.lib>
#pragma lib <imagehlp.lib>
#pragma lib <version.lib>
// *************************************************
// End of Object/Import Libraries To Search
// *************************************************
#endif
// *************************************************
// User Defined Constants
// *************************************************
#define IDC_CTRL 1001
#define IDC_Btn1 1002
// *************************************************
// System Variables
// *************************************************
/* <--UNICODE AWARE--> */
// *************************************************
// Late binding COM support section
// (c) Ljubisa Knezevic 2004, ljube@blic.net
// *************************************************
#include <unknwn.h>
#include <tchar.h>
// types used by Late binding COM support
#define COM_STACK_SIZE 64
#ifndef CON_VARBOOL2BOOL
#define CON_VARBOOL2BOOL(b) ((BOOL)(b ? TRUE : FALSE))
#endif
typedef struct _OBJECT
{
IUnknown* p_unknown;
VARIANT pObjects[COM_STACK_SIZE];
BOOL pStatus;
int ipointer;
}OBJECT, *LPOBJECT;
typedef struct _PARAM_VARARRAY
{
VARIANT pParams[COM_STACK_SIZE];
}PARAM_VARARRAY, *LPPARAM_VARARRAY;
// global vars used by late binding COM support
static PARAM_VARARRAY bcx_static_param_list;
static _TCHAR bcx_last_com_error_holder[4096];
static _TCHAR bcx_last_com_error_indicator[64];
static int bcx_param_list_index_p=0;
static VARIANT bcx_temp_result_variant;
static HRESULT bcx_last_com_HRESULT;
static BOOL bcx_ole_initialized = FALSE;
static int bcx_ole_objects_count = 0;
static int bcx_force_reset_chain = 0;
static BOOL BCX_COM_ERROR = FALSE;
static BOOL bSHOW_BCX_COM_ERROR = FALSE;
static SAFEARRAY * bcx_safe_array_pointer_psa = NULL;
static LPOLESTR bcx_temp_wide_string_pointer = NULL;
static char* bcx_temp_ans_string_pointer = NULL;
static ULONG bcx_temp_wide_string_buffer_size = 0;
static ULONG bcx_temp_ans_string_buffer_size = 0;
static BOOL bcx_com_get_enumerator_intf = FALSE;
static int bcx_preserve_dispatch_storage[ 32];
static int bcx_preserve_dispatch_storage_index = 0;
static int bcx_preserve_dispatch_at_offset = 0;
/* >--UNICODE AWARE--< */
HHOOK CmDlgHook;
HINSTANCE BCX_DllStore[256];
// *************************************************
// User Global Variables
// *************************************************
static HFONT BcxFont;
static float BCX_ScaleX;
static float BCX_ScaleY;
static HINSTANCE BCX_hInstance;
static HWND BCX_hwndMDIClient;
static WNDCLASSEX BCX_WndClass;
static BOOL BCX_GUI_Init;
static char BCX_ClassName[2048];
static HWND hWmp;
static HWND Form;
static HWND Btn1;
static IUnknown *pUnk;
static OBJECT objWmp;
static char Pth[2048];
// *************************************************
// Standard Macros
// *************************************************
#define DefaultFont ((BcxFont==0)?GetStockObject(DEFAULT_GUI_FONT):BcxFont)
#define Show(Window)RedrawWindow(Window,0,0,0);ShowWindow(Window,SW_SHOW);
// *************************************************
// Standard Prototypes
// *************************************************
void BCX_SetMetric (char *);
void BCX_RegWnd (char *, WNDPROC);
void BCX_InitGUI (void);
HWND BCX_Form(char*,int=0,int=0,int=250,int=150,int=0,int=0);
HWND BCX_Button(char*,HWND,int=0,int=0,int=0,int=0,int=0,int=0,int=-1);
HWND BCX_Control (char*,HWND,char*,int,int,int,int,int,int=0,int=0);
char* BCX_TmpStr(size_t);
char* sysdir (void);
LRESULT CALLBACK SBProc (int, WPARAM, LPARAM);
char* GetFileName (char*,char*,int=0,HWND=0,DWORD=0,char* =0,char* =0,int* =0);
SIZE* GetTextSize (char*, HWND=0, HFONT=0);
char* join (int, ... );
// COM functions used internally by BCX
void bcx_ole_initialize(void);
void bcx_ole_uninitialize(void);
void bcx_catch_hr_error_desc(HRESULT hr, TCHAR* extra_info);
DISPID bcx_get_DISPID_of_dispatch(IDispatch* lpDispatch, LPOLESTR comsegment);
void bcx_get_next_dispatch(OBJECT* object, LPOLESTR comsegment);
void bcx_invoke_helper(OBJECT* object, LPOLESTR comsegment,WORD wFlags, VARIANT *pvResult);
void bcx_build_exception_info(HRESULT hr, EXCEPINFO* pexcep = NULL, UINT uiArgErr= 0);
void bcx_clean_parameter_list(void);
void bcx_reset_dispatch_chain(OBJECT* object);
void bcx_create_safe_array(void);
// public COM support functions >>>
void BCX_SetNothing(OBJECT* object);
HRESULT BCX_GET_COM_ERROR_CODE(void);
char* BCX_GET_COM_ERROR_DESC(void);
BOOL BCX_GET_COM_SUCCESS(void);
void BCX_SHOW_COM_ERRORS(BOOL Show_err);
void BCX_DispatchObject(IUnknown* iobj, OBJECT* obj, BOOL b_release = TRUE);
// <<< public COM support functions
HRESULT BCX_COM_AS2WS(LPCSTR ansi_string, UINT code_page = CP_ACP);
HRESULT BCX_COM_WS2AS(LPCWSTR wide_string, UINT code_page = CP_ACP);
void BCX_COM_FREE_TEMP_ANSI_STRING(void);
void BCX_COM_FREE_TEMP_WIDE_STRING(void);
HINSTANCE BCX_LoadDll(char *);
void BCX_UnloadDll(void);
typedef int (CALLBACK *DYNACALL1)(void);
int BCX_DynaCall(char *, char *, int, ...);
// *************************************************
// User Prototypes
// *************************************************
void FormLoad (void);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
void LoadWmp (char *);
// **********************************
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR CmdLine,int CmdShow)
{
MSG Msg;
strcpy(BCX_ClassName,"MediaPlayer4");
BCX_SetMetric("pixels");
BCX_InitGUI();
BCX_hInstance = hInst;
BCX_WndClass.hIcon = LoadIcon(NULL,IDI_WINLOGO);
BCX_RegWnd( BCX_ClassName, WndProc );
// ******************************************
FormLoad();
// ******************************************
while(GetMessage(&Msg,NULL,0,0))
{
HWND hActiveWindow = GetActiveWindow();
if(!IsWindow(hActiveWindow) || !IsDialogMessage(hActiveWindow,&Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return Msg.wParam;
}
// *************************************************
// Runtime Functions
// *************************************************
char *BCX_TmpStr (size_t Bites)
{
static int StrCnt;
static char *StrFunc[2048];
StrCnt=(StrCnt + 1) & 2047;
if(StrFunc[StrCnt]) free (StrFunc[StrCnt]);
return StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char));
}
char *sysdir (void)
{
register char *strtmp = BCX_TmpStr(2048);
GetSystemDirectory (strtmp,2048);
return strtmp;
}
char * join(int n, ...)
{
register int i = n, tmplen = 0;
register char *s_;
register char *strtmp;
va_list marker;
va_start(marker, n); // Initialize variable arguments
while(i-- > 0)
{
s_ = va_arg(marker, char *);
if(s_) tmplen += strlen(s_);
}
strtmp = BCX_TmpStr(tmplen);
va_end(marker); // Reset variable arguments
i = n;
va_start(marker, n); // Initialize variable arguments
while(i-- > 0)
{
s_ = va_arg(marker, char *);
if(s_) strcat(strtmp, s_);
}
va_end(marker); // Reset variable arguments
return strtmp;
}
LRESULT CALLBACK SBProc (int Msg, WPARAM wParam, LPARAM lParam)
{
if(Msg==HCBT_ACTIVATE)
{
static RECT rc1;
static RECT rc2;
GetWindowRect(GetDesktopWindow(),&rc1);
GetWindowRect((HWND)wParam,&rc2);
SetWindowPos((HWND)wParam,HWND_TOP,(rc1.left+rc1.right-rc2.right+rc2.left)/2,
(rc1.top+rc1.bottom-rc2.bottom+rc2.top)/2,0,0,SWP_NOSIZE|SWP_NOACTIVATE);
UnhookWindowsHookEx(CmDlgHook);
}
return 0;
}
char *GetFileName(char *Title,char *Filter,int Flag,HWND hWnd,DWORD Flags,char *InitialDir,char *Initfname,int *ExtIdx)
{
OPENFILENAME OpenFileStruct;
char Extension[256];
int Counter=0, TmpSize;
static char *filename;
static int BufSize;
TmpSize = ((Flags&OFN_ALLOWMULTISELECT) ? 500000:MAX_PATH);
if(TmpSize>BufSize)
{
BufSize=TmpSize;
filename=(char*)realloc(filename, BufSize);
}
memset(filename,0,BufSize);
memset(Extension,0,256);
memset(&OpenFileStruct,0,sizeof(OpenFileStruct));
if(Initfname) strcpy(filename,Initfname);
for(Counter=0;Counter<=strlen(Filter);Counter++)
{
if(Filter[Counter]=='|')
Extension[Counter]=0;
else
Extension[Counter]=Filter[Counter];
}
CmDlgHook=SetWindowsHookEx(WH_CBT,(HOOKPROC)SBProc,(HINSTANCE)NULL,GetCurrentThreadId());
OpenFileStruct.lStructSize=sizeof(OpenFileStruct);
OpenFileStruct.hwndOwner=hWnd;
OpenFileStruct.hInstance=0;
OpenFileStruct.lpstrFilter=Extension;
OpenFileStruct.lpstrTitle=Title;
OpenFileStruct.nMaxFile=BufSize;
OpenFileStruct.nMaxFileTitle=0;
OpenFileStruct.lpstrFile=filename;
OpenFileStruct.lpstrFileTitle=NULL;
OpenFileStruct.lpstrCustomFilter=0;
OpenFileStruct.nMaxCustFilter=0;
if(ExtIdx) OpenFileStruct.nFilterIndex=*ExtIdx;
OpenFileStruct.lpstrInitialDir=InitialDir;
OpenFileStruct.nFileOffset=0;
OpenFileStruct.nFileExtension=0;
OpenFileStruct.lpstrDefExt=0;
OpenFileStruct.lCustData=0;
OpenFileStruct.lpfnHook=0;
OpenFileStruct.lpTemplateName=0;
if(!Flags)
OpenFileStruct.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_EXPLORER;
else
OpenFileStruct.Flags = Flags | OFN_EXPLORER;
if(!Flag)
{
if(GetOpenFileName(&OpenFileStruct)==0)
{
*filename=0;
}else{
int len=strlen(filename);
if(filename[len+1]==0) return filename;
char *fname = filename+len;
while(fname[1])
{
*fname= ',';
len=strlen(++fname);
fname+=len;
}
}
}
else
{
if(GetSaveFileName(&OpenFileStruct)==0) *filename=0;
}
if(ExtIdx) *ExtIdx=OpenFileStruct.nFilterIndex;
return filename;
}
HWND BCX_Form(char *Caption,int X,int Y,int W,int H,int Style,int Exstyle)
{
if(!Style)
{
Style= WS_MINIMIZEBOX | WS_SIZEBOX | WS_CAPTION |
WS_MAXIMIZEBOX | WS_POPUP | WS_SYSMENU;
}
HWND A = CreateWindowEx(Exstyle,BCX_ClassName,Caption,Style,
X*BCX_ScaleX,Y*BCX_ScaleY,(4+W)*BCX_ScaleX,(12+H)*BCX_ScaleY,
NULL,(HMENU)NULL,BCX_hInstance,NULL);
SendMessage(A,(UINT)WM_SETFONT,(WPARAM)DefaultFont,(LPARAM)MAKELPARAM(FALSE,0));
return A;
}
HWND BCX_Button(char* Text,HWND hWnd,int id,int X,int Y,int W,int H,int Style,int Exstyle)
{
if(!Style)
{
Style=WS_CHILD | WS_VISIBLE | BS_MULTILINE | BS_PUSHBUTTON | WS_TABSTOP;
}
if(Exstyle==-1)
{
Exstyle=WS_EX_STATICEDGE;
}
HWND A = CreateWindowEx(Exstyle,"button",Text,Style,
X*BCX_ScaleX, Y*BCX_ScaleY, W*BCX_ScaleX, H*BCX_ScaleY,
hWnd,(HMENU)id,BCX_hInstance,NULL);
SendMessage(A,(UINT)WM_SETFONT,(WPARAM)DefaultFont,(LPARAM)MAKELPARAM(FALSE,0));
if (W==0)
{
SIZE* size=GetTextSize(Text,A);
MoveWindow(A,X*BCX_ScaleX,Y*BCX_ScaleY,size->cx+24,size->cy+12,TRUE);
}
return A;
}
HWND BCX_Control(char *Class,HWND hWnd,char *Caption,int id,int x,int y,int w,int h,int Style,int Exstyle)
{
HWND A;
if(!Style)Style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
A=CreateWindowEx(Exstyle,Class,Caption,Style,
x*BCX_ScaleX, y*BCX_ScaleY, w*BCX_ScaleX, h*BCX_ScaleY,
hWnd,(HMENU)id, BCX_hInstance, NULL);
SendMessage(A,(UINT)WM_SETFONT,(WPARAM)DefaultFont,(LPARAM)MAKELPARAM(FALSE,0));
return A;
}
SIZE* GetTextSize(char* text, HWND hWnd, HFONT fnt)
{
HDC hdc=GetDC(hWnd);
if(!fnt) fnt=(HFONT)SendMessage(hWnd,WM_GETFONT,0,0);
HFONT sobj=(HFONT)SelectObject(hdc,fnt);
static SIZE sz;
GetTextExtentPoint32(hdc,text,strlen(text),&sz);
SelectObject(hdc,sobj);
ReleaseDC(hWnd,hdc);
return (&sz);
}
HINSTANCE BCX_LoadDll (char *DllName)
{
static int DllCnt;
static int RegUnload;
if (!RegUnload) RegUnload=!atexit(BCX_UnloadDll);
DllCnt=(DllCnt+1) & 255;
FreeLibrary(BCX_DllStore[DllCnt]);
return BCX_DllStore[DllCnt]=LoadLibrary(DllName);
}
void BCX_UnloadDll (void)
{
register int i;
for(i=255;i>=0;i--)
{
FreeLibrary(BCX_DllStore[i]);
}
}
int BCX_DynaCall (char *FuncName, char *DllName, int nArgs, ...)
{
register int i;
HINSTANCE hInst=0;
DYNACALL1 lpAddr=0;
int arg, result =0;
int *argtable = (int*)malloc(nArgs * sizeof *argtable);
char buff[256];
va_list ap;
hInst=GetModuleHandle(DllName);
if(hInst==NULL)
{
hInst=BCX_LoadDll(DllName);
}
lpAddr=(DYNACALL1)GetProcAddress(hInst,FuncName);
if(lpAddr==NULL)
{
sprintf(buff,"%s%s",FuncName,"A");
lpAddr=(DYNACALL1)GetProcAddress(hInst,buff);
}
if(lpAddr==NULL)
{
sprintf(buff,"%s%s","_",FuncName);
lpAddr=(DYNACALL1)GetProcAddress(hInst,buff);
}
if (lpAddr)
{
va_start(ap,nArgs);
for (i=0; i<nArgs;i++)
{
arg = va_arg(ap,int);
argtable[i] = arg;
}
va_end(ap);
for (i=nArgs-1;i >=0; i--)
{
arg = argtable[i];
#if defined( __LCC__ )
_asm("pushl %arg")
#elif defined( __MINGW32__ ) || defined( __TINYC__)
__asm__("pushl %0" : : "r" (arg));
#elif defined( __BCPLUSPLUS__ )
asm push arg
#else
__asm{push arg}
#endif
}
result = (int)lpAddr();
}
free(argtable);
return result;
}
/* <--UNICODE AWARE--> */
HRESULT BCX_GET_COM_ERROR_CODE(void)
{
return bcx_last_com_HRESULT;
}
_TCHAR* BCX_GET_COM_ERROR_DESC(void)
{
return bcx_last_com_error_holder;
}
BOOL BCX_GET_COM_SUCCESS(void)
{
return (!BCX_COM_ERROR);
}
void BCX_SHOW_COM_ERRORS(BOOL Show_err)
{
bSHOW_BCX_COM_ERROR = Show_err;
}
void bcx_ole_initialize(void)
{
if (bcx_ole_initialized) return;
#ifdef __BCX_MULTITHREADED__
bcx_last_com_HRESULT = CoInitializeEx(NULL,COINIT_MULTITHREADED);
#else
bcx_last_com_HRESULT = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
#endif
if (SUCCEEDED(bcx_last_com_HRESULT)) {
bcx_ole_initialized = TRUE;
VariantInit(&bcx_temp_result_variant);
atexit(bcx_ole_uninitialize);
bcx_preserve_dispatch_storage[0] = 0;
bcx_preserve_dispatch_storage_index = 0;
if (bcx_temp_wide_string_pointer) CoTaskMemFree((void*)bcx_temp_wide_string_pointer);
bcx_temp_wide_string_pointer = (LPOLESTR)CoTaskMemAlloc(2048);
if (NULL == bcx_temp_wide_string_pointer){
bcx_temp_wide_string_buffer_size = 0;
bcx_last_com_HRESULT = E_OUTOFMEMORY;
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Mem Allocation of temp_wide_variable Failed in CoInitializeEx!"));
return;
} // if
bcx_temp_wide_string_buffer_size = 2048;
if (bcx_temp_ans_string_pointer) free(bcx_temp_ans_string_pointer);
bcx_temp_ans_string_pointer = (char*)calloc(2048,sizeof(char));
if (NULL == bcx_temp_ans_string_pointer){
bcx_last_com_HRESULT = E_OUTOFMEMORY;
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Mem Allocation of temp_char_variable Failed in CoInitializeEx!"));
return;
} // if
bcx_temp_ans_string_buffer_size = 2048;
return;
} else {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("CoInitializeEx Failed!"));
}
}
void bcx_ole_uninitialize(void)
{
if (bcx_ole_objects_count) {
_TCHAR ermm[2048];
wsprintf(ermm,_T("Check BCX Set Nothing Statement!\nNumber of objects not released: %d"), bcx_ole_objects_count);
MessageBox(GetActiveWindow(), ermm, _T("Memory leaks detected!"),MB_OK|MB_ICONWARNING|MB_TASKMODAL);
}
BCX_COM_FREE_TEMP_WIDE_STRING();
BCX_COM_FREE_TEMP_ANSI_STRING();
CoUninitialize();
}
void BCX_SetNothing(OBJECT* object)
{
if (!object->pStatus) return;
bcx_ole_objects_count--;
#ifdef __cplusplus
if (object->p_unknown) object->p_unknown->Release();
#else
if (object->p_unknown) object->p_unknown->lpVtbl->Release(object->p_unknown);
#endif
if (object->ipointer) {
bcx_reset_dispatch_chain(object);
object->ipointer = 0;
}
bcx_last_com_HRESULT = VariantClear(&object->pObjects[0]);
if (FAILED(bcx_last_com_HRESULT)) {
lstrcpy(bcx_last_com_error_indicator, _T("BCX_SetNothing Failed!"));
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Release of objects IDispatch interface failed!"));
}
object->pStatus = FALSE;
Sleep(100);
}
void bcx_catch_hr_error_desc(HRESULT hr, _TCHAR* extra_info)
{
BCX_COM_ERROR = TRUE;
void* pMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pMsgBuf, 0, NULL);
wsprintf(bcx_last_com_error_holder, _T("COM error code %d (0x%X)\n%s\n%s\nmember: %s"), hr,hr,extra_info, pMsgBuf, bcx_last_com_error_indicator);
memset(&bcx_last_com_error_indicator,0,sizeof(bcx_last_com_error_indicator));
if(bSHOW_BCX_COM_ERROR) {
MessageBox(GetActiveWindow(),bcx_last_com_error_holder, _T("BCX COM parser, error report:"), MB_OK|MB_ICONERROR|MB_SYSTEMMODAL);
}
LocalFree(pMsgBuf);
}
void bcx_build_exception_info(HRESULT hr, EXCEPINFO* pexcep, UINT uiArgErr)
{
SCODE oleSCODE;
static _TCHAR lv_message[2048];
oleSCODE = GetScode(hr);
while(1)
{
if (oleSCODE==DISP_E_PARAMNOTFOUND)
{
wsprintf(lv_message, _T("\nArgument not found, argument %d."), uiArgErr);
_tcscat(bcx_last_com_error_holder, lv_message);
break;
}
if (oleSCODE==DISP_E_TYPEMISMATCH)
{
wsprintf(lv_message, _T("\nType mismatch, argument %d."), uiArgErr);
_tcscat(bcx_last_com_error_holder, lv_message);
break;
}
if (oleSCODE==DISP_E_BADVARTYPE)
{
_tcscat(bcx_last_com_error_holder, _T("\nOne or more of the arguments passed in isn't a valid VARIANT type."));
break;
}
if (oleSCODE==E_INVALIDARG)
{
_tcscat(bcx_last_com_error_holder, _T("\nOne of the arguments is invalid."));
break;
}
break;
} // WHILE
if (pexcep)
{
wsprintf(lv_message, _T("\nCOM Error %X:"), pexcep->wCode);
if (pexcep->bstrDescription){
_TCHAR err_desc[512];
#ifndef UNICODE
bcx_last_com_HRESULT = BCX_COM_WS2AS(pexcep->bstrDescription);
if (FAILED(bcx_last_com_HRESULT)) {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Get Error Description Failed! Wide to ANSI conversion failure!"));
} else {
wsprintf(err_desc, _T("\nException desc: %s"), bcx_temp_ans_string_pointer);
} // if
#else
wsprintf(err_desc, _T("\nException desc: %s"), pexcep->bstrDescription);
#endif
_tcscat(lv_message, err_desc);
SysFreeString(pexcep->bstrDescription);
pexcep->bstrDescription = NULL;
}
if (pexcep->bstrSource) {
_TCHAR err_desc[512];
#ifndef UNICODE
bcx_last_com_HRESULT = BCX_COM_WS2AS(pexcep->bstrSource);
if (FAILED(bcx_last_com_HRESULT)) {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Get Error Source Failed! Wide to ANSI conversion failure!"));
} else {
wsprintf(err_desc, _T("\nException source: %s"), bcx_temp_ans_string_pointer);
} // if
#else
wsprintf(err_desc, _T("\nException source: %s"), pexcep->bstrSource);
#endif
_tcscat(lv_message, err_desc);
SysFreeString(pexcep->bstrSource);
pexcep->bstrSource = NULL;
}
if (pexcep->bstrHelpFile) {
_TCHAR err_desc[512];
#ifndef UNICODE
bcx_last_com_HRESULT = BCX_COM_WS2AS(pexcep->bstrHelpFile);
if (FAILED(bcx_last_com_HRESULT)) {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Get Help File Info Failed! Wide to ANSI conversion failure!"));
} else {
wsprintf(err_desc, _T("\nHelp file: %s | topic: %lu"), bcx_temp_ans_string_pointer, pexcep->dwHelpContext);
} // if
#else
wsprintf(err_desc, _T("\nHelp file: %s | topic: %lu"), pexcep->bstrHelpFile, pexcep->dwHelpContext);
#endif
_tcscat(lv_message, err_desc);
SysFreeString(pexcep->bstrHelpFile);
pexcep->bstrHelpFile = NULL;
}
_tcscat(bcx_last_com_error_holder ,lv_message);
}
if(bSHOW_BCX_COM_ERROR) {
MessageBox(NULL,bcx_last_com_error_holder, _T("BCX COM pareser, Exception Info:"), MB_OK|MB_ICONERROR|MB_SYSTEMMODAL);
}
}
DISPID bcx_get_DISPID_of_dispatch(IDispatch* lpDispatch, LPOLESTR comsegment)
{
static DISPID D_ID;
D_ID = 0;
if (!lpDispatch) return -1;
#ifdef __cplusplus
bcx_last_com_HRESULT = lpDispatch->GetIDsOfNames(IID_NULL, &comsegment, 1, LOCALE_SYSTEM_DEFAULT, &D_ID);
#else
bcx_last_com_HRESULT = lpDispatch->lpVtbl->GetIDsOfNames(lpDispatch, &IID_NULL, &comsegment, 1, LOCALE_SYSTEM_DEFAULT, &D_ID);
#endif
if (FAILED(bcx_last_com_HRESULT)) {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Unrecognized member name"));
return -1;
}
return D_ID;
}
void bcx_get_next_dispatch(OBJECT* object, LPOLESTR comsegment)
{
if (!object->pStatus) return;
if (0 == object->ipointer) BCX_COM_ERROR = FALSE;
if (BCX_COM_ERROR) return;
bcx_force_reset_chain++;
bcx_invoke_helper(object, comsegment,DISPATCH_PROPERTYGET|DISPATCH_METHOD,&object->pObjects[object->ipointer+1]);
bcx_force_reset_chain--;
if (!BCX_COM_ERROR) {
object->ipointer++;
}
}
void bcx_invoke_helper(OBJECT* object, LPOLESTR comsegment,WORD wFlags, VARIANT *pvResult)
{
if (!object->pStatus) return;
if (BCX_COM_ERROR) return;
DISPID lv_DID;
EXCEPINFO exception;
UINT argerr = 0;
DISPPARAMS dp = {NULL, NULL, 0, 0 };
WORD invoke_flags=0;
DISPID setdispid = DISPID_PROPERTYPUT;
if (bcx_com_get_enumerator_intf) {
lv_DID = DISPID_NEWENUM;
} else {
lv_DID = bcx_get_DISPID_of_dispatch(object->pObjects[object->ipointer].pdispVal, comsegment);
if (-1 == lv_DID) goto cleanInProp;
} // if
memset(&exception,0,sizeof(EXCEPINFO));
if(bcx_param_list_index_p>0){
setdispid = DISPID_PROPERTYPUT;
dp.rgvarg = (VARIANTARG*)bcx_static_param_list.pParams;
} // if
if(wFlags & DISPATCH_PROPERTYPUT) {
dp.rgdispidNamedArgs = &setdispid;
dp.cNamedArgs = 1;
}
dp.cArgs = bcx_param_list_index_p;
invoke_flags = wFlags;
if(wFlags & DISPATCH_PROPERTYGET) {
if (pvResult) VariantInit(pvResult);
}
if (VT_DISPATCH != object->pObjects[object->ipointer].vt||NULL==object->pObjects[object->ipointer].pdispVal){
bcx_last_com_HRESULT = E_NOINTERFACE;
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("bcx_invoke_helper::Invalid IDispatch interface."));
goto cleanInProp;
}
#ifdef __cplusplus
bcx_last_com_HRESULT = object->pObjects[object->ipointer].pdispVal->Invoke(lv_DID, IID_NULL, LOCALE_SYSTEM_DEFAULT, invoke_flags , &dp, pvResult, &exception, &argerr);
#else
bcx_last_com_HRESULT = object->pObjects[object->ipointer].pdispVal->lpVtbl->Invoke(object->pObjects[object->ipointer].pdispVal, lv_DID, &IID_NULL, LOCALE_SYSTEM_DEFAULT, invoke_flags , &dp, pvResult, &exception, &argerr);
#endif
if (FAILED(bcx_last_com_HRESULT)) {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("bcx_invoke_helper::Invoke failed."));
bcx_build_exception_info(bcx_last_com_HRESULT,&exception,argerr);
}
cleanInProp:
if(V_ISARRAY(&bcx_static_param_list.pParams[0])) {
if((VT_ARRAY|VT_VARIANT)==bcx_static_param_list.pParams[0].vt) {
bcx_last_com_HRESULT = SafeArrayDestroy(V_ARRAY(&bcx_static_param_list.pParams[0]));
if (FAILED(bcx_last_com_HRESULT)) {
lstrcpy(bcx_last_com_error_indicator, _T("SafeArrayDestroy failed"));
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Error while cleaning parameter list."));
}
ZeroMemory((PVOID)&bcx_static_param_list.pParams[0],sizeof(VARIANT));
bcx_safe_array_pointer_psa = NULL;
bcx_param_list_index_p = 0;
}
}
if (bcx_param_list_index_p) bcx_clean_parameter_list();
if (0 == bcx_force_reset_chain) bcx_reset_dispatch_chain(object);
}
void bcx_clean_parameter_list(void)
{
int total_parms = bcx_param_list_index_p;
if(bcx_param_list_index_p > 0) {
do {
bcx_last_com_HRESULT = VariantClear(&bcx_static_param_list.pParams[bcx_param_list_index_p-1]);
if (FAILED(bcx_last_com_HRESULT)) {
wsprintf(bcx_last_com_error_indicator, _T("\nVariant type = %d, at index %d, total params = %d."),bcx_static_param_list.pParams[bcx_param_list_index_p-1].vt, bcx_param_list_index_p-1, total_parms);
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Error while cleaning parameter list."));
}
bcx_param_list_index_p--;
} while(bcx_param_list_index_p > 0);
} // if
}
void bcx_reset_dispatch_chain(OBJECT* object)
{
if(object->ipointer>bcx_preserve_dispatch_at_offset) {
do {
VariantClear(&object->pObjects[object->ipointer]);
object->ipointer--;
} while (object->ipointer > bcx_preserve_dispatch_at_offset);
} //if
}
/* >--UNICODE AWARE--< */
/* <--UNICODE AWARE--> */
void BCX_DispatchObject(IUnknown* iobj, OBJECT* obj, BOOL b_release)
{
if (!obj) return;
static ULONG inc_inf_ussage=0;
if (!bcx_ole_initialized) bcx_ole_initialize();
obj->p_unknown = iobj;
#ifdef __cplusplus
inc_inf_ussage = obj->p_unknown->AddRef();
#else
inc_inf_ussage = obj->p_unknown->lpVtbl->AddRef(obj->p_unknown);
#endif
VariantInit(&obj->pObjects[0]);
#ifdef __cplusplus
bcx_last_com_HRESULT = obj->p_unknown->QueryInterface(IID_IDispatch, (void **)&obj->pObjects[0].pdispVal);
#else
bcx_last_com_HRESULT = obj->p_unknown->lpVtbl->QueryInterface(obj->p_unknown, &IID_IDispatch, (void **)&obj->pObjects[0].pdispVal);
#endif
if (FAILED(bcx_last_com_HRESULT)) {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("QueryInterface::IID_IDispatch failed!"));
#ifdef __cplusplus
obj->p_unknown->Release();
#else
obj->p_unknown->lpVtbl->Release(obj->p_unknown);
#endif
return;
} // if
if (b_release) {
#ifdef __cplusplus
iobj->Release();
#else
iobj->lpVtbl->Release(obj->p_unknown);
#endif
}
obj->pObjects[0].vt = VT_DISPATCH;
obj->pStatus = TRUE;
obj->ipointer = 0;
bcx_ole_objects_count++;
}
/* >--UNICODE AWARE--< */
/* <--UNICODE AWARE--> */
HRESULT BCX_COM_WS2AS(LPCWSTR wide_string, UINT code_page)
{
if(wide_string==NULL) return (HRESULT) NO_ERROR;
ULONG temp_bytes_copied_len=0;
ULONG temp_ansi_len = (ULONG)WideCharToMultiByte(code_page,0,wide_string,-1,bcx_temp_ans_string_pointer,0,NULL,NULL)+256;
if(temp_ansi_len==0) return (HRESULT) NO_ERROR;
if (bcx_temp_ans_string_buffer_size < temp_ansi_len) {
if (bcx_temp_ans_string_pointer) free(bcx_temp_ans_string_pointer);
bcx_temp_ans_string_pointer = (char*)calloc(temp_ansi_len,sizeof(char));
if (NULL == bcx_temp_ans_string_pointer){
bcx_temp_ans_string_buffer_size = 0;
return E_OUTOFMEMORY;
} // if
bcx_temp_ans_string_buffer_size = temp_ansi_len;
}
if((temp_bytes_copied_len = WideCharToMultiByte(code_page,0,wide_string,-1,bcx_temp_ans_string_pointer,temp_ansi_len,NULL,NULL))==0)
{
return HRESULT_FROM_WIN32(GetLastError());
} // if
bcx_temp_ans_string_pointer[temp_bytes_copied_len] = '\0';
return (HRESULT)NO_ERROR;
}
HRESULT BCX_COM_AS2WS(LPCSTR ansi_string, UINT code_page)
{
if (!*ansi_string) return (HRESULT)NO_ERROR;
ULONG ansi_str_len = strlen(ansi_string);
if (!ansi_str_len) return (HRESULT)NO_ERROR;
ULONG wide_str_len = (ansi_str_len * 2) + 256;
if (bcx_temp_wide_string_buffer_size < wide_str_len) {
if (bcx_temp_wide_string_pointer) CoTaskMemFree((void*)bcx_temp_wide_string_pointer);
bcx_temp_wide_string_pointer = (LPOLESTR)CoTaskMemAlloc(wide_str_len);
if (NULL == bcx_temp_wide_string_pointer){
bcx_temp_wide_string_buffer_size = 0;
return E_OUTOFMEMORY;
} // if
bcx_temp_wide_string_buffer_size = wide_str_len;
}
if (MultiByteToWideChar(code_page, MB_PRECOMPOSED, ansi_string, ansi_str_len, bcx_temp_wide_string_pointer, wide_str_len)==0) {
return HRESULT_FROM_WIN32(GetLastError());
} // if
bcx_temp_wide_string_pointer[ansi_str_len] = L'\0';
return (HRESULT)NO_ERROR;
}
void BCX_COM_FREE_TEMP_WIDE_STRING(void)
{
if (bcx_temp_wide_string_pointer) {
CoTaskMemFree((void*)bcx_temp_wide_string_pointer);
bcx_temp_wide_string_pointer = NULL;
}
}
void BCX_COM_FREE_TEMP_ANSI_STRING(void)
{
if (bcx_temp_ans_string_pointer) {
free(bcx_temp_ans_string_pointer);
bcx_temp_ans_string_pointer = NULL;
}
}
/* >--UNICODE AWARE--< */
void BCX_SetMetric (char *metric)
{
if(!BCX_GUI_Init)
{
BCX_InitGUI();
}
if(stricmp(metric,"PIXELS")==0)
{
BCX_ScaleX=1;
BCX_ScaleY=1;
}
else
{
RECT rc={0,0,4,8};
MapDialogRect(NULL,&rc);
BCX_ScaleX=rc.right/2;
BCX_ScaleY=rc.bottom/4;
}
}
void BCX_RegWnd (char *classname, WNDPROC Form_WndProc)
{
if(classname[0]==0)
{
MessageBox (GetActiveWindow(),"Empty String For BCX_ClassName NOT Allowed","Empty ClassName",0);
fflush(stdout);
ExitProcess(1);
}
if(GetClassInfoEx( BCX_hInstance, classname, &BCX_WndClass)!=0)
{
if(!Form_WndProc)
{
UnregisterClass(classname,BCX_hInstance);
}
return;
}
if(!BCX_GUI_Init)
{
BCX_InitGUI();
}
if(BCX_ScaleX==0&&BCX_ScaleY==0)
{
BCX_SetMetric("Pixels");
}
strcpy(BCX_ClassName,classname);
BCX_WndClass.lpfnWndProc=Form_WndProc;
BCX_WndClass.hInstance=BCX_hInstance;
BCX_WndClass.lpszClassName=classname;
RegisterClassEx(&BCX_WndClass);
}
void BCX_InitGUI (void)
{
INITCOMMONCONTROLSEX iccex;
if(BCX_GUI_Init)
{
return;
}
BCX_ScaleX=1;
BCX_ScaleY=1;
BCX_hInstance=GetModuleHandle(NULL);
BCX_hwndMDIClient=NULL;
BCX_WndClass.cbSize=sizeof(BCX_WndClass);
BCX_WndClass.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
BCX_WndClass.cbClsExtra=0;
BCX_WndClass.cbWndExtra=0;
BCX_WndClass.hIcon= LoadIcon(NULL,IDI_WINLOGO);;
BCX_WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
BCX_WndClass.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);
BCX_WndClass.lpszMenuName=NULL;
BCX_WndClass.hIconSm=NULL;
iccex.dwSize=sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC=ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES | ICC_TAB_CLASSES | ICC_UPDOWN_CLASS | ICC_PROGRESS_CLASS | ICC_USEREX_CLASSES | ICC_DATE_CLASSES;
InitCommonControlsEx(&iccex);
BCX_GUI_Init=TRUE;
}
// ************************************
// User Subs and Functions
// ************************************
void FormLoad (void)
{
int Style=WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN;
BCX_SHOW_COM_ERRORS(TRUE);
strcpy(Pth, join(2,sysdir(),"\\atl.dll"));
BCX_DynaCall("AtlAxWinInit",Pth,0);
Form=BCX_Form("Embedded Media Player",0,0,450,300,Style,WS_EX_CONTROLPARENT);
hWmp=BCX_Control("AtlAxWin",Form,"WMPlayer.OCX",IDC_CTRL,0,0,0,0);
Btn1=BCX_Button("Load",Form,IDC_Btn1);
BCX_DynaCall("AtlAxGetControl",Pth,2,hWmp, &pUnk);
BCX_DispatchObject(pUnk,&objWmp,TRUE);
Show(Form);
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
RECT rc;
while(1)
{
if(Msg==WM_SYSCOMMAND)
{
if((wParam&0xFFF0)==SC_CLOSE)
{
SendMessage(hWnd,(UINT)WM_DESTROY,(WPARAM)wParam,(LPARAM)lParam);
return 0;
}
break;
}
if(Msg==WM_COMMAND)
{
if(LOWORD(wParam)==IDC_Btn1)
{
static char Filename[2048];
memset(&Filename,0,sizeof(Filename));
static char Mask[2048];
memset(&Mask,0,sizeof(Mask));
strcpy(Mask,"Music Files|*.mid;*.mp3;*.wma;*.wav|");
strcpy(Filename,GetFileName("Open Media File",Mask,0,Form,0,"D:\\Music1\\MP3"));
if(Filename[0]>0)
{
LoadWmp(Filename);
*Filename=0;
}
}
break;
}
if(Msg==WM_SIZE)
{
if(wParam!=SIZE_MINIMIZED)
{
GetClientRect(hWnd, &rc);
MoveWindow(GetDlgItem(hWnd,IDC_CTRL),0,25,rc.right-rc.left,rc.bottom-rc.top-25,TRUE);
}
break;
}
if(Msg==WM_DESTROY)
{
BCX_SetNothing(&objWmp);
PostQuitMessage(0);
return 0;
}
break;
}
if(Msg==WM_DESTROY)
{
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,Msg,wParam,lParam);
}
void LoadWmp (char *Filename)
{
lstrcpy(bcx_last_com_error_indicator, _T("url"));
bcx_last_com_HRESULT = BCX_COM_AS2WS(Filename);
if (FAILED(bcx_last_com_HRESULT)) {
bcx_catch_hr_error_desc(bcx_last_com_HRESULT, _T("Build ParamList Failed! ANSI to Wide conversion failure!"));
} else {
bcx_static_param_list.pParams[0].vt = VT_BSTR;
bcx_static_param_list.pParams[0].bstrVal = SysAllocString(bcx_temp_wide_string_pointer);
}
bcx_param_list_index_p = 1;
if (!BCX_COM_ERROR) bcx_invoke_helper(&objWmp, L"url", DISPATCH_PROPERTYPUT, NULL);
}