Microsoft DirectX 8.1 (C++) |
To customize the setup process, first create a callback function that conforms to the DirectXSetupCallbackFunction prototype, as in the following declaration:
DWORD WINAPI DirectXSetupCallbackFunction( DWORD dwReason, DWORD dwMsgType, LPSTR szMessage, LPSTR szName, void *pInfo);
In this example, adapted from the Dinstall Sample application, the name of the function is the same as that of the prototype, but this is optional. The parameter names differ slightly from those in the prototype declared in the Dsetup.h header file and are used throughout the following discussion.
The dwReason parameter indicates why the callback function has been called. The possible values are listed and explained in the reference for DirectXSetupCallbackFunction.
The dwMsgType parameter receives flags equivalent to those that Microsoft® DirectSetup would, by default, pass to MessageBox, such as those controlling which buttons and icons are displayed. Of special interest are the button flags, which you use to determine what return values are expected. If this value is 0, the event never requires user input, and DirectSetup normally displays a status message.
The szMessage parameter receives the same text that DirectSetup would otherwise pass to the status dialog box or to MessageBox.
When a driver is a candidate for upgrading, its name is passed in the szName parameter, and pInfo points to information about how the upgrade is to be handled—for example, whether DirectSetup recommends that the old driver be kept or upgraded. For more information, see Creating a DirectSetup Callback Function.
The way your callback function interprets the parameters is entirely up to you. Typically, you would choose which messages to display (based on dwReason) and when to present the user with alternatives, and you would modify the interface accordingly.
The value returned by your callback function must conform to the following rules:
To determine the appropriate return value in the second case, test dwMsgType for the buttons that would normally have been put in a message box. The following example, from the GetReply function in Dinstall, shows how this is done:
/* The global g_wReply identifies the custom dialog button that has been selected by the user. */ switch (dwMsgType & 0x0000000F) { / * There would normally have been an OK and a Cancel button. IDBUT1 is equivalent to the OK button. If the user did not choose that, it was a Cancel. */ case MB_OKCANCEL: wDefaultButton = (g_wReply == IDBUT1) ? IDOK : IDCANCEL; break; / * And so on with the other button combinations. */ case MB_OK: wDefaultButton = IDOK; break; case MB_RETRYCANCEL: wDefaultButton = (g_wReply == IDBUT1) ? IDRETRY : IDCANCEL; break; case MB_ABORTRETRYIGNORE: if (g_wReply == IDBUT1) wDefaultButton = IDABORT; else if (g_wReply == IDBUT2) wDefaultButton = IDRETRY; else wDefaultButton = IDIGNORE; break; case MB_YESNOCANCEL: if (g_wReply == IDBUT1) wDefaultButton = IDYES; else if (g_wReply == IDBUT2) wDefaultButton = IDNO; else wDefaultButton = IDCANCEL; break; case MB_YESNO: wDefaultButton = (g_wReply == IDBUT1) ? IDYES : IDNO; break; default: wDefaultButton = IDOK; }
This routine translates button clicks from the custom interface into the equivalent button identifiers in the standard dialog box that DirectSetup would otherwise create. The wDefaultButton variable is set to the identifier of the equivalent standard dialog box button, and this value is ultimately returned from the callback function.
You do not necessarily have to give the user a choice, even when dwMsgType is nonzero. You might decide, for example, to upgrade drivers automatically even if DirectSetup would normally ask for confirmation from the user. The Dinstall sample does this when the user has asked to see only problem messages and the driver upgrade is considered safe, as follows:
case DSETUP_CB_UPGRADE_SAFE: switch (dwMsgType & 0x0000000F) { case MB_YESNO: case MB_YESNOCANCEL: return IDYES; case MB_OKCANCEL: case MB_OK: default: return IDOK; } break;
The callback function returns either IDYES or IDOK, depending on which button would have represented a positive choice in a dialog box asking the user whether or not the upgrade should proceed.
Before calling DirectXSetup, notify DirectSetup that you want to use a callback by calling the DirectXSetupSetCallback function, passing a pointer to the callback as a parameter. The following example shows how this is done:
DirectXSetupSetCallback( (DSETUP_CALLBACK) DirectXSetupCallbackFunction);
When the application-defined callback function DirectXSetupCallbackFunction is called by the DirectXSetup function, it is passed a parameter that contains the reason that the callback function was invoked. If the reason is DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE, the pInfo parameter points to a DSETUP_CB_UPGRADEINFO structure containing flags that summarize the DirectXSetup function recommendations on how to perform the upgrade of Microsoft® DirectX® components and drivers. The structure member containing the flags is called UpgradeFlags.
The flags fall into the following categories:
DSETUP_CB_UPGRADE_FORCE
DSETUP_CB_UPGRADE_KEEP
DSETUP_CB_UPGRADE_SAFE
DSETUP_CB_UPGRADE_UNKNOWN
DSETUP_CB_UPGRADE_CANTBACKUP
DSETUP_CB_UPGRADE_HASWARNINGS
DSETUP_CB_UPGRADE_DEVICE_ACTIVE
DSETUP_CB_UPGRADE_DISPLAY
DSETUP_CB_UPGRADE_MEDIA
In summary: every time the Reason parameter has the value DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE, the UpgradeFlags member of the structure pointed to by pInfo contains one Primary Upgrade Flag, zero or more Secondary Upgrade Flags, zero or one Device Active Flag, and one Device Class Flag.
If the UpgradeFlags member is set to DSETUP_CB_UPGRADE_KEEP, the DirectX component or device driver cannot be upgraded without causing Microsoft® Windows® to cease functioning properly. The DirectXSetup function does not perform an upgrade on the component or driver.
A value of DSETUP_CB_UPGRADE_FORCE in UpgradeFlags means that the component or driver must be upgraded for Windows to function properly. The DirectXSetup function upgrades the driver or component. It is possible that the upgrade might adversely affect some programs on the system. When the DirectXSetup function detects this condition, the UpgradeFlags member is set to (DSETUP_CB_UPGRADE_FORCE | DSETUP_CB_UPGRADE_HAS_WARNINGS). When this occurs, the DirectXSetup function performs the upgrade but issues a warning to the user.
Components and drivers are considered safe for upgrade if they do not adversely affect the operation of Windows when they are installed. In this case, the UpgradeFlags member is set to DSETUP_CB_UPGRADE_SAFE. It is possible that the upgrade can be safe for Windows but still cause problems for programs installed on the system. When DirectXSetup detects this condition, the UpgradeFlags member contains the value (DSETUP_CB_UPGRADE_SAFE | DSETUP_CB_UPGRADE_HAS_WARNINGS). If this condition occurs, the default action for the DirectXSetup function is not to perform the upgrade.
The application-defined function DirectXSetupCallbackFunction can override some of the default behaviors of the DirectXSetup function through its return value.
For example, the default behavior for DirectXSetup is not to install a component if the upgrade type in the structure pointed to by the pInfo parameter is set to (DSETUP_CB_UPGRADE_SAFE | DSETUP_CB_UPGRADE_HAS_WARNINGS). In this case, the MsgType parameter of the callback function is set to (MB_YESNO | MB_DEFBUTTON2). Without a callback function, DirectSetup would present the user with a dialog box whose default button was No. If the callback function does not seek user input but accepts the default, it returns IDNO. To override the default, the callback function returns IDYES. If it does override the default, the DirectXSetup function notifies the user.