508 lines
14 KiB
C
508 lines
14 KiB
C
/*****************************************************************************
|
|
*
|
|
* diqmain.c
|
|
*
|
|
* The main dialog box.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "diquick.h"
|
|
|
|
GUID GUID_Uninit = { 1 };
|
|
|
|
DWORD g_dwEnumType;
|
|
DWORD g_dwEnumFlags;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Dialog instance data
|
|
*
|
|
* Instance data for main dialog box.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct MAINDLGINFO {
|
|
HWND hwndDevices; /* Devices combo box */
|
|
UINT cBusy; /* Number of threads starting */
|
|
UINT cDevs; /* Number of devices created */
|
|
IDirectInput *pdi; /* Cached interface */
|
|
BOOL fW; /* Is pdi a pdiW? (else, pdiA) */
|
|
DARY daryDevs; /* Device info lives here */
|
|
} MAINDLGINFO, *PMAINDLGINFO;
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_DeviceEnumProc
|
|
*
|
|
* Device enumeration procedure which is called one for each device.
|
|
*
|
|
* Add the item to our dialog instance data and to the combo box.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_DeviceEnumProc(PCV pvDi, LPVOID pv)
|
|
{
|
|
PMAINDLGINFO pmdi = pv;
|
|
DIDEVICEINSTANCE didi;
|
|
TCHAR tsz[1024];
|
|
int ich;
|
|
|
|
if (pmdi->fW) {
|
|
LPCDIDEVICEINSTANCEW pdiW = pvDi;
|
|
didi.guidInstance = pdiW->guidInstance;
|
|
didi.guidProduct = pdiW->guidProduct;
|
|
didi.dwDevType = pdiW->dwDevType;
|
|
ConvertString(pmdi->fW, pdiW->tszProductName,
|
|
didi.tszProductName,
|
|
cA(didi.tszProductName));
|
|
ConvertString(pmdi->fW, pdiW->tszInstanceName,
|
|
didi.tszInstanceName,
|
|
cA(didi.tszInstanceName));
|
|
} else {
|
|
LPCDIDEVICEINSTANCEA pdiA = pvDi;
|
|
didi.guidInstance = pdiA->guidInstance;
|
|
didi.guidProduct = pdiA->guidProduct;
|
|
didi.dwDevType = pdiA->dwDevType;
|
|
ConvertString(pmdi->fW, pdiA->tszProductName,
|
|
didi.tszProductName,
|
|
cA(didi.tszProductName));
|
|
ConvertString(pmdi->fW, pdiA->tszInstanceName,
|
|
didi.tszInstanceName,
|
|
cA(didi.tszInstanceName));
|
|
}
|
|
|
|
ich = wsprintf(tsz, TEXT("%s (%s)"),
|
|
didi.tszInstanceName,
|
|
didi.tszProductName);
|
|
|
|
|
|
if (didi.dwDevType & DIDEVTYPE_HID) {
|
|
LoadString(g_hinst, IDS_SPACEPARENHID, &tsz[ich], 10);
|
|
}
|
|
|
|
ComboBox_AddString(pmdi->hwndDevices, tsz);
|
|
Dary_Append(&pmdi->daryDevs, &didi);
|
|
|
|
return DIENUM_CONTINUE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_EnumDevices
|
|
*
|
|
* Rebuild the list of enumerated devices. Try to preserve the
|
|
* current selection index.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void INTERNAL
|
|
Diq_EnumDevices(PMAINDLGINFO pmdi)
|
|
{
|
|
HRESULT hres;
|
|
int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
|
|
HCURSOR hcurPrev = GetCursor();
|
|
SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
Dary_Term(&pmdi->daryDevs);
|
|
ZeroX(pmdi->daryDevs);
|
|
ComboBox_ResetContent(pmdi->hwndDevices);
|
|
|
|
#if defined(_DEBUG) || defined(DEBUG)
|
|
{
|
|
/*
|
|
* Create the intentionally invalid device.
|
|
*/
|
|
DIDEVICEINSTANCE didi;
|
|
ComboBox_AddString(pmdi->hwndDevices, g_tszInvalid);
|
|
ZeroX(didi);
|
|
Dary_Append(&pmdi->daryDevs, &didi);
|
|
|
|
ComboBox_AddString(pmdi->hwndDevices, "<uninit>");
|
|
ZeroX(didi);
|
|
didi.guidInstance = GUID_Uninit;
|
|
lstrcpyn(didi.tszInstanceName, "<uninit instance>",
|
|
cA(didi.tszInstanceName));
|
|
Dary_Append(&pmdi->daryDevs, &didi);
|
|
}
|
|
#endif
|
|
|
|
pmdi->fW = 1;
|
|
hres = DirectInput8Create(g_hinst, g_dwDIVer, &IID_IDirectInput8W, (PVOID)&pmdi->pdi, 0);
|
|
|
|
/* For each object, add it to the menu */
|
|
if (SUCCEEDED(hres)) {
|
|
|
|
IDirectInput_EnumDevices(pmdi->pdi, g_dwEnumType, Diq_DeviceEnumProc,
|
|
pmdi, g_dwEnumFlags);
|
|
IDirectInput_Release(pmdi->pdi);
|
|
pmdi->pdi = 0;
|
|
}
|
|
|
|
ComboBox_SetCurSel(pmdi->hwndDevices, max(iSel, 0));
|
|
|
|
SetCursor(hcurPrev);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnInitDialog
|
|
*
|
|
* Populate the combo box with the list of devices.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnInitDialog(HWND hdlg)
|
|
{
|
|
PMAINDLGINFO pmdi;
|
|
|
|
Diq_HackPropertySheets(hdlg);
|
|
|
|
pmdi = LocalAlloc(LPTR, cbX(MAINDLGINFO));
|
|
|
|
if ( !pmdi ) {
|
|
return 0;
|
|
}
|
|
|
|
SetDialogPtr(hdlg, pmdi);
|
|
|
|
pmdi->hwndDevices = GetDlgItem(hdlg, IDC_MAIN_DEVICES);
|
|
|
|
Diq_EnumDevices(pmdi);
|
|
|
|
CheckRadioButton(hdlg, IDC_MAIN_OLE, IDC_MAIN_DI, IDC_MAIN_DI);
|
|
CheckRadioButton(hdlg, IDC_MAIN_DIA, IDC_MAIN_DIW, IDC_MAIN_DIW);
|
|
CheckRadioButton(hdlg, IDC_MAIN_DIDA, IDC_MAIN_ITFMAC, IDC_MAIN_DIDW);
|
|
|
|
if (g_dwDIVer <= 0x0300) {
|
|
//EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DID2A), FALSE);
|
|
//EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DID2W), FALSE);
|
|
EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DIDJC), FALSE);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnDestroy
|
|
*
|
|
* Clean up.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnDestroy(PMAINDLGINFO pmdi, HWND hdlg)
|
|
{
|
|
if (pmdi) {
|
|
Dary_Term(&pmdi->daryDevs);
|
|
LocalFree(pmdi);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_RecalcClose
|
|
*
|
|
* Enable or disable the SC_CLOSE option accordingly.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void INTERNAL
|
|
Diq_RecalcClose(PMAINDLGINFO pmdi, HWND hdlg)
|
|
{
|
|
EnableMenuItem(GetSystemMenu(hdlg, 0), SC_CLOSE,
|
|
MF_BYCOMMAND |
|
|
(pmdi->cDevs ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnGetStatus
|
|
*
|
|
* Somebody asked for the status of the device.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnGetStatus(HWND hdlg)
|
|
{
|
|
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
|
|
int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
|
|
|
|
if ((UINT)iSel < (UINT)pmdi->daryDevs.cx) {
|
|
|
|
LPDIRECTINPUTA pdia;
|
|
HRESULT hres;
|
|
UINT didc;
|
|
int ids;
|
|
|
|
didc = GetCheckedRadioButton(hdlg,
|
|
IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
|
|
|
|
hres = CreateDI(IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
|
|
IsUnicodeDidc(didc),
|
|
(PPV)&pdia);
|
|
|
|
if (SUCCEEDED(hres)) {
|
|
LPDIDEVICEINSTANCE pdidi;
|
|
pdidi = Dary_GetPtr(&pmdi->daryDevs, iSel, DIDEVICEINSTANCE);
|
|
|
|
hres = IDirectInput_GetDeviceStatus(pdia,
|
|
&pdidi->guidInstance);
|
|
|
|
switch (hres) {
|
|
case DI_OK: ids = IDS_GETSTAT_OK; break;
|
|
case DI_NOTATTACHED: ids = IDS_GETSTAT_NOTATTACHED; break;
|
|
default: ids = IDS_GETSTAT_ERROR; break;
|
|
}
|
|
|
|
} else {
|
|
ids = IDS_GETSTAT_ERROR;
|
|
}
|
|
MessageBoxV(hdlg, ids, hres);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnCreateObject
|
|
*
|
|
* Somebody asked us to create an object. Party!
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnCreateObject(HWND hdlg)
|
|
{
|
|
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
|
|
int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
|
|
|
|
//#ifdef DEBUG
|
|
if (IsDlgButtonChecked(hdlg, IDC_MAIN_DIDJC)) {
|
|
if (Cpl_Create(hdlg,
|
|
IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
|
|
IsDlgButtonChecked(hdlg, IDC_MAIN_DIW))) {
|
|
pmdi->cBusy++;
|
|
pmdi->cDevs++;
|
|
RecalcCursor(hdlg);
|
|
Diq_RecalcClose(pmdi, hdlg);
|
|
}
|
|
} else
|
|
//#endif
|
|
if ((UINT)iSel < (UINT)pmdi->daryDevs.cx) {
|
|
UINT didc;
|
|
LPDIDEVICEINSTANCE pdidi;
|
|
|
|
didc = GetCheckedRadioButton(hdlg,
|
|
IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
|
|
pdidi = Dary_GetPtr(&pmdi->daryDevs, iSel, DIDEVICEINSTANCE);
|
|
|
|
if (Dev_Create(hdlg,
|
|
IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
|
|
IsUnicodeDidc(didc),
|
|
&pdidi->guidInstance,
|
|
pdidi->tszInstanceName,
|
|
didc)) {
|
|
pmdi->cBusy++;
|
|
pmdi->cDevs++;
|
|
RecalcCursor(hdlg);
|
|
Diq_RecalcClose(pmdi, hdlg);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnFindDevice
|
|
*
|
|
* Display the "FindDevice" dialog.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnFindDevice(HWND hdlg)
|
|
{
|
|
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
|
|
UINT didc;
|
|
|
|
didc = GetCheckedRadioButton(hdlg,
|
|
IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
|
|
|
|
if (Find_Create(hdlg,
|
|
IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
|
|
IsDlgButtonChecked(hdlg, IDC_MAIN_DIW))) {
|
|
pmdi->cBusy++;
|
|
pmdi->cDevs++;
|
|
RecalcCursor(hdlg);
|
|
Diq_RecalcClose(pmdi, hdlg);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnControlPanel
|
|
*
|
|
* Run the DirectInput control panel using the indicated interface.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnControlPanel(HWND hdlg)
|
|
{
|
|
HRESULT hres;
|
|
LPDIRECTINPUTA pdia;
|
|
|
|
hres = CreateDI(IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
|
|
IsDlgButtonChecked(hdlg, IDC_MAIN_DIW),
|
|
(PPV)&pdia);
|
|
if (SUCCEEDED(hres)) {
|
|
hres = pdia->lpVtbl->RunControlPanel(pdia, hdlg, 0);
|
|
if (SUCCEEDED(hres)) {
|
|
} else {
|
|
MessageBoxV(hdlg, IDS_ERR_RUNCPL, hres);
|
|
}
|
|
pdia->lpVtbl->Release(pdia);
|
|
} else {
|
|
MessageBoxV(hdlg, IDS_ERR_CREATEOBJ, hres);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnRefresh
|
|
*
|
|
* Refresh the device list.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnRefresh(HWND hdlg)
|
|
{
|
|
if (DialogBox(g_hinst, MAKEINTRESOURCE(IDD_ENUMDEV),
|
|
hdlg, DEnum_DlgProc) > 0) {
|
|
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
|
|
Diq_EnumDevices(pmdi);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnCommand
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INLINE
|
|
Diq_OnCommand(HWND hdlg, int id, UINT cmd)
|
|
{
|
|
switch (id) {
|
|
|
|
case IDC_MAIN_GETSTAT:return Diq_OnGetStatus(hdlg);
|
|
case IDC_MAIN_CREATE: return Diq_OnCreateObject(hdlg);
|
|
case IDC_MAIN_CPL: return Diq_OnControlPanel(hdlg);
|
|
case IDC_MAIN_FIND: return Diq_OnFindDevice(hdlg);
|
|
case IDC_MAIN_REFRESH:return Diq_OnRefresh(hdlg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnChildExit
|
|
*
|
|
* A client device has exited. Decrement the dev count.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnChildExit(PMAINDLGINFO pmdi, HWND hdlg)
|
|
{
|
|
if (pmdi) {
|
|
pmdi->cDevs--;
|
|
if (pmdi->cDevs == 0) {
|
|
Diq_RecalcClose(pmdi, hdlg);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnThreadStarted
|
|
*
|
|
* A worker thread has finished starting. Decrement our busy count.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnThreadStarted(PMAINDLGINFO pmdi, HWND hdlg)
|
|
{
|
|
if (pmdi) {
|
|
pmdi->cBusy--;
|
|
if (pmdi->cBusy == 0) { /* Set the cursor back if it's us */
|
|
RecalcCursor(hdlg);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_OnSetCursor
|
|
*
|
|
* Set the cursor to match our pending thread create count.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL INTERNAL
|
|
Diq_OnSetCursor(PMAINDLGINFO pmdi, HWND hdlg, WPARAM wp, LPARAM lp)
|
|
{
|
|
if (LOWORD(lp) == HTCLIENT && pmdi->cBusy) {
|
|
SetCursor(g_hcurStarting);
|
|
return SetDlgMsgResult(hdlg, WM_SETCURSOR, 1);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Diq_DlgProc
|
|
*
|
|
*****************************************************************************/
|
|
|
|
INT_PTR CALLBACK
|
|
Diq_DlgProc(HWND hdlg, UINT wm, WPARAM wp, LPARAM lp)
|
|
{
|
|
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
|
|
switch (wm) {
|
|
case WM_INITDIALOG: return Diq_OnInitDialog(hdlg);
|
|
case WM_DESTROY: return Diq_OnDestroy(pmdi, hdlg);
|
|
|
|
case WM_CLOSE: EndDialog(hdlg, 0); break;
|
|
|
|
case WM_COMMAND:
|
|
return Diq_OnCommand(hdlg,
|
|
(int)GET_WM_COMMAND_ID(wp, lp),
|
|
(UINT)GET_WM_COMMAND_CMD(wp, lp));
|
|
|
|
case WM_SETCURSOR:
|
|
return Diq_OnSetCursor(pmdi, hdlg, wp, lp);
|
|
|
|
case WM_THREADSTARTED:
|
|
return Diq_OnThreadStarted(pmdi, hdlg);
|
|
|
|
case WM_CHILDEXIT:
|
|
return Diq_OnChildExit(pmdi, hdlg);
|
|
}
|
|
return 0;
|
|
}
|