646 lines
20 KiB
C++
646 lines
20 KiB
C++
|
//===========================================================================
|
||
|
// DICPUTIL.CPP
|
||
|
//
|
||
|
// DirectInput CPL helper functions.
|
||
|
//
|
||
|
// Functions:
|
||
|
// DIUtilGetJoystickTypeName()
|
||
|
// DIUtilPollJoystick()
|
||
|
//
|
||
|
//===========================================================================
|
||
|
|
||
|
//===========================================================================
|
||
|
// (C) Copyright 1997 Microsoft Corp. All rights reserved.
|
||
|
//
|
||
|
// You have a royalty-free right to use, modify, reproduce and
|
||
|
// distribute the Sample Files (and/or any modified version) in
|
||
|
// any way you find useful, provided that you agree that
|
||
|
// Microsoft has no warranty obligations or liability for any
|
||
|
// Sample Application Files which are modified.
|
||
|
//===========================================================================
|
||
|
|
||
|
#include "cplsvr1.h"
|
||
|
#include "dicputil.h"
|
||
|
#include <shlwapi.h> // for Str... functions!
|
||
|
#include <malloc.h> // for _alloca
|
||
|
|
||
|
extern HWND ghDlg;
|
||
|
extern CDIGameCntrlPropSheet_X *pdiCpl;
|
||
|
extern HINSTANCE ghInst;
|
||
|
extern CRITICAL_SECTION gcritsect;
|
||
|
|
||
|
|
||
|
//===========================================================================
|
||
|
// DIUtilPollJoystick
|
||
|
//
|
||
|
// Polls the joystick device and returns the device state.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// LPDIRECTINPUTDEVICE2 pdiDevice2 - ptr to device object
|
||
|
// DIJOYSTATE *pdijs - ptr to store joystick state
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
//===========================================================================
|
||
|
HRESULT DIUtilPollJoystick(LPDIRECTINPUTDEVICE2 pdiDevice2, LPDIJOYSTATE pdijs)
|
||
|
{
|
||
|
// clear the pdijs memory
|
||
|
// this way, if we fail, we return no data
|
||
|
pdijs->lX = pdijs->lY = pdijs->lZ = pdijs->lRx = pdijs->lRy = pdijs->lRz = pdijs->rglSlider[0] = pdijs->rglSlider[1] = 0;
|
||
|
|
||
|
// poll the joystick
|
||
|
HRESULT hRes;
|
||
|
|
||
|
if( SUCCEEDED(hRes = pdiDevice2->Poll()) )
|
||
|
{
|
||
|
static BOOL bFirstPoll = TRUE;
|
||
|
|
||
|
// This is to disreguard the first poll!
|
||
|
// DINPUT sends garbage the first poll.
|
||
|
if( bFirstPoll )
|
||
|
{
|
||
|
pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs);
|
||
|
bFirstPoll = FALSE;
|
||
|
}
|
||
|
|
||
|
// query the device state
|
||
|
if( FAILED(hRes = pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs)) )
|
||
|
{
|
||
|
if( hRes == DIERR_INPUTLOST )
|
||
|
{
|
||
|
if( SUCCEEDED(hRes = pdiDevice2->Acquire()) )
|
||
|
hRes = pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// done
|
||
|
return(hRes);
|
||
|
} // *** end DIUtilPollJoystick()
|
||
|
|
||
|
//===========================================================================
|
||
|
// InitDInput
|
||
|
//
|
||
|
// Initializes DirectInput objects
|
||
|
//
|
||
|
// Parameters:
|
||
|
// HWND hWnd - handle of caller's window
|
||
|
// CDIGameCntrlPropSheet_X *pdiCpl - pointer to Game Controllers property
|
||
|
// sheet object
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
//===========================================================================
|
||
|
HRESULT InitDInput(HWND hWnd, CDIGameCntrlPropSheet_X *pdiCpl)
|
||
|
{
|
||
|
HRESULT hRes = S_OK;
|
||
|
LPDIRECTINPUTDEVICE2 pdiDevice2;
|
||
|
LPDIRECTINPUTJOYCONFIG pdiJoyCfg;
|
||
|
LPDIRECTINPUT pdi = 0;
|
||
|
|
||
|
// protect ourselves from multithreading problems
|
||
|
EnterCriticalSection(&gcritsect);
|
||
|
|
||
|
// validate pdiCpl
|
||
|
if( (IsBadReadPtr((void*)pdiCpl, sizeof(CDIGameCntrlPropSheet_X))) ||
|
||
|
(IsBadWritePtr((void*)pdiCpl, sizeof(CDIGameCntrlPropSheet_X))) )
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
OutputDebugString(TEXT("GCDEF.DLL: InitDInput() - bogus pointer\n"));
|
||
|
#endif
|
||
|
hRes = E_POINTER;
|
||
|
goto exitinit;
|
||
|
}
|
||
|
|
||
|
// retrieve the current device object
|
||
|
pdiCpl->GetDevice(&pdiDevice2);
|
||
|
|
||
|
// retrieve the current joyconfig object
|
||
|
pdiCpl->GetJoyConfig(&pdiJoyCfg);
|
||
|
|
||
|
// have we already initialized DirectInput?
|
||
|
if( (NULL == pdiDevice2) || (NULL == pdiJoyCfg) )
|
||
|
{
|
||
|
// no, create a base DirectInput object
|
||
|
if( FAILED(hRes = DirectInputCreate(ghInst, DIRECTINPUT_VERSION, &pdi, NULL)) )
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
OutputDebugString(TEXT("GCDEF.DLL: DirectInputCreate() failed\n"));
|
||
|
#endif
|
||
|
goto exitinit;
|
||
|
}
|
||
|
|
||
|
// have we already created a joyconfig object?
|
||
|
if( NULL == pdiJoyCfg )
|
||
|
{
|
||
|
// no, create a joyconfig object
|
||
|
if( SUCCEEDED(pdi->QueryInterface(IID_IDirectInputJoyConfig, (LPVOID*)&pdiJoyCfg)) )
|
||
|
{
|
||
|
if( SUCCEEDED(pdiJoyCfg->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND)) )
|
||
|
pdiCpl->SetJoyConfig(pdiJoyCfg);
|
||
|
} else
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
OutputDebugString(TEXT("GCDEF.DLL: Unable to create joyconfig\n"));
|
||
|
#endif
|
||
|
goto exitinit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// have we already created a device object?
|
||
|
if( NULL == pdiDevice2 )
|
||
|
{
|
||
|
// no, create a device object
|
||
|
if( NULL != pdiJoyCfg )
|
||
|
{
|
||
|
LPDIRECTINPUTDEVICE pdiDevTemp;
|
||
|
LPDIJOYCONFIG_DX5 lpDIJoyConfig = (LPDIJOYCONFIG_DX5)_alloca(sizeof(DIJOYCONFIG_DX5));
|
||
|
ASSERT (lpDIJoyConfig);
|
||
|
|
||
|
// get the type name
|
||
|
ZeroMemory(lpDIJoyConfig, sizeof(DIJOYCONFIG_DX5));
|
||
|
|
||
|
// GetConfig will provide this information
|
||
|
lpDIJoyConfig->dwSize = sizeof(DIJOYCONFIG_DX5);
|
||
|
|
||
|
// Get the instance necessarey for CreateDevice
|
||
|
if( SUCCEEDED(hRes = pdiJoyCfg->GetConfig(pdiCpl->GetID(), (LPDIJOYCONFIG)lpDIJoyConfig, DIJC_GUIDINSTANCE)) )
|
||
|
{
|
||
|
// Create the device
|
||
|
if( SUCCEEDED(hRes = pdi->CreateDevice(lpDIJoyConfig->guidInstance, &pdiDevTemp, NULL)) )
|
||
|
{
|
||
|
// Query the device for the Device2 interface!
|
||
|
if( SUCCEEDED(hRes = pdiDevTemp->QueryInterface(IID_IDirectInputDevice2, (LPVOID*)&pdiDevice2)) )
|
||
|
{
|
||
|
// release the temporary object
|
||
|
pdiDevTemp->Release();
|
||
|
|
||
|
// Set the DataFormat and CooperativeLevel!
|
||
|
if( SUCCEEDED(hRes = pdiDevice2->SetDataFormat(&c_dfDIJoystick)) )
|
||
|
hRes = pdiDevice2->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( SUCCEEDED(hRes) )
|
||
|
{
|
||
|
// store the device object
|
||
|
pdiCpl->SetDevice(pdiDevice2);
|
||
|
} else
|
||
|
{
|
||
|
goto exitinit;
|
||
|
}
|
||
|
} else goto exitinit;
|
||
|
}
|
||
|
} else {
|
||
|
goto exitinit;
|
||
|
}
|
||
|
|
||
|
// if everything is Zero, either you've never enumerated or the enumeration is suspectable
|
||
|
if( (pdiCpl->GetStateFlags()->nButtons == 0) &&
|
||
|
(pdiCpl->GetStateFlags()->nAxis == 0) &&
|
||
|
(pdiCpl->GetStateFlags()->nPOVs == 0) )
|
||
|
{
|
||
|
EnumDeviceObjects(pdiDevice2, pdiCpl->GetStateFlags());
|
||
|
|
||
|
/*
|
||
|
if (FAILED(pdiDevice2->EnumObjects((LPDIENUMDEVICEOBJECTSCALLBACK)DIEnumDeviceObjectsProc, (LPVOID *)pdiCpl->GetStateFlags(), DIDFT_ALL)))
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
OutputDebugString(TEXT("GCDEF.DLL: TEST.CPP: WM_INIT: EnumObjects FAILED!\n"));
|
||
|
#endif
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
exitinit:
|
||
|
// release the base DirectInput object
|
||
|
if( pdi ) {
|
||
|
pdi->Release();
|
||
|
}
|
||
|
|
||
|
// we're done
|
||
|
LeaveCriticalSection(&gcritsect);
|
||
|
return(hRes);
|
||
|
|
||
|
} //*** end InitDInput()
|
||
|
|
||
|
|
||
|
|
||
|
void OnHelp(LPARAM lParam)
|
||
|
{
|
||
|
assert ( lParam );
|
||
|
|
||
|
short nSize = STR_LEN_32;
|
||
|
|
||
|
// point to help file
|
||
|
LPTSTR pszHelpFileName = (LPTSTR) _alloca(sizeof(TCHAR[STR_LEN_32]));
|
||
|
assert (pszHelpFileName);
|
||
|
|
||
|
// returns help file name and size of string
|
||
|
GetHelpFileName(pszHelpFileName, &nSize);
|
||
|
|
||
|
if( ((LPHELPINFO)lParam)->iContextType == HELPINFO_WINDOW )
|
||
|
WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, pszHelpFileName, (UINT)HELP_WM_HELP, (ULONG_PTR)gaHelpIDs);
|
||
|
}
|
||
|
|
||
|
BOOL GetHelpFileName(TCHAR *lpszHelpFileName, short* nSize)
|
||
|
{
|
||
|
if( LoadString(ghInst, IDS_HELPFILENAME, lpszHelpFileName, *nSize) )
|
||
|
return(S_OK);
|
||
|
else
|
||
|
return(E_FAIL);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// OnContextMenu(WPARAM wParam)
|
||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
void OnContextMenu(WPARAM wParam)
|
||
|
{
|
||
|
short nSize = STR_LEN_32;
|
||
|
|
||
|
// point to help file
|
||
|
LPTSTR pszHelpFileName = (LPTSTR) _alloca(sizeof(TCHAR[STR_LEN_32]));
|
||
|
assert (pszHelpFileName);
|
||
|
|
||
|
// returns help file name and size of string
|
||
|
GetHelpFileName(pszHelpFileName, &nSize);
|
||
|
|
||
|
WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (ULONG_PTR)gaHelpIDs);
|
||
|
}
|
||
|
|
||
|
// Instead of enumerating via EnumObjects
|
||
|
void EnumDeviceObjects(LPDIRECTINPUTDEVICE2 pdiDevice2, STATEFLAGS *pStateFlags)
|
||
|
{
|
||
|
LPDIDEVICEOBJECTINSTANCE_DX3 pDevObjInst = (LPDIDEVICEOBJECTINSTANCE_DX3) _alloca(sizeof(DIDEVICEOBJECTINSTANCE_DX3));
|
||
|
assert (pDevObjInst);
|
||
|
|
||
|
pDevObjInst->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
|
||
|
|
||
|
const DWORD dwOffsetArray[] = {DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1)};
|
||
|
|
||
|
// -1 is for 0 based dwOffsetArray!
|
||
|
BYTE n = MAX_AXIS;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
if( SUCCEEDED(pdiDevice2->GetObjectInfo((LPDIDEVICEOBJECTINSTANCE)pDevObjInst, dwOffsetArray[--n], DIPH_BYOFFSET)) )
|
||
|
pStateFlags->nAxis |= (HAS_X<<n);
|
||
|
} while( n );
|
||
|
|
||
|
|
||
|
n = MAX_BUTTONS;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
if( SUCCEEDED(pdiDevice2->GetObjectInfo((LPDIDEVICEOBJECTINSTANCE)pDevObjInst, DIJOFS_BUTTON(--n), DIPH_BYOFFSET)) )
|
||
|
pStateFlags->nButtons |= (HAS_BUTTON1<<n);
|
||
|
} while( n );
|
||
|
|
||
|
|
||
|
n = MAX_POVS;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
if( SUCCEEDED(pdiDevice2->GetObjectInfo((LPDIDEVICEOBJECTINSTANCE)pDevObjInst, DIJOFS_POV(--n), DIPH_BYOFFSET)) )
|
||
|
pStateFlags->nPOVs |= (HAS_POV1<<n);
|
||
|
} while( n );
|
||
|
}
|
||
|
|
||
|
#define GETRANGE( n ) \
|
||
|
pDIPropCal->lMin = lpMyRanges->jpMin.dw##n##; \
|
||
|
pDIPropCal->lCenter = lpMyRanges->jpCenter.dw##n##; \
|
||
|
pDIPropCal->lMax = lpMyRanges->jpMax.dw##n##; \
|
||
|
|
||
|
|
||
|
void SetMyRanges(LPDIRECTINPUTDEVICE2 lpdiDevice2, LPMYJOYRANGE lpMyRanges, BYTE nAxis)
|
||
|
{
|
||
|
LPDIPROPCAL pDIPropCal = (LPDIPROPCAL)_alloca(sizeof(DIPROPCAL));
|
||
|
assert (pDIPropCal);
|
||
|
|
||
|
pDIPropCal->diph.dwSize = sizeof(DIPROPCAL);
|
||
|
pDIPropCal->diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||
|
pDIPropCal->diph.dwHow = DIPH_BYOFFSET;
|
||
|
|
||
|
const DWORD dwOffsetArray[] = {DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1)};
|
||
|
BYTE n = 0;
|
||
|
|
||
|
// You have to start with a "while" here because Reset to Default may not have Any Axis!!!
|
||
|
while( nAxis )
|
||
|
{
|
||
|
if( nAxis & HAS_X )
|
||
|
{
|
||
|
GETRANGE(X);
|
||
|
} else if( nAxis & HAS_Y )
|
||
|
{
|
||
|
GETRANGE(Y);
|
||
|
n = 1;
|
||
|
} else if( nAxis & HAS_Z )
|
||
|
{
|
||
|
GETRANGE(Z)
|
||
|
n = 2;
|
||
|
} else if( nAxis & HAS_RX )
|
||
|
{
|
||
|
GETRANGE(Rx);
|
||
|
n = 3;
|
||
|
} else if( nAxis & HAS_RY )
|
||
|
{
|
||
|
GETRANGE(Ry);
|
||
|
n = 4;
|
||
|
} else if( nAxis & HAS_RZ )
|
||
|
{
|
||
|
GETRANGE(Rz);
|
||
|
n = 5;
|
||
|
} else if( nAxis & HAS_SLIDER0 )
|
||
|
{
|
||
|
GETRANGE(S0);
|
||
|
n = 6;
|
||
|
} else if( nAxis & HAS_SLIDER1 )
|
||
|
{
|
||
|
GETRANGE(S1);
|
||
|
n = 7;
|
||
|
}
|
||
|
|
||
|
pDIPropCal->diph.dwObj = dwOffsetArray[n];
|
||
|
|
||
|
VERIFY(SUCCEEDED(lpdiDevice2->SetProperty(DIPROP_CALIBRATION, &pDIPropCal->diph)));
|
||
|
|
||
|
nAxis &= ~HAS_X<<n;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Removed 'till we calibrate POVs again!
|
||
|
void SetMyPOVRanges(LPDIRECTINPUTDEVICE2 pdiDevice2)
|
||
|
{
|
||
|
DIPROPCALPOV *pDIPropCal = new (DIPROPCALPOV);
|
||
|
assert (pDIPropCal);
|
||
|
|
||
|
ZeroMemory(pDIPropCal, sizeof(*pDIPropCal));
|
||
|
|
||
|
pDIPropCal->diph.dwSize = sizeof(*pDIPropCal);
|
||
|
pDIPropCal->diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||
|
pDIPropCal->diph.dwHow = DIPH_BYID;
|
||
|
pDIPropCal->diph.dwObj = DIDFT_POV;
|
||
|
|
||
|
memcpy( pDIPropCal->lMin, myPOV[POV_MIN], sizeof(pDIPropCal->lMin) );
|
||
|
memcpy( pDIPropCal->lMax, myPOV[POV_MAX], sizeof(pDIPropCal->lMax) );
|
||
|
|
||
|
if( FAILED(pdiDevice2->SetProperty(DIPROP_CALIBRATION, &pDIPropCal->diph)) )
|
||
|
{
|
||
|
#if (defined(_DEBUG) || defined(DEBUG))
|
||
|
OutputDebugString(TEXT("GCDEF.DLL: SetMyRanges: SetProperty failed to set POV!\n"));
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if( pDIPropCal ) {
|
||
|
delete (pDIPropCal);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void SetTitle( HWND hDlg )
|
||
|
{
|
||
|
// Set the title bar!
|
||
|
LPDIRECTINPUTDEVICE2 pdiDevice2;
|
||
|
pdiCpl->GetDevice(&pdiDevice2);
|
||
|
|
||
|
DIPROPSTRING *pDIPropStr = new (DIPROPSTRING);
|
||
|
ASSERT (pDIPropStr);
|
||
|
|
||
|
ZeroMemory(pDIPropStr, sizeof(DIPROPSTRING));
|
||
|
|
||
|
pDIPropStr->diph.dwSize = sizeof(DIPROPSTRING);
|
||
|
pDIPropStr->diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||
|
pDIPropStr->diph.dwHow = DIPH_DEVICE;
|
||
|
|
||
|
if( SUCCEEDED(pdiDevice2->GetProperty(DIPROP_INSTANCENAME, &pDIPropStr->diph)) )
|
||
|
{
|
||
|
TCHAR tszFormat[STR_LEN_64];
|
||
|
#ifndef _UNICODE
|
||
|
CHAR szOut[STR_LEN_128];
|
||
|
#endif
|
||
|
|
||
|
LPWSTR lpwszTitle = new (WCHAR[STR_LEN_128]);
|
||
|
ASSERT (lpwszTitle);
|
||
|
|
||
|
// Shorten length, provide elipse,
|
||
|
if( wcslen(pDIPropStr->wsz) > 32 )
|
||
|
{
|
||
|
pDIPropStr->wsz[30] = pDIPropStr->wsz[31] = pDIPropStr->wsz[32] = L'.';
|
||
|
pDIPropStr->wsz[33] = L'\0';
|
||
|
}
|
||
|
|
||
|
LoadString(ghInst, IDS_SHEETCAPTION, tszFormat, sizeof(tszFormat)/sizeof(tszFormat[0]));
|
||
|
|
||
|
#ifdef _UNICODE
|
||
|
wsprintfW(lpwszTitle, tszFormat, pDIPropStr->wsz);
|
||
|
#else
|
||
|
USES_CONVERSION;
|
||
|
|
||
|
wsprintfA(szOut, tszFormat, W2A(pDIPropStr->wsz));
|
||
|
StrCpyW(lpwszTitle, A2W(szOut));
|
||
|
#endif
|
||
|
|
||
|
//SetWindowText(GetParent(hDlg),
|
||
|
::SendMessage(GetParent(hDlg), WM_SETTEXT, 0, (LPARAM)(LPCTSTR)
|
||
|
#ifdef _UNICODE
|
||
|
lpwszTitle);
|
||
|
#else
|
||
|
W2A(lpwszTitle));
|
||
|
#endif
|
||
|
|
||
|
if( lpwszTitle )
|
||
|
delete[] (lpwszTitle);
|
||
|
}
|
||
|
#ifdef _DEBUG
|
||
|
else OutputDebugString(TEXT("GCDEF.DLL: DICPUTIL.CPP: SetTitle: GetProperty Failed!\n"));
|
||
|
#endif
|
||
|
|
||
|
if( pDIPropStr )
|
||
|
delete (pDIPropStr);
|
||
|
}
|
||
|
|
||
|
BOOL Error(HWND hWnd, short nTitleID, short nMsgID)
|
||
|
{
|
||
|
LPTSTR lptTitle = new TCHAR[STR_LEN_64];
|
||
|
ASSERT (lptTitle);
|
||
|
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
if( LoadString(ghInst, nTitleID, lptTitle, STR_LEN_64) )
|
||
|
{
|
||
|
LPTSTR lptMsg = (LPTSTR)_alloca(sizeof(TCHAR[STR_LEN_128]));
|
||
|
ASSERT (lptMsg);
|
||
|
|
||
|
if( LoadString(ghInst, nMsgID, lptMsg, STR_LEN_128) )
|
||
|
{
|
||
|
MessageBox(hWnd, lptMsg, lptTitle, MB_ICONHAND | MB_OK);
|
||
|
bRet = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( lptTitle )
|
||
|
delete[] (lptTitle);
|
||
|
|
||
|
return(bRet);
|
||
|
}
|
||
|
|
||
|
void CenterDialog(HWND hWnd)
|
||
|
{
|
||
|
RECT rc;
|
||
|
HWND hParentWnd = GetParent(hWnd);
|
||
|
|
||
|
GetWindowRect(hParentWnd, &rc);
|
||
|
|
||
|
// Centre the Dialog!
|
||
|
SetWindowPos(hParentWnd, NULL,
|
||
|
(GetSystemMetrics(SM_CXSCREEN) - (rc.right-rc.left))>>1,
|
||
|
(GetSystemMetrics(SM_CYSCREEN) - (rc.bottom-rc.top))>>1,
|
||
|
NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define SETRANGE( n ) \
|
||
|
lpMyRanges->jpMin.dw##n## = pDIPropRange->lMin; \
|
||
|
lpMyRanges->jpCenter.dw##n## = pDIPropRange->lCenter; \
|
||
|
lpMyRanges->jpMax.dw##n## = pDIPropRange->lMax; \
|
||
|
|
||
|
//===========================================================================
|
||
|
// BOOL GetMyRanges( LPMYJOYRANGE lpMyRanges, LPDIRECTINPUTDEVICE2 pdiDevice2, BYTE nAxis)
|
||
|
//
|
||
|
// Parameters:
|
||
|
// LPMYJOYRANGE lpMyRanges - Structure to fill with ranges
|
||
|
// LPDIRECTINPUTDEVICE2 pdiDevice2 - Device in which axis ranges are requested
|
||
|
// BYTE nAxis - Bit mask of axis ranges to retrieve
|
||
|
//
|
||
|
// Returns: FALSE if failed
|
||
|
//
|
||
|
//===========================================================================
|
||
|
void GetMyRanges(LPDIRECTINPUTDEVICE2 lpdiDevice2, LPMYJOYRANGE lpMyRanges, BYTE nAxis)
|
||
|
{
|
||
|
// Use DIPROPCAL to retrieve Range Information
|
||
|
// Don't use DIPROPRANGE, as it doesn't have Center!
|
||
|
LPDIPROPCAL pDIPropRange = (LPDIPROPCAL)_alloca(sizeof(DIPROPCAL));
|
||
|
assert(pDIPropRange);
|
||
|
|
||
|
pDIPropRange->diph.dwSize = sizeof(DIPROPCAL);
|
||
|
pDIPropRange->diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||
|
pDIPropRange->diph.dwHow = DIPH_BYOFFSET;
|
||
|
|
||
|
const DWORD dwOffsetArray[] = {DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1)};
|
||
|
BYTE nIndex = 0;
|
||
|
|
||
|
// Zero out the buffer members and the index!
|
||
|
pDIPropRange->lMin = pDIPropRange->lCenter = pDIPropRange->lMax = 0;
|
||
|
|
||
|
// You don't have to start with "while" here because Reset to Default does not call this function!!1
|
||
|
do
|
||
|
{
|
||
|
if( nAxis & HAS_X )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 0];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(X);
|
||
|
}
|
||
|
} else if( nAxis & HAS_Y )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 1];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(Y);
|
||
|
}
|
||
|
} else if( nAxis & HAS_Z )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 2];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(Z);
|
||
|
}
|
||
|
} else if( nAxis & HAS_RX )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 3];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(Rx);
|
||
|
}
|
||
|
} else if( nAxis & HAS_RY )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 4];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(Ry);
|
||
|
}
|
||
|
} else if( nAxis & HAS_RZ )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 5];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(Rz);
|
||
|
}
|
||
|
} else if( nAxis & HAS_SLIDER0 )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 6];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(S0);
|
||
|
}
|
||
|
} else if( nAxis & HAS_SLIDER1 )
|
||
|
{
|
||
|
pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 7];
|
||
|
|
||
|
if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
|
||
|
{
|
||
|
SETRANGE(S1);
|
||
|
}
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
} while( nAxis &= ~HAS_X<<nIndex );
|
||
|
}
|
||
|
|
||
|
void PostDlgItemEnableWindow(HWND hDlg, USHORT nItem, BOOL bEnabled)
|
||
|
{
|
||
|
HWND hCtrl = GetDlgItem(hDlg, nItem);
|
||
|
|
||
|
if( hCtrl )
|
||
|
PostEnableWindow(hCtrl, bEnabled);
|
||
|
}
|
||
|
|
||
|
void PostEnableWindow(HWND hCtrl, BOOL bEnabled)
|
||
|
{
|
||
|
DWORD dwStyle = GetWindowLong(hCtrl, GWL_STYLE);
|
||
|
|
||
|
// No point Redrawing the Window if there's no change!
|
||
|
if( bEnabled )
|
||
|
{
|
||
|
if( dwStyle & WS_DISABLED )
|
||
|
dwStyle &= ~WS_DISABLED;
|
||
|
else return;
|
||
|
} else
|
||
|
{
|
||
|
if( !(dwStyle & WS_DISABLED) )
|
||
|
dwStyle |= WS_DISABLED;
|
||
|
else return;
|
||
|
}
|
||
|
|
||
|
SetWindowLongPtr(hCtrl, GWL_STYLE, (LONG_PTR)dwStyle);
|
||
|
|
||
|
RedrawWindow(hCtrl, NULL, NULL, RDW_INTERNALPAINT | RDW_INVALIDATE);
|
||
|
}
|
||
|
|
||
|
void CopyRange( LPJOYRANGE lpjr, LPMYJOYRANGE lpmyjr )
|
||
|
{
|
||
|
memcpy( &lpjr->jpMin, &lpmyjr->jpMin, sizeof(JOYPOS) );
|
||
|
memcpy( &lpjr->jpCenter, &lpmyjr->jpCenter, sizeof(JOYPOS) );
|
||
|
memcpy( &lpjr->jpMax, &lpmyjr->jpMax, sizeof(JOYPOS) );
|
||
|
|
||
|
}
|