windows-nt/Source/XPSP1/NT/multimedia/directx/dinput/dx7/diquick/diquick.c
2020-09-26 16:20:57 +08:00

881 lines
25 KiB
C

/*****************************************************************************
*
* diquick.c
*
* DirectInput quick test
*
*****************************************************************************/
#include "diquick.h"
/*****************************************************************************
*
* GetCheckedRadioButton
*
* Return the ID of the one that is checked.
*
* If nothing is checked, we return idFirst.
*
*****************************************************************************/
UINT EXTERNAL
GetCheckedRadioButton(HWND hdlg, UINT idFirst, UINT idLast)
{
for (; idFirst < idLast; idLast--) {
if (IsDlgButtonChecked(hdlg, idLast)) {
return idLast;
}
}
return idLast;
}
/*****************************************************************************
*
* MessageBoxV
*
* Format a message and display a message box.
*
*****************************************************************************/
int __cdecl
MessageBoxV(HWND hdlg, UINT ids, ...)
{
va_list ap;
TCHAR tszStr[256] = {0};
TCHAR tszBuf[1024] = {0};
LoadString(g_hinst, ids, tszStr, cA(tszStr));
va_start(ap, ids);
#ifdef WIN95
{
char *psz = NULL;
char szDfs[1024]={0};
strcpy(szDfs,tszStr); // make a local copy of format string
while (psz = strstr(szDfs,"%p")) // find each %p
*(psz+1) = 'x'; // replace each %p with %x
wvsprintf(tszBuf, szDfs, ap); // use the local format string
}
#else
{
wvsprintf(tszBuf, tszStr, ap);
}
#endif
va_end(ap);
return MessageBox(hdlg, tszBuf, TEXT("DirectInput QuickTest"), MB_OK);
}
/*****************************************************************************
*
* ThreadFailHres
*
* Tell the parent that a thread failed to start, and display
* an error message with an HRESULT code.
*
*****************************************************************************/
int EXTERNAL
ThreadFailHres(HWND hdlg, UINT ids, HRESULT hres)
{
SendNotifyMessage(hdlg, WM_THREADSTARTED, 0, 0);
SendNotifyMessage(hdlg, WM_CHILDEXIT, 0, 0);
return MessageBoxV(hdlg, ids, hres);
}
/*****************************************************************************
*
* RecalcCursor
*
* If the cursor is over the window, force a new WM_SETCUSOR.
*
*****************************************************************************/
void EXTERNAL
RecalcCursor(HWND hdlg)
{
POINT pt;
HWND hwnd;
GetCursorPos(&pt);
hwnd = WindowFromPoint(pt);
if( (hwnd != NULL) && (hwnd == hdlg || IsChild(hdlg, hwnd)) ) {
SetCursorPos(pt.x, pt.y);
}
}
/*****************************************************************************
*
* ModalVtbl
*
* Things that tell you about the modal gizmo.
*
*****************************************************************************/
typedef struct MODALVTBL {
BOOL (WINAPI *IsDialogMessage)(HWND, LPMSG);
BOOL (WINAPI *IsAlive)(HWND);
void (INTERNAL *SendIdle)(HWND);
} MODALVTBL, *PMODALVTBL;
/*****************************************************************************
*
* ModalLoop
*
* Spin waiting for the dialog box to die.
*
* WEIRDNESS! We send the WM_SELFENTERIDLE message to the dialog box
* rather than to the owner. This avoids inter-thread sendmessage goo.
*
* Don't re-post the quit message if we get one. The purpose of the
* quit message is to break the modal loop.
*
*****************************************************************************/
int EXTERNAL
ModalLoop(HWND hwndOwner, HWND hdlg, PMODALVTBL pvtbl)
{
if (hdlg) {
BOOL fSentIdle = 0;
while (pvtbl->IsAlive(hdlg)) {
MSG msg;
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
fSentIdle = 0;
if (msg.message == WM_QUIT) {
break;
}
if (!pvtbl->IsDialogMessage(hdlg, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else {
if (fSentIdle) {
WaitMessage();
} else {
fSentIdle = 1;
pvtbl->SendIdle(hdlg);
}
}
}
if (IsWindow(hdlg)) {
DestroyWindow(hdlg);
}
}
SendNotifyMessage(hwndOwner, WM_CHILDEXIT, 0, 0);
return 0;
}
/*****************************************************************************
*
* SendDlgIdle
*
* Send the fake idle message.
*
*****************************************************************************/
void INTERNAL
SendDlgIdle(HWND hdlg)
{
SendMessage(hdlg, WM_SELFENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hdlg);
}
/*****************************************************************************
*
* SemimodalDialogBoxParam
*
* Create a non-modal dialog box, then spin waiting for it to die.
*
*****************************************************************************/
#pragma BEGIN_CONST_DATA
MODALVTBL c_dlgvtbl = {
IsDialogMessage,
IsWindow,
SendDlgIdle,
};
#pragma END_CONST_DATA
int EXTERNAL
SemimodalDialogBoxParam(UINT idd, HWND hwndOwner, DLGPROC dp, LPARAM lp)
{
return ModalLoop(hwndOwner, CreateDialogParam(g_hinst,
(LPVOID)(UINT_PTR)idd, hwndOwner, dp, lp), &c_dlgvtbl);
}
/*****************************************************************************
*
* IsPrshtMessage
*
*****************************************************************************/
BOOL WINAPI
IsPrshtMessage(HWND hdlg, LPMSG pmsg)
{
return PropSheet_IsDialogMessage(hdlg, pmsg);
}
/*****************************************************************************
*
* IsPrshtAlive
*
*****************************************************************************/
BOOL WINAPI
IsPrshtAlive(HWND hdlg)
{
return (BOOL)(INT_PTR)PropSheet_GetCurrentPageHwnd(hdlg);
}
/*****************************************************************************
*
* SendPrshtIdle
*
* Send the fake idle message.
*
*****************************************************************************/
void INTERNAL
SendPrshtIdle(HWND hdlg)
{
hdlg = PropSheet_GetCurrentPageHwnd(hdlg);
SendDlgIdle(hdlg);
}
/*****************************************************************************
*
* SemimodalPropertySheet
*
* Create a non-modal property sheet, then spin waiting for it to die.
*
* We nuke the Cancel and Apply buttons, change OK to Close, and move
* the button into the corner.
*
*****************************************************************************/
#pragma BEGIN_CONST_DATA
MODALVTBL c_pshvtbl = {
IsPrshtMessage,
IsPrshtAlive,
SendPrshtIdle,
};
#pragma END_CONST_DATA
int EXTERNAL
SemimodalPropertySheet(HWND hwndOwner, LPPROPSHEETHEADER ppsh)
{
HWND hdlg = (HWND)PropertySheet(ppsh);
if ( hdlg && hdlg != (HWND)-1 ) {
RECT rcOk, rcCancel;
HWND hwnd;
PropSheet_CancelToClose(hdlg);
/* Slide the Close button to where the Cancel button is */
hwnd = GetDlgItem(hdlg, IDCANCEL);
GetWindowRect(hwnd, &rcCancel);
ShowWindow(hwnd, SW_HIDE);
hwnd = GetDlgItem(hdlg, IDOK);
GetWindowRect(hwnd, &rcOk);
rcOk.left += rcCancel.right - rcOk.right;
ScreenToClient(hdlg, (LPPOINT)&rcOk);
SetWindowPos(hwnd, 0, rcOk.left, rcOk.top, 0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
return ModalLoop(hwndOwner, hdlg, &c_pshvtbl);
} else {
return -1;
}
}
/*****************************************************************************
*
* CreateDI
*
* Create an IDirectInput interface in the appropriate manner.
*
*****************************************************************************/
#pragma BEGIN_CONST_DATA
/*
* This table must be in sync with the CDIFL_* values.
*/
const IID *c_rgiidDI[] = {
&IID_IDirectInputA, /* */
&IID_IDirectInputW, /* CDIFL_UNICODE */
&IID_IDirectInput2A, /* CDIFL_DI2 */
&IID_IDirectInput2W, /* CDIFL_UNICODE | CDIFL_DI2 */
};
#pragma END_CONST_DATA
STDMETHODIMP
CreateDI(BOOL fOle, UINT flCreate, PV ppvOut)
{
HRESULT hres;
if (fOle) {
const IID *piid = c_rgiidDI[flCreate];
hres = CoCreateInstance(&CLSID_DirectInput, 0, CLSCTX_INPROC_SERVER,
piid, ppvOut);
if (SUCCEEDED(hres)) {
LPDIRECTINPUT pdi = *(PPV)ppvOut;
hres = pdi->lpVtbl->Initialize(pdi, g_hinst, g_dwDIVer);
if (FAILED(hres)) {
pdi->lpVtbl->Release(pdi);
*(PPV)ppvOut = 0;
}
}
} else { /* Create via DI */
if (flCreate & CDIFL_UNICODE) {
hres = DirectInputCreateW(g_hinst, g_dwDIVer, ppvOut, 0);
} else {
hres = DirectInputCreateA(g_hinst, g_dwDIVer, ppvOut, 0);
}
/*
* If necessary, QI for the 2 interface.
*/
if (flCreate & CDIFL_DI2) {
LPDIRECTINPUT pdi = *(PPV)ppvOut;
hres = pdi->lpVtbl->QueryInterface(pdi, c_rgiidDI[flCreate],
ppvOut);
pdi->lpVtbl->Release(pdi);
}
}
return hres;
}
/*****************************************************************************
*
* GetDwordProperty
*
* Get a DWORD property from an IDirectInputDevice.
*
*****************************************************************************/
STDMETHODIMP
GetDwordProperty(IDirectInputDevice *pdid, PCGUID pguid, LPDWORD pdw)
{
HRESULT hres;
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
hres = IDirectInputDevice_GetProperty(pdid, pguid, &dipdw.diph);
if (SUCCEEDED(hres)) {
*pdw = dipdw.dwData;
}
return hres;
}
/*****************************************************************************
*
* SetDwordProperty
*
* Set a DWORD property into an IDirectInputDevice.
*
*****************************************************************************/
STDMETHODIMP
SetDwordProperty(IDirectInputDevice *pdid, PCGUID pguid, DWORD dw)
{
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = dw;
return IDirectInputDevice_SetProperty(pdid, pguid, &dipdw.diph);
}
/*****************************************************************************
*
* ConvertString
*
* Convert a string from whatever character set it is in into
* the preferred character set (ANSI or UNICODE, whichever we
* were compiled with).
*
* This is used to convert strings received from DirectInput
* into something we like.
*
*****************************************************************************/
void EXTERNAL
ConvertString(BOOL fWide, LPCVOID pvIn, LPTSTR ptszOut, UINT ctchOut)
{
if (fTchar(fWide)) {
lstrcpyn(ptszOut, pvIn, ctchOut);
} else {
#ifdef UNICODE
MultiByteToWideChar(CP_ACP, 0, pvIn, -1, ptszOut, ctchOut);
#else
WideCharToMultiByte(CP_ACP, 0, pvIn, -1, ptszOut, ctchOut, 0, 0);
#endif
}
}
/*****************************************************************************
*
* UnconvertString
*
* Convert a string from the preferred character set
* (ANSI or UNICODE, whichever we were compiled with)
* into the specified character set.
*
* This is used to convert strings generated from dialogs
* into something that DirectInput will like.
*
*****************************************************************************/
void EXTERNAL
UnconvertString(BOOL fWide, LPCTSTR ptszIn, LPVOID pvOut, UINT ctchOut)
{
if (fTchar(fWide)) {
lstrcpyn(pvOut, ptszIn, ctchOut);
} else {
#ifdef UNICODE
WideCharToMultiByte(CP_ACP, 0, ptszIn, -1, pvOut, ctchOut, 0, 0);
#else
MultiByteToWideChar(CP_ACP, 0, ptszIn, -1, pvOut, ctchOut);
#endif
}
}
/*****************************************************************************
*
* ConvertDoi
*
* Convert the pvDoi into the local character set.
*
*****************************************************************************/
void EXTERNAL
ConvertDoi(PDEVDLGINFO pddi, LPDIDEVICEOBJECTINSTANCE pdoi, LPCVOID pvDoi)
{
if (IsUnicodeDidc(pddi->didcItf)) {
LPCDIDEVICEOBJECTINSTANCEW pdoiW = pvDoi;
ConvertString(TRUE,
pdoiW->tszName, pdoi->tszName, cA(pdoi->tszName));
pdoi->guidType = pdoiW->guidType;
pdoi->dwOfs = pdoiW->dwOfs;
pdoi->dwType = pdoiW->dwType;
pdoi->dwFlags = pdoiW->dwFlags;
pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
pdoi->wReportId = pdoiW->wReportId;
if (pdoiW->dwSize > cbX(DIDEVICEOBJECTINSTANCE_DX3W)) {
pdoi->dwFFMaxForce = pdoiW->dwFFMaxForce;
pdoi->dwFFForceResolution = pdoiW->dwFFForceResolution;
pdoi->wCollectionNumber = pdoiW->wCollectionNumber;
pdoi->wDesignatorIndex = pdoiW->wDesignatorIndex;
pdoi->wUsagePage = pdoiW->wUsagePage;
pdoi->wUsage = pdoiW->wUsage;
pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
}
} else {
LPCDIDEVICEOBJECTINSTANCEA pdoiA = pvDoi;
ConvertString(FALSE,
pdoiA->tszName, pdoi->tszName, cA(pdoi->tszName));
pdoi->guidType = pdoiA->guidType;
pdoi->dwOfs = pdoiA->dwOfs;
pdoi->dwType = pdoiA->dwType;
pdoi->dwFlags = pdoiA->dwFlags;
pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
pdoi->wReportId = pdoiA->wReportId;
if (pdoiA->dwSize > cbX(DIDEVICEOBJECTINSTANCE_DX3A)) {
pdoi->dwFFMaxForce = pdoiA->dwFFMaxForce;
pdoi->dwFFForceResolution = pdoiA->dwFFForceResolution;
pdoi->wCollectionNumber = pdoiA->wCollectionNumber;
pdoi->wDesignatorIndex = pdoiA->wDesignatorIndex;
pdoi->wUsagePage = pdoiA->wUsagePage;
pdoi->wUsage = pdoiA->wUsage;
pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
}
}
}
/*****************************************************************************
*
* GetObjectInfo
*
* Do a GetObjectInfo with character set conversion.
*
*****************************************************************************/
HRESULT EXTERNAL
GetObjectInfo(PDEVDLGINFO pddi, LPDIDEVICEOBJECTINSTANCE pdoi,
DWORD dwObj, DWORD dwHow)
{
HRESULT hres;
union {
DIDEVICEOBJECTINSTANCEA doiA;
DIDEVICEOBJECTINSTANCEW doiW;
} u;
if (IsUnicodeDidc(pddi->didcItf)) {
if (g_dwDIVer > 0x0300) {
u.doiW.dwSize = cbX(u.doiW);
} else {
u.doiW.dwSize = cbX(DIDEVICEOBJECTINSTANCE_DX3W);
}
} else {
if (g_dwDIVer > 0x0300) {
u.doiA.dwSize = cbX(u.doiA);
} else {
u.doiA.dwSize = cbX(DIDEVICEOBJECTINSTANCE_DX3A);
}
}
hres = IDirectInputDevice_GetObjectInfo(pddi->pdid, (PV)&u,
dwObj, dwHow);
if (SUCCEEDED(hres)) {
ConvertDoi(pddi, pdoi, &u);
hres = S_OK;
}
return hres;
}
/*****************************************************************************
*
* ConvertDdi
*
* Convert the pvDdi into the local character set.
*
*****************************************************************************/
void EXTERNAL
ConvertDdi(PDEVDLGINFO pddi, LPDIDEVICEINSTANCE pinst, LPCVOID pvDdi)
{
if (IsUnicodeDidc(pddi->didcItf)) {
LPCDIDEVICEINSTANCEW pinstW = pvDdi;
ConvertString(TRUE,
pinstW->tszInstanceName,
pinst->tszInstanceName, cA(pinst->tszInstanceName));
ConvertString(TRUE,
pinstW->tszProductName,
pinst->tszProductName, cA(pinst->tszProductName));
pinst->guidInstance = pinstW->guidInstance;
pinst->guidProduct = pinstW->guidProduct;
pinst->dwDevType = pinstW->dwDevType;
pinst->dwSize = sizeof(DIDEVICEINSTANCE_DX3);
if (pinstW->dwSize > cbX(DIDEVICEINSTANCE_DX3W)) {
pinst->guidFFDriver = pinstW->guidFFDriver;
pinst->wUsagePage = pinstW->wUsagePage;
pinst->wUsage = pinstW->wUsage;
pinst->dwSize = sizeof(DIDEVICEINSTANCE);
}
} else {
LPCDIDEVICEINSTANCEA pinstA = pvDdi;
ConvertString(FALSE,
pinstA->tszInstanceName,
pinst->tszInstanceName, cA(pinst->tszInstanceName));
ConvertString(FALSE,
pinstA->tszProductName,
pinst->tszProductName, cA(pinst->tszProductName));
pinst->guidInstance = pinstA->guidInstance;
pinst->guidProduct = pinstA->guidProduct;
pinst->dwDevType = pinstA->dwDevType;
pinst->dwSize = sizeof(DIDEVICEINSTANCE_DX3);
if (pinstA->dwSize > cbX(DIDEVICEINSTANCE_DX3A)) {
pinst->guidFFDriver = pinstA->guidFFDriver;
pinst->wUsagePage = pinstA->wUsagePage;
pinst->wUsage = pinstA->wUsage;
pinst->dwSize = sizeof(DIDEVICEINSTANCE);
}
}
}
/*****************************************************************************
*
* GetDeviceInfo
*
* Do a GetDeviceInfo with character set conversion.
*
*****************************************************************************/
HRESULT EXTERNAL
GetDeviceInfo(PDEVDLGINFO pddi, LPDIDEVICEINSTANCE pinst)
{
HRESULT hres;
union {
DIDEVICEINSTANCEA ddiA;
DIDEVICEINSTANCEW ddiW;
} u;
if (IsUnicodeDidc(pddi->didcItf)) {
if (g_dwDIVer > 0x0300) {
u.ddiW.dwSize = cbX(u.ddiW);
} else {
u.ddiW.dwSize = cbX(DIDEVICEINSTANCE_DX3W);
}
} else {
if (g_dwDIVer > 0x0300) {
u.ddiA.dwSize = cbX(u.ddiA);
} else {
u.ddiA.dwSize = cbX(DIDEVICEINSTANCE_DX3A);
}
}
hres = IDirectInputDevice_GetDeviceInfo(pddi->pdid, (PV)&u);
if (SUCCEEDED(hres)) {
ConvertDdi(pddi, pinst, &u);
hres = S_OK;
}
return hres;
}
/*****************************************************************************
*
* ConvertEffi
*
* Convert the pvEffi into the local character set.
*
*****************************************************************************/
void EXTERNAL
ConvertEffi(PDEVDLGINFO pddi, LPDIEFFECTINFO pei, LPCVOID pvEffi)
{
LPCDIEFFECTINFOW peiW = pvEffi;
LPCDIEFFECTINFOA peiA = pvEffi;
LPCVOID pvStr;
if (IsUnicodeDidc(pddi->didcItf)) {
pvStr = peiW->tszName;
} else {
pvStr = peiA->tszName;
}
ConvertString(IsUnicodeDidc(pddi->didcItf),
pvStr, pei->tszName, cA(pei->tszName));
pei->guid = peiA->guid;
pei->dwEffType = peiA->dwEffType;
pei->dwStaticParams = peiA->dwStaticParams;
pei->dwDynamicParams= peiA->dwDynamicParams;
}
/*****************************************************************************
*
* GetEffectInfo
*
* Do a GetEffectInfo with character set conversion.
*
*****************************************************************************/
HRESULT EXTERNAL
GetEffectInfo(PDEVDLGINFO pddi, LPDIEFFECTINFO pei, REFGUID rguid)
{
HRESULT hres;
union {
DIEFFECTINFOA deiA;
DIEFFECTINFOW deiW;
} u;
if (IsUnicodeDidc(pddi->didcItf)) {
u.deiW.dwSize = cbX(u.deiW);
} else {
u.deiA.dwSize = cbX(u.deiA);
}
hres = IDirectInputDevice2_GetEffectInfo(pddi->pdid2, (PV)&u, rguid);
if (SUCCEEDED(hres)) {
ConvertEffi(pddi, pei, &u);
hres = S_OK;
}
return hres;
}
/*****************************************************************************
*
* StringFromGuid
*
*****************************************************************************/
void EXTERNAL
StringFromGuid(LPTSTR ptsz, REFGUID rclsid)
{
wsprintf(ptsz,
TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
rclsid->Data1, rclsid->Data2, rclsid->Data3,
rclsid->Data4[0], rclsid->Data4[1],
rclsid->Data4[2], rclsid->Data4[3],
rclsid->Data4[4], rclsid->Data4[5],
rclsid->Data4[6], rclsid->Data4[7]);
}
/*****************************************************************************
*
* MapGUID
*
* Convert a GUID to a string, using a friendly name if possible.
*
* ptszBuf must be large enough to hold a stringized GUID.
*
*****************************************************************************/
#pragma BEGIN_CONST_DATA
extern GUID GUID_HIDClass;
GUID GUID_Null;
GUIDMAP c_rggm[] = {
{ &GUID_XAxis, "GUID_XAxis", },
{ &GUID_YAxis, "GUID_YAxis", },
{ &GUID_ZAxis, "GUID_ZAxis", },
{ &GUID_RxAxis, "GUID_RxAxis", },
{ &GUID_RyAxis, "GUID_RyAxis", },
{ &GUID_RzAxis, "GUID_RzAxis", },
{ &GUID_Slider, "GUID_Slider", },
{ &GUID_Button, "GUID_Button", },
{ &GUID_Key, "GUID_Key", },
{ &GUID_POV, "GUID_POV", },
{ &GUID_Unknown, "GUID_Unknown", },
{ &GUID_SysMouse, "GUID_SysMouse" },
{ &GUID_SysKeyboard, "GUID_SysKeyboard" },
{ &GUID_Joystick, "GUID_Joystick", },
{ &GUID_Unknown, "GUID_Unknown", },
{ &GUID_ConstantForce,"GUID_ConstantForce", },
{ &GUID_RampForce, "GUID_RampForce", },
{ &GUID_Square, "GUID_Square", },
{ &GUID_Sine, "GUID_Sine", },
{ &GUID_Triangle, "GUID_Triangle", },
{ &GUID_SawtoothUp, "GUID_SawtoothUp", },
{ &GUID_SawtoothDown, "GUID_SawtoothDown", },
{ &GUID_Spring, "GUID_Spring", },
{ &GUID_Damper, "GUID_Damper", },
{ &GUID_Inertia, "GUID_Inertia", },
{ &GUID_Friction, "GUID_Friction", },
{ &GUID_CustomForce, "GUID_CustomForce", },
{ &GUID_Null, "GUID_NULL", },
{ &GUID_HIDClass, "GUID_HIDClass", },
};
LPCTSTR EXTERNAL
MapGUID(REFGUID rguid, LPTSTR ptszBuf)
{
int igm;
for (igm = 0; igm < cA(c_rggm); igm++) {
if (IsEqualGUID(rguid, c_rggm[igm].rguid)) {
return c_rggm[igm].ptsz;
}
}
StringFromGuid(ptszBuf, rguid);
return ptszBuf;
}
/*****************************************************************************
*
* ProbeDinputVersion
*
* Snoop around to determine what version of DirectInput is available.
*
*****************************************************************************/
void INTERNAL
ProbeDinputVersion(void)
{
IDirectInput *pdi;
HRESULT hres;
/*
* For safety's sake, start with DirectX 3.0 and gradually
* work upwards.
*/
g_dwDIVer = 0x0300;
hres = DirectInputCreate(g_hinst, 0x0300, (PVOID)&pdi, 0);
if (SUCCEEDED(hres)) {
/*
* Probe upward to see what version of DirectX is supported.
*/
if (SUCCEEDED(IDirectInput_Initialize(pdi, g_hinst,
DIRECTINPUT_VERSION))) {
g_dwDIVer = DIRECTINPUT_VERSION;
}
IDirectInput_Release(pdi);
}
}
/*****************************************************************************
*
* Globals
*
*****************************************************************************/
HINSTANCE g_hinst;
HCURSOR g_hcurWait;
HCURSOR g_hcurStarting;
DWORD g_dwDIVer;
#ifdef DEBUG
TCHAR g_tszInvalid[128];
#endif
/*****************************************************************************
*
* Entry
*
*****************************************************************************/
void __cdecl
Entry(void)
{
g_hcurWait = LoadCursor(0, IDC_WAIT);
g_hcurStarting = LoadCursor(0, IDC_APPSTARTING);
g_hinst = GetModuleHandle(0);
#ifdef DEBUG
LoadString(g_hinst, IDS_INVALID, g_tszInvalid, cA(g_tszInvalid));
#endif
Checklist_Init();
ProbeDinputVersion();
if (SUCCEEDED(CoInitialize(0))) {
DialogBox(g_hinst, MAKEINTRESOURCE(IDD_MAIN), 0, Diq_DlgProc);
CoUninitialize();
}
Checklist_Term();
ExitProcess(0);
}