DJP can be applied to two different scenarios. The first scenario applies to applications that query or modify DJP_ITEMs; these events are usually performed asynchronously. In this scenario, the application opens up a OD_INFO DC, sets up its job property information, and then turns around and opens up a OD_QUEUED DC to print. Setting or querying data uses only the printer property information in the device context (DC) and does not affect the print job in any other way.
In the other scenario for using DJPs, the DC characteristics provided in the DevOpenDC information are changed. This is either accomplished at the start of a document with GreEscape DEVESC_STARTDOC_WPROP or at the beginning of a new page with GreEscape DEVESC_NEWFRAME_WPROP. In this scenario, the application must query the printer driver again and again for DevQueryCaps, DevQueryHardcopyCaps, list of devices fonts, and any other DC information. The driver must use the same code path that DevOpenDC uses (FillLogicalDeviceBlock, FillPhysicalDeviceBlock, EnableDeviceContext, CompleteOpenDC). After the printer driver resets all of its information, it calls the new Gre call, GreResetDC2 (hdc, 0). This call instructs the graphics engine to query the printer driver again and recalculate its internal state data. This has the side effect of performing a ResetDC.
The DJP_ITEM is the new structure that contains DJP information. The structure DJP_ITEM is used by both applications and device drivers. The format of the structure follows.
/* Dynamic Job Property Item */ typedef struct _djpItem { ULONG cb; // size of this structure ULONG ulProperty; // Type of Property LONG iType; // INPUT : DJP_ALL - Returns all possible // values (placed at ulValue). // DJP_ALL is not valid if // setting properties. // // DJP_CURRENT - returns current // value // // OUTPUT: DJP_ERROR_XXX if there was an // error ULONG ulNumReturned; // How many elements are returned in // ulValue on a query. This should be // 1 for DEVESC_SETJOBPROPERTIES. ULONG ulValue; // The start of the types supported by // this property. } DJP_ITEM, *PDJP_ITEM;
Because the individual properties have variable lengths, the properties are broken up into two different categories: simple and complex. The names of these properties are identified by either "_Sx_" for simple or "_Cx_" for complex. In addition, they are sorted into different subcategories such as "_xJ_" for job properties or "_xP_" for printer properties. Simple types are ULONG sized. This is the minimum size for the data. The complex types can be larger and have structures associated with them. All property types, simple and complex, are associated with a type; for example, DJP_SJ_ORIENTATION is a simple type of type PDJPT_ORIENTATION. The values for DJP_SJ_ORIENTATION can be DJP_ORI_PORTRAIT or DJP_ORI_LANDSCAPE. DJP_CJ_RESOLUTION is a complex type of type PDJPT_RESOLUTION; this is a structure composed of two members: x and y resolutions.
The following helper macros have been created to work with DJP_ITEMs: DJP_NEXT_STRUCTP(), DJP_ELEMENTP(), and DJP_SET_ELEMENT().
DJP_NEXT_STRUCTP():
// Bump to the next DJP_ITEM structure pDJP = DJP_NEXT_STRUCTP (pDJP);DJP_ELEMENTP():
// Get the pointer to the resolution value PDJPT_RESOLUTION pElm; pElm = DJP_ELEMENTP (pDJP, DJPT_RESOLUTION);DJP_SET_ELEMENT():
// Structure (from header file DJP.H) typedef struct _djpResolution { USHORT usXResolution; // X resolution (in dots per inch) USHORT usYResolution; // Y resolution (in dots per inch) } DJPT_RESOLUTION, *PDJPT_RESOLUTION; // Set the # of bytes in the structure pDJP->cb = DJP_HEADER_SIZE + sizeof (DJPT_RESOLUTION); // Set the current property and type pDJP->ulProperty = DJP_CJ_RESOLUTION; pDJP->iType = DJP_CURRENT; // Set up the resolution structure djpResolution.usXResolution = 720; djpResolution.usYResolution = 720; // Put the data into the DJP_ITEM structure. DJP_SET_ELEMENT (*pDJP, DJPT_RESOLUTION, djpResolution); To set a simple type such as the color mode use: pDJP->cb = sizeof (DJP_ITEM); pDJP->ulProperty = DJP_SJ_COLOR; pDJP->lType = DJP_CURRENT; pDJP->ulValue = DJP_CLR_COLOR; /* Move to next element. Either way, you use the same macro. ** Dependent on cb having the correct value. */ pDJP = DJP_NEXT_STRUCTP (pDJP);
The parts of the DJP property defines identified by _Sx_ and _Cx_ indicate whether the specified item is a simple item or a complex item. This information helps you to determine the correct strategy for setting the structure size and the data value.