/* $Header$ */
#include <extcomp.he>
#include <extfval.he>
#include <hwnd.he>
#include <gdi.he>
#include "generic2.he"

// Generic 2 is built on the foundations of the generic sample.
// It registers a single color property on in OMNIS that will appear in the property inspector,
// and can be access via the notation $cwind.$objs.yourobj.$mycolor, where yourobj is the name 
// of the object assigned to the generic2 component in window design mode.


// This is how we define the properties for our components.

// propery number
const qlong cMyColorProp = 1;	// rmmCW9

// This table will go back to OMNIS

// some of the property parts below are better expained in other external
// components such as the calendar example.
ECOproperty MyProperties[] =
{ 
//    propid				resourceid,   datatype,			propflags						propFlags2, 		enumStart, 		enumEnd
			cMyColorProp, 4000, 				fftInteger, 	EXTD_FLAG_PWINDCOL, 0, 							0, 						0
};


// Your generic object constructor
tqfGenericObject::tqfGenericObject( HWND pFieldHWnd )
{
	mHWnd = pFieldHWnd;
	mMyColor = GDI_COLOR_WINDOW;		// set default values
}

// Generic destruction
tqfGenericObject::~tqfGenericObject()
{
	// Insert any memory deletion code or general cleanup code
}

// You need to paint your control
qbool tqfGenericObject::paint()
{
	WNDpaintStruct paintStruct;
	WNDbeginPaint( mHWnd, &paintStruct );
	// get the client rect for our component
	qrect cRect; 
	WNDgetClientRect( mHWnd, &cRect );
	// get a solid brush from the stock - stock brushes to not need to be deleted
	HBRUSH brush = GDIgetStockBrush	( BLACK_BRUSH );
	// set the text color ( fill color for a solid brush ) based on our objects color
 	GDIsetTextColor( paintStruct.hdc, mMyColor );
 	// and fill our object
	GDIfillRect( paintStruct.hdc, &cRect, brush );
	// finished

	// If in design mode, then call drawNumber & drawMultiKnobs to draw design
	// numbers and multiknobs, if required.
	if ( ECOisDesign(mHWnd) )
	{
		ECOdrawNumber(mHWnd,paintStruct.hdc);
		ECOdrawMultiKnobs(mHWnd,paintStruct.hdc);
	}

	WNDendPaint( mHWnd, &paintStruct );	
	return qtrue;
}

// This function handles our property setting,getting and canassign query.
qlong tqfGenericObject::attributeSupport( LPARAM pMessage, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci )
{
	switch( pMessage )
	{ 
		case ECM_PROPERTYCANASSIGN: 
		{
			// as we only have one property, and it is assignable, return 1L;
			return 1L;		
		}
		case ECM_SETPROPERTY: 
		{
			// get the externals parameter
			EXTParamInfo* param = ECOfindParamNum( eci, 1 );
			if ( param )
			{                             
				// get the fldval from the parameter.
				EXTfldval fval( (qfldval)param->mData );
				// fldvals are containers that store data. All values in and out of OMNIS are passes in fldvals.
				// switch on property id
				switch( ECOgetId(eci) )
				{  
					// we are setting our color property
					case cMyColorProp:
					{
						// as our property is a color property - as set in our property table
						// we can assign the long value stored in the fldval to our color data member.
						mMyColor = (qcol)fval.getLong();						                                
						// qcol is an OMNIS RGB value.
						WNDinvalidateRect( mHWnd, NULL );
						// mark our window as needing a repaint, due to the color changing
						break;
					} 
				}
			}   
			return 1L;
		}
		case ECM_GETPROPERTY: 
		{
			EXTfldval fval;
			// switch on property id
			switch( ECOgetId(eci) )
			{         
				// OMNIS wants to know our color property value
				case cMyColorProp:
				{
					// send back the current value of our color in the fldval container
					fval.setLong( (qlong)mMyColor );                                              
					break;
				}
			}
			// to send it back, we add a parameter which OMNIS will check on return.
			ECOaddParam(eci,&fval);
			return 1L;
		}             
	}
	return 0L;		// no property found or message was wrong
}


// Component library entry point (name as declared in resource 31000 )
extern "C" LRESULT OMNISWNDPROC GenericWndProc(HWND hwnd, UINT Msg,WPARAM wParam,LPARAM lParam,EXTCompInfo* eci)
{
	 // Initialize callback tables - THIS MUST BE DONE
   ECOsetupCallbacks(hwnd, eci);		
	 switch (Msg)
	 {
			// WM_PAINT - standard paint message
			case WM_PAINT:
			{
				// First find the object in the libraries chain of objects
				tqfGenericObject* object = (tqfGenericObject*)ECOfindObject( eci, hwnd );
				// and if its good, call the paint function
				if ( NULL!=object && object->paint() )
					return qtrue;
				break;
			}  
			
			// ECM_OBJCONSTRUCT - this is a message to create a new object
			case ECM_OBJCONSTRUCT:				
			{
				// Allocate a new object
				tqfGenericObject* object = new tqfGenericObject( hwnd );
				// and insert into a chain of objects. The OMNIS library will maintain this chain
				ECOinsertObject( eci, hwnd, (void*)object );
				return qtrue;
			}    
			
			// ECM_OBJDESTRUCT - this is a message to inform you to delete the object
			case ECM_OBJDESTRUCT:					
			{
				// First find the object in the libraries chain of objects, 
				// this call if ok also removes the object from the chain.
				tqfGenericObject* object = (tqfGenericObject*)ECOremoveObject( eci, hwnd );
				if ( NULL!=object )
				{
					// Now you can delete the object you previous allocated
					// Note: The hwnd passed on ECM_OBJCONSTRUCT should not be deleted, as
					// it was created and will be destroyed by OMNIS
					delete object;
				}
				return qtrue;
			}
	 		
	 		// ECM_CONNECT - this message is sent once per OMNIS session and should not be confused 
	 		// with ECM_OBJCONSTRUCT which is sent once per object. ECM_CONNECT can be used if load other libraries
	 		// once or other general global actions that need to be done only once.
	 		//
	 		// For most components this can be removed - see other BLYTH component examples
	 		case ECM_CONNECT:
      {
        return ECOmakeConnectFlags(EXT_FLAG_LOADED); // Return external flags
      } 
      
	 		// ECM_DISCONNECT - this message is sent only once when the OMNIS session is ending and should not be confused
	 		// with ECM_OBJDESTRUCT which is sent once per object. ECM_DISCONNECT can be used to free other libraries
	 		// loaded on ECM_CONNECT or other general global actions that need to be done only once.
	 		// 
	 		// For most components this can be removed - see other BLYTH component examples
      case ECM_DISCONNECT:
      { 
        return qtrue;
      }

      // ECM_GETCOMPLIBINFO - this is sent by OMNIS to find out the name of the library, and
      // the number of components this library supports
      case ECM_GETCOMPLIBINFO:
      {
      	return ECOreturnCompInfo( gInstLib, eci, LIB_RES_NAME, OBJECT_COUNT );
      }

      // ECM_GETCOMPICON - this is sent by OMNIS to get an icon for the OMNIS component store and
      // external component browser. You need to always supply an icon in your resource file.
			case ECM_GETCOMPICON:
			{
				// OMNIS will call you once per component for an icon.
				// GENERIC_ICON is defined in the header and included in the resource file
				if ( eci->mCompId==OBJECT_ID1 ) return ECOreturnIcon( gInstLib, eci, GENERIC_ICON );
				return qfalse;
			}

			// ECM_GETCOMPID - this message is sent by OMNIS to get information about each component in this library
			// wParam is a number from 1 to the number of components return on the ECM_GETCOMPLIBINFO message.
			//
			// For each call you should return the internal object ID and the type of object it is.
			// The object id will be used for other calls such as ECM_GETCOMPICON 
			// 
			// The object type is for example : cObjType_Basic 		- a basic window object or 
			//																	cRepObjType_Basic	- a basic report object.
			// 																	There are others 	- see BLYTH examples and headers
			case ECM_GETCOMPID:
			{
				if ( wParam==1 )
					return ECOreturnCompID( gInstLib, eci, OBJECT_ID1, cObjType_Basic );
				return 0L;
			}

      // ECM_CUSTOMTABNAME - as we now support properties, we have a tab in the propery inspector.
      // If we do not handle this message i.e. remove the ECM_CUSTOMTABNAME
      // case, the tab name in the property inspector defaults to 'Custom'. The code shown here will
      // return a name for the tab
      //
      // Here we are tell OMNIS to use our resource 3000
			case ECM_CUSTOMTABNAME:
			{
				ECOsetCustomTabName( gInstLib, eci, 3000 );
				return 1L;
			}

			// ECM_GETPROPNAME - this messasge is send by OMNIS to get your properties.
			// ECOreturnProperties takes the table of properties at the top of this file and returns
			// them to OMNIS. The last parameter is the number of properties in your table
			case ECM_GETPROPNAME:
			{
				return ECOreturnProperties( gInstLib, eci, &MyProperties[0], 1 );
			}   
			
			// The following messages will be sent now we support properties. OMNIS has three modes where
			// properties are concerned. The modes are canAssign, set and get value. These map onto OMNIS notation,
			// and are sent if our object is being displayed in the property inspector.
			case ECM_PROPERTYCANASSIGN:  	
			case ECM_SETPROPERTY: 				
			case ECM_GETPROPERTY:					
			{
  			// First find the object in the libraries chain of objects
				tqfGenericObject* object = (tqfGenericObject*)ECOfindObject( eci, hwnd );
				if ( object )
					// if we found the object, call a function to handle the message
					return object->attributeSupport( Msg, wParam, lParam, eci );
				return 0L;
			}
                                                                            

	 }

	 // As a final result this must ALWAYS be called. It handles all other messages that this component
	 // decides to ignore.
	 return WNDdefWindowProc(hwnd,Msg,wParam,lParam,eci);
}

	
