The CAR sample Workplace Shell object in the Toolkit can be used to illustrate the requirements for defining Details data for a class of objects. CAR can provide Details data for CAR objects by:
/* CARDETAILS: Structure used for Details view */ typedef struct _CARDETAILS { PSZ pszMake; /* Manufacturer */ PSZ pszModel; /* Model */ PSZ pszColor; /* Color of car */ CDATE cdateSale; /* Date of sale */ ULONG ulPrice; /* Price in dollars */ } CARDETAILS; typedef CARDETAILS *PCARDETAILS;
Note: Title and Icon details are defined for CAR objects by its ancestor class WPObject. This means that the CLASSFIELDINFO data structures for Title and Icon details are defined and initialized in the WPObject class definition.
#define NUM_CAR_FIELDS 5 CLASSFIELDINFO fieldinfo[NUM_CAR_FIELDS]; PSZ pszCarColTitles[] = { "Make", /* Details column 1 */ "Model", /* Details column 2 */ "Color", /* Details column 3 */ "Sale date", /* Details column 4 */ "Price ($)" /* Details column 5 */ }; . . . /****************************************************************/ /* Method: wpclsInitData */ /* Purpose: Initialize the Details data */ /****************************************************************/ SOM_Scope void SOMLINK carM_wpclsInitData(M_Car *somSelf) { USHORT rc, i; PCLASSFIELDINFO pCFI; /* M_CarData *somThis = M_CarGetData(somSelf); */ M_CarMethodDebug("M_Car","carM_wpclsInitData"); /* Call the parent class method first */ parent_wpclsInitData(somSelf); /* Get the class title */ if (!WinLoadString(WinQueryAnchorBlock(HWND_DESKTOP), _clsQueryModuleHandle(somSelf), ID_TITLE, sizeof(szCarClassTitle), szCarClassTitle)) /* If the load string has failed, use the parent's string */ strcpy(szCarClassTitle, parent_wpclsQueryTitle(somSelf)); /* Initialize everything needed for the CLASSFIELDINFO */ /* data structure for the CAR object class */ for (i=0,pCFI=fieldinfo;i<NUM_CAR_FIELDS;i++,pCFI++) { /* Memset the structure to zero's */ memset((PCH)pCFI,0,sizeof(CLASSFIELDINFO)); pCFI->cb = sizeof(CLASSFIELDINFO); pCFI->flData = CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY; pCFI->flTitle = CFA_CENTER | CFA_SEPARATOR | CFA_HORZSEPARATOR | CFA_STRING | CFA_FITITLEREADONLY; pCFI->pNextFieldInfo = pCFI + 1; /* Point to the next CLASSFIELDINFO */ pCFI->pTitleData = (PVOID) apszCarColTitles[i]; pCFI->flCompare = COMPARE_SUPPORTED | SORTBY_SUPPORTED; switch (i) { case INDEX_MAKE: pCFI->flData |= CFA_STRING; pCFI->offFieldData = (ULONG)(FIELDOFFSET(CARDETAILS,pszMake)); pCFI->ulLenFieldData = sizeof(PSZ); pCFI->DefaultComparison = CMP_EQUAL; break; case INDEX_MODEL: pCFI->flData |= CFA_STRING; pCFI->offFieldData = (ULONG)(FIELDOFFSET(CARDETAILS,pszModel)); pCFI->ulLenFieldData = sizeof(PSZ); pCFI->DefaultComparison = CMP_EQUAL; break; case INDEX_COLOR: pCFI->flData |= CFA_STRING; pCFI->offFieldData = (ULONG)(FIELDOFFSET(CARDETAILS,pszColor)); pCFI->ulLenFieldData = sizeof(PSZ); pCFI->DefaultComparison = CMP_EQUAL; break; case INDEX_SALE_DATE: pCFI->flData |= CFA_DATE; pCFI->offFieldData = (ULONG)(FIELDOFFSET(CARDETAILS,cdateSale)); pCFI->ulLenFieldData = sizeof(CDATE); pCFI->ulLenCompareValue = sizeof(CDATE); pCFI->DefaultComparison = CMP_GREATER; break; case INDEX_PRICE: pCFI->flData |= CFA_ULONG; pCFI->offFieldData = (ULONG)(FIELDOFFSET(CARDETAILS,ulPrice)); pCFI->ulLenFieldData = sizeof(ULONG); pCFI->ulLenCompareValue = sizeof(ULONG); pCFI->DefaultComparison = CMP_GREATER; break; } /* End switch(i) */ } /* End for (i=0,pCFI=fieldinfo;i<NUM_CAR_FIELDS;i++,pCFI++) */ /* Terminate linked list */ fieldinfo[NUM_CAR_FIELDS-1].pNextFieldInfo = NULL; } /* End carM_ wpclsInitData() */
/****************************************************************/ /* Method: wpclsQueryDetailsInfo */ /* Appends the CAR specific chain of FIELDINFO data structure */ /* describing the Details data of this object to */ /* *ppClassFieldInfo, if ppClassFieldInfo is non-NULL. */ /* In this case, it also sets *ppClasssFieldInfo to the head */ /* of the linked list. */ /* */ /* Adds the number of bytes required by the Details data for */ /* car to *pSize, if pSize is non-NULL. */ /* */ /* Add Details data for this object. */ /****************************************************************/ SOM_Scope ULONG SOMLINK redcarM_wpclsQueryDetailsInfo(M_Car *somself, PCLASSFIELDINFO *ppClassFieldInfo, PULONG pSize) { ULONG cParentColumns; PCLASSFIELDINFO pCFI; ULONG i; /* M_CarData *somThis = M_CarGetData(somself); */ M_CarMethodDebug("M_Car","carM_wpclsQueryDetailsInfo"); /* Always call the parent method first to retrieve the number */ /* of Details columns and parent's data already defined in */ /* the Details buffer. */ cParentColumns = parent_wpclsQueryDetailsInfo(somself,ppClassFieldInfo,pSize); /* If pSize is non-NULL, we must add the size of our */ /* Details column data structure. */ if (pSize) *pSize += sizeof(CARDETAILS); /* Adjust size */ /*******************************************************************/ /* If the request was for the chained FIELDINFO data structures */ /* (ppClassFieldInfo is non-NULL), link them in. */ /* Eventually the chain will look like this: */ /* */ /* Grandparent - Parent - Me - Child - Grandchild. */ /* */ /* Get the pointer to the beginning of the chain. */ /* If the beginning of the chain is 0, assign the address */ /* of the first CLASSFIELDINFO structure to *ppClassFieldInfo. */ /* Otherwise, *ppClassFieldInfo points to the first column */ /* description in the chain. The chain is examined and */ /* the CLASSFIELDINFO data structure is linked to the end of it. */ /*******************************************************************/ if (ppClassFieldInfo) { /* Find the last link in the chain; then link the CLASSFIELDINFO */ /* data structures to the chain. */ if (*ppClassFieldInfo) { pCFI = *ppClassFieldInfo; for (i=0;i<cParentColumns;i++) pCFI = (pCFI->pNextFieldInfo) ? pCFI->pNextFieldInfo : pCFI; pCFI->pNextFieldInfo = fieldinfo; } else *ppClassFieldInfo = fieldinfo; } return ((ULONG) (cParentColumns + NUM_CAR_FIELDS)); } /* End carM_wpclsQueryDetailsInfo() */4.
/* * Returns the car specific data for the Details view of this object. * Sets the pointer (*ppDetailsData) to the beginning of the buffer * into which the data is written. */ SOM_Scope ULONG SOMLINK car_wpQueryDetailsData(Car *somSelf, PVOID *ppDetailsData, PULONG pcp) { PCARDETAILS pCarDetails; PBYTE pSize; CarData *somThis = CarGetData(somSelf); CarMethodDebug("Car","car_wpQueryDetailsData"); parent_wpQueryDetailsData(somSelf,ppDetailsData,pcp); if (ppDetailsData) /* Query data */ { pCarDetails = (PCARDETAILS) *ppDetailsData; pCarDetails->pszMake = "Toyota"; /* Manufacturer */ pCarDetails->pszModel = "Camry"; /* Model name */ pCarDetails->pszColor = "BLUE"; /* Color of the car */ pCarDetails->cdateSale.day = 24; /* Date of sale */ pCarDetails->cdateSale.month = 12; pCarDetails->cdateSale.year = 91; pCarDetails->ulPrice = 14000; /* Price in dollars */ /* Point to buffer location after the Details data */ *ppDetailsData = ((PBYTE) (*ppDetailsData)) + sizeof(*pCarDetails); } /* End if (ppDetailsData) */ else /* Query size of data */ { /* Caller is querying the buffer size */ *pcp += sizeof(*pCarDetails); } return(TRUE); } /* End car_wpQueryDetailsData() */