Skip to content

Commit

Permalink
If hwnd is null, use main window for fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
elishacloud committed Nov 1, 2024
1 parent 91dcead commit a54e087
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 15 deletions.
2 changes: 1 addition & 1 deletion BuildNo.rc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define BUILD_NUMBER 78
#define BUILD_NUMBER 79
70 changes: 59 additions & 11 deletions IDirectInputDeviceX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,37 @@

#include "dinputto8.h"

const DIDATAFORMAT c_dfDIKeyboard = {
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDF_RELAXIS,
MAX_KEYBAORD,
sizeof(dfDIKeyboard) / sizeof(*dfDIKeyboard),
(LPDIOBJECTDATAFORMAT)dfDIKeyboard
};
HWND GetMainWindow()
{
struct ENUMEDATA
{
DWORD processId = GetCurrentProcessId();
HWND mainWindow = nullptr;
} WindowData;

EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL
{
DWORD wndProcessId;
GetWindowThreadProcessId(hwnd, &wndProcessId);
ENUMEDATA* WindowData = reinterpret_cast<ENUMEDATA*>(lParam);

if (wndProcessId == WindowData->processId && GetWindow(hwnd, GW_OWNER) == nullptr && IsWindowVisible(hwnd))
{
WindowData->mainWindow = hwnd;
return FALSE; // Stop enumerating once found
}

return TRUE;
}, reinterpret_cast<LPARAM>(&WindowData));

// Fallback to GetForegroundWindow if no suitable window is found
if (!WindowData.mainWindow)
{
WindowData.mainWindow = GetForegroundWindow();
}

return WindowData.mainWindow;
}

// Our EnumObjectDataLUT contains only abstract types AXIS, BUTTON and POV, so consider it a match if
// any bit of the type matches (e.g. DIDFT_AXIS is 3 while DIDFT_ABSAXIS is 1).
Expand Down Expand Up @@ -422,6 +445,10 @@ HRESULT m_IDirectInputDeviceX::SetProperty(REFGUID rguidProp, LPCDIPROPHEADER pd
{
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";

// Get rguidProp as a raw integer value, assuming it's not an actual GUID pointer
const int rguidBytes = (const int)reinterpret_cast<const BYTE*>(&rguidProp);
Logging::LogDebug() << __FUNCTION__ << " (" << this << ") Property Identifier: " << rguidBytes;

return ProxyInterface->SetProperty(rguidProp, pdiph);
}

Expand Down Expand Up @@ -533,19 +560,32 @@ HRESULT m_IDirectInputDeviceX::SetDataFormat(LPCDIDATAFORMAT lpdf)
std::vector<DIOBJECTDATAFORMAT> rgodf(lpdf->dwNumObjs);

const DIDATAFORMAT df {
sizeof(df),
lpdf->dwObjSize,
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
lpdf->dwFlags,
lpdf->dwDataSize,
lpdf->dwNumObjs,
rgodf.data() };

Logging::LogDebug() << __FUNCTION__ << " (" << this << ") "
<< " Size: " << lpdf->dwSize
<< " ObjSize: " << lpdf->dwObjSize
<< " Flags: " << Logging::hex(lpdf->dwFlags)
<< " DataSize: " << lpdf->dwDataSize
<< " NumObjs: " << lpdf->dwNumObjs;

for (DWORD x = 0; x < df.dwNumObjs; x++)
{
rgodf[x].pguid = lpdf->rgodf[x].pguid;
rgodf[x].dwOfs = lpdf->rgodf[x].dwOfs;
rgodf[x].dwType = ((lpdf->rgodf[x].dwType & DIDFT_ANYINSTANCE) == 0xFF00) ? lpdf->rgodf[x].dwType | DIDFT_ANYINSTANCE : lpdf->rgodf[x].dwType;
rgodf[x].dwFlags = lpdf->rgodf[x].dwFlags;

Logging::LogDebug() << __FUNCTION__ << " (" << this << ") -" << x << "-"
<< " GUID: " << rgodf[x].pguid
<< " Ofs: " << rgodf[x].dwOfs
<< " Type: " << Logging::hex(rgodf[x].dwType)
<< " Flags: " << Logging::hex(rgodf[x].dwFlags);
}

Offset = 0;
Expand Down Expand Up @@ -575,7 +615,15 @@ HRESULT m_IDirectInputDeviceX::SetEventNotification(HANDLE hEvent)

HRESULT m_IDirectInputDeviceX::SetCooperativeLevel(HWND hwnd, DWORD dwFlags)
{
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";
Logging::LogDebug() << __FUNCTION__ << " (" << this << ") hwnd: " << hwnd << " dwFlags: " << Logging::hex(dwFlags);

// If hwnd is null, assign the main application window as a fallback
if (!hwnd && IsMouse)
{
hwnd = GetMainWindow();
Logging::LogDebug() << __FUNCTION__ << " Warning: null hwnd, using: " << hwnd << (dwFlags & DISCL_FOREGROUND ? " Removing: DISCL_FOREGROUND" : "");
dwFlags = (dwFlags | DISCL_BACKGROUND) & ~DISCL_FOREGROUND;
}

return ProxyInterface->SetCooperativeLevel(hwnd, dwFlags);
}
Expand Down
2 changes: 1 addition & 1 deletion IDirectInputDeviceX.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class m_IDirectInputDeviceX : public AddressLookupTableDinputObject
// Vector to store instances of m_IDirectInputEffect
std::vector<m_IDirectInputEffect*> effects;

// For GetDeviceData
// For SetCooperativeLevel
bool IsMouse = false;

// Format memory
Expand Down
45 changes: 45 additions & 0 deletions IDirectInputTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,51 @@
#include "dinputto8.h"
#include <hidusage.h>

const DIDATAFORMAT c_dfDIKeyboard = {
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDF_RELAXIS,
MAX_KEYBAORD,
sizeof(dfDIKeyboard) / sizeof(*dfDIKeyboard),
(LPDIOBJECTDATAFORMAT)dfDIKeyboard
};

const DIDATAFORMAT c_dfDIMouse = {
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDF_RELAXIS,
sizeof(DIMOUSESTATE),
sizeof(dfDIMouse) / sizeof(*dfDIMouse),
(LPDIOBJECTDATAFORMAT)dfDIMouse
};

const DIDATAFORMAT c_dfDIMouse2 = {
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDF_RELAXIS,
sizeof(DIMOUSESTATE2),
sizeof(dfDIMouse2) / sizeof(*dfDIMouse2),
(LPDIOBJECTDATAFORMAT)dfDIMouse2
};

const DIDATAFORMAT c_dfDIJoystick = {
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDF_ABSAXIS,
sizeof(DIJOYSTATE),
sizeof(dfDIJoystick) / sizeof(*dfDIJoystick),
(LPDIOBJECTDATAFORMAT)dfDIJoystick
};

const DIDATAFORMAT c_dfDIJoystick2 = {
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDF_ABSAXIS,
sizeof(DIJOYSTATE2),
sizeof(dfDIJoystick2) / sizeof(*dfDIJoystick2),
(LPDIOBJECTDATAFORMAT)dfDIJoystick2
};

DWORD ConvertDevTypeTo7(DWORD dwDevType, WORD wUsagePage, WORD wUsage, BOOL isHID, BOOL& IsGamepad)
{
IsGamepad = FALSE;
Expand Down
2 changes: 1 addition & 1 deletion IDirectInputX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ template HRESULT m_IDirectInputX::CreateDeviceExX<IDirectInput8W, LPDIRECTINPUTD
template <class T, class V>
HRESULT m_IDirectInputX::CreateDeviceExX(REFGUID rguid, REFIID riid, V *ppvObj, LPUNKNOWN pUnkOuter)
{
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";
Logging::LogDebug() << __FUNCTION__ << " (" << this << ") " << rguid;

HRESULT hr = GetProxyInterface<T>()->CreateDevice(rguid, ppvObj, pUnkOuter);

Expand Down
Loading

0 comments on commit a54e087

Please sign in to comment.