|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionLateLoad is a series of macros for managing The attached sample uses LoadLoad to access the BackgroundI was getting sick & tired of constantly rewriting simple Unfortunately, it didn't come with full source :( So LateLoad was created! Using the codeCouldn't be easier. You may notice more than a passing resemblance to various The LateLoad macros create a class derived from The following sample will create the class #include "LateLoad.h" LATELOAD_BEGIN_CLASS(CMsImg32Wrapper,msimg32,FALSE,FALSE) LATELOAD_FUNC_6(FALSE,BOOL,STDAPICALLTYPE,GradientFill,HDC,PTRIVERTEX, ULONG,PVOID,ULONG,ULONG) LATELOAD_FUNC_0(FALSE,BOOL,STDAPICALLTYPE,BadFunctionName) LATELOAD_END_CLASS() The generated class will be functionally equivalent to: class CMsImg32Wrapper : public CLateLoadBase { public: CMsImg32Wrapper(); BOOL Is_GradientFill(); BOOL STDAPICALLTYPE GradientFill(HDC a,PTRIVERTEX b,ULONG c, PVOID d, ULONG e,ULONG f); BOOL Is_BadFunctionName(); BOOL STDAPICALLTYPE BadFunctionName(); }; With the above code, you can instantiate Since So - what's going on here?Macros are the key.
// // Start, Declares the name of the class // // ClassName = the name of the class // ModuleName = the DLL name // bLoadDllNow = if true, the DLL will be loaded in the constructor. // if false, it will ONLY be loaded when any bound function // is first used // bManaged = if true, FreeLibrary will be called in the destructor // #define LATELOAD_BEGIN_CLASS(ClassName,ModuleName,bLoadDllNow,bManaged) \ class ClassName : public CLateLoadBase \ { \ public:\ ClassName()\ {\ /*Automagicaly blank out all the function pointers and */ \ /*ImportedProcState member vars that will be declared */ \ /*in following LATELOAD_FUNC_* declarations, very handy. */ \ ZeroMemory(static_cast<ClassName*>(this),sizeof(ClassName)); \ m_bManaged = bManaged; \ /*and load the DLL*/ \ dll_LoadLibrary(#ModuleName,bLoadDllNow); \ } // // End of the class // #define LATELOAD_END_CLASS() }; Not much to it, blanks out ALL the member variables that we don't know about yet (function pointers & state variables) but will be declared in the The
// // Function Declaration, Zero Parameters, returns a value // // ErrorResult, Default return value if the function could not be loaded & // it is called anyways // ReturnType, type of value that the function returns // CallingConv, Calling convention of the function // FuncName, Name of the function // // A function prototype that looked like... // typedef BOOL (CALLBACK* SOMETHING)(); // or // BOOL CALLBACK Something(); // // Would be changed to... // LATELOAD_FUNC_0(0,BOOL,CALLBACK,Something) // // If "Something" could not be loaded, and it was called - it would return 0 // #define LATELOAD_FUNC_0(ErrorResult,ReturnType,CallingConv,FuncName) \ protected: \ typedef ReturnType(CallingConv * TYPE_##FuncName)(); \ TYPE_##FuncName m_pf##FuncName; \ ImportedProcState m_ips##FuncName;\ public: \ BOOL Is_##FuncName() \ { \ if(ipsUnknown == m_ips##FuncName) \ m_pf##FuncName = (TYPE_##FuncName)dll_GetProcAddress(#FuncName, \ m_ips##FuncName); \ return(ipsAvailable == m_ips##FuncName); \ } \ ReturnType FuncName() \ {\ if( !Is_##FuncName() ) \ return ErrorResult; \ return m_pf##FuncName(); \ } Optionally, there are also In UseFrom the demo: //--------------------- // In LateLoadDemo.h //--------------------- #include "LateLoad.h" LATELOAD_BEGIN_CLASS(CMsImg32Wrapper,msimg32,FALSE,FALSE) LATELOAD_FUNC_6(FALSE,BOOL,STDAPICALLTYPE,GradientFill,HDC, PTRIVERTEX,ULONG,PVOID,ULONG,ULONG) LATELOAD_FUNC_0(FALSE,BOOL,STDAPICALLTYPE,BadFunctionName) LATELOAD_END_CLASS() class CLateLoadDemoDlg : public CDialog { .... CMsImg32Wrapper m_msimg32; .... } //--------------------- // In LateLoadDemo.cpp //--------------------- // Attempt to call a non-existant function in MSIMG32.DLL if( m_msimg32.BadFunctionName() ) { // This will never return true because the default return value in the // LATELOAD_FUNC_ for this non-existant funct if FALSE // m_msimg32.Is_BadFunctionName() would have returned false } void CLateLoadDemoDlg::OnPaint() { ... CPaintDC dc(this); BOOL bPaintedGradient = FALSE; TRIVERTEX vert[2]; GRADIENT_RECT gRect; vert[0].x = m_rcGradient.left; vert[0].y = m_rcGradient.top; vert[0].Red = MAKEWORD(0,GetRValue(m_clrStart)); vert[0].Green = MAKEWORD(0,GetGValue(m_clrStart)); vert[0].Blue = MAKEWORD(0,GetBValue(m_clrStart)); vert[0].Alpha = 0x0000; vert[1].x = m_rcGradient.right; vert[1].y = m_rcGradient.bottom; vert[1].Red = MAKEWORD(0,GetRValue(m_clrEnd)); vert[1].Green = MAKEWORD(0,GetGValue(m_clrEnd)); vert[1].Blue = MAKEWORD(0,GetBValue(m_clrEnd)); vert[1].Alpha = 0x0000; gRect.UpperLeft = 0; gRect.LowerRight = 1; #if 0 //Using this will require explicit linking to msimg32.lib bPaintedGradient = ::GradientFill(dc.GetSafeHdc(),vert,2,&gRect,1, m_bHorizontal?GRADIENT_FILL_RECT_H:GRADIENT_FILL_RECT_V); #else bPaintedGradient = m_msimg32.GradientFill(dc.GetSafeHdc(),vert,2, &gRect,1,m_bHorizontal?GRADIENT_FILL_RECT_H:GRADIENT_FILL_RECT_V); #endif ... } Points of InterestDid you know that this is my first CodeProject code submission? Be kind. History2004.Mar.01 - Initial release.
|
||||||||||||||||||||||