From: Rémi Bernon rbernon@codeweavers.com
--- dlls/joy.cpl/dinput.c | 228 +++++++++++++++++++++---------------- dlls/joy.cpl/joy.rc | 3 + dlls/joy.cpl/joy_private.h | 6 + dlls/joy.cpl/main.c | 24 ++++ dlls/joy.cpl/resource.h | 3 + dlls/joy.cpl/wginput.c | 138 +++++++++++++++++++++- 6 files changed, 299 insertions(+), 103 deletions(-)
diff --git a/dlls/joy.cpl/dinput.c b/dlls/joy.cpl/dinput.c index a536fd167a1..68268cbb72c 100644 --- a/dlls/joy.cpl/dinput.c +++ b/dlls/joy.cpl/dinput.c @@ -309,7 +309,7 @@ static DWORD WINAPI input_thread( void *param ) return 0; }
-static void draw_axis_view( HDC hdc, RECT rect, const WCHAR *name, LONG value ) +static void draw_axis_view( HDC hdc, RECT rect, const WCHAR *name, double value ) { POINT center = { @@ -317,7 +317,7 @@ static void draw_axis_view( HDC hdc, RECT rect, const WCHAR *name, LONG value ) .y = (rect.top + rect.bottom) / 2, }; LONG w = (rect.bottom - rect.top + 1) / 3; - LONG x = rect.left + 20 + (w + 1) / 2 + MulDiv( value, rect.right - rect.left - 20 - w, 0xffff ); + LONG x = rect.left + 20 + (w + 1) / 2 + value * (rect.right - rect.left - 20 - w); COLORREF color; HFONT font;
@@ -354,6 +354,53 @@ static void draw_axis_view( HDC hdc, RECT rect, const WCHAR *name, LONG value ) } }
+void paint_axes_view( HWND hwnd, UINT32 count, double *axes, const WCHAR **names ) +{ + RECT rect, tmp_rect; + PAINTSTRUCT paint; + HDC hdc; + + hdc = BeginPaint( hwnd, &paint ); + + GetClientRect( hwnd, &rect ); + rect.bottom = rect.top + (rect.bottom - rect.top - 2) / 4 - 2; + rect.right = rect.left + (rect.right - rect.left) / 2 - 10; + + OffsetRect( &rect, 5, 2 ); + draw_axis_view( hdc, rect, names[0], axes[0] ); + + tmp_rect = rect; + OffsetRect( &rect, rect.right - rect.left + 10, 0 ); + draw_axis_view( hdc, rect, names[4], axes[4] ); + rect = tmp_rect; + + OffsetRect( &rect, 0, rect.bottom - rect.top + 2 ); + draw_axis_view( hdc, rect, names[1], axes[1] ); + + tmp_rect = rect; + OffsetRect( &rect, rect.right - rect.left + 10, 0 ); + draw_axis_view( hdc, rect, names[5], axes[5] ); + rect = tmp_rect; + + OffsetRect( &rect, 0, rect.bottom - rect.top + 2 ); + draw_axis_view( hdc, rect, names[2], axes[2] ); + + tmp_rect = rect; + OffsetRect( &rect, rect.right - rect.left + 10, 0 ); + draw_axis_view( hdc, rect, names[6], axes[6] ); + rect = tmp_rect; + + OffsetRect( &rect, 0, rect.bottom - rect.top + 2 ); + draw_axis_view( hdc, rect, names[3], axes[3] ); + + tmp_rect = rect; + OffsetRect( &rect, rect.right - rect.left + 10, 0 ); + draw_axis_view( hdc, rect, names[7], axes[7] ); + rect = tmp_rect; + + EndPaint( hwnd, &paint ); +} + static void draw_pov_view( HDC hdc, RECT rect, DWORD value ) { POINT points[] = @@ -407,6 +454,30 @@ static void draw_pov_view( HDC hdc, RECT rect, DWORD value ) if (value != -1) Polygon( hdc, points + value / 4500 * 2, 3 ); }
+void paint_povs_view( HWND hwnd, UINT32 count, UINT32 *povs ) +{ + PAINTSTRUCT paint; + RECT rect; + HDC hdc; + + hdc = BeginPaint( hwnd, &paint ); + + GetClientRect( hwnd, &rect ); + rect.bottom = rect.top + (rect.bottom - rect.top - 5) / 2 - 5; + rect.right = rect.left + (rect.bottom - rect.top); + + OffsetRect( &rect, 5, 5 ); + draw_pov_view( hdc, rect, povs[0] ); + OffsetRect( &rect, rect.right - rect.left + 5, 0 ); + draw_pov_view( hdc, rect, povs[1] ); + OffsetRect( &rect, rect.left - rect.right - 5, rect.bottom - rect.top + 5 ); + draw_pov_view( hdc, rect, povs[1] ); + OffsetRect( &rect, rect.right - rect.left + 5, 0 ); + draw_pov_view( hdc, rect, povs[2] ); + + EndPaint( hwnd, &paint ); +} + static void draw_button_view( HDC hdc, RECT rect, BOOL set, const WCHAR *name ) { COLORREF color; @@ -432,18 +503,58 @@ static void draw_button_view( HDC hdc, RECT rect, BOOL set, const WCHAR *name ) SelectObject( hdc, font ); }
+void paint_buttons_view( HWND hwnd, UINT32 count, BYTE *buttons ) +{ + UINT i, j, offs, size, step, space = 2; + PAINTSTRUCT paint; + RECT rect; + HDC hdc; + + if (count <= 48) step = 16; + else step = 24; + + hdc = BeginPaint( hwnd, &paint ); + + GetClientRect( hwnd, &rect ); + FillRect( hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1) ); + + size = (rect.right - rect.left - space) / step; + offs = (rect.right - rect.left - step * size - space) / 2; + OffsetRect( &rect, offs, offs ); + rect.right = rect.left + size - space; + rect.bottom = rect.top + size - space; + + for (i = 0; i < count;) + { + RECT first = rect; + + for (j = 0; j < step && i < count; j++, i++) + { + WCHAR buffer[3]; + if (step == 24) swprintf( buffer, ARRAY_SIZE(buffer), L"%02x", i ); + else swprintf( buffer, ARRAY_SIZE(buffer), L"%d", i ); + draw_button_view( hdc, rect, buttons[i], buffer ); + OffsetRect( &rect, size, 0 ); + } + + rect = first; + OffsetRect( &rect, 0, size ); + } + + EndPaint( hwnd, &paint ); +} + LRESULT CALLBACK test_di_axes_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { TRACE( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam );
if (msg == WM_PAINT) { + static const WCHAR *names[] = { L"X", L"Y", L"Z", L"S", L"Rx", L"Ry", L"Rz", L"Rs" }; DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; + double axes[16], *axis = axes; IDirectInputDevice8W *device; DIJOYSTATE2 state = {0}; - RECT rect, tmp_rect; - PAINTSTRUCT paint; - HDC hdc;
if ((device = get_selected_device())) { @@ -452,46 +563,16 @@ LRESULT CALLBACK test_di_axes_window_proc( HWND hwnd, UINT msg, WPARAM wparam, L IDirectInputDevice8_Release( device ); }
- hdc = BeginPaint( hwnd, &paint ); - - GetClientRect( hwnd, &rect ); - rect.bottom = rect.top + (rect.bottom - rect.top - 2) / 4 - 2; - rect.right = rect.left + (rect.right - rect.left) / 2 - 10; - - OffsetRect( &rect, 5, 2 ); - draw_axis_view( hdc, rect, L"X", state.lX ); - - tmp_rect = rect; - OffsetRect( &rect, rect.right - rect.left + 10, 0 ); - draw_axis_view( hdc, rect, L"Rx", state.lRx ); - rect = tmp_rect; - - OffsetRect( &rect, 0, rect.bottom - rect.top + 2 ); - draw_axis_view( hdc, rect, L"Y", state.lY ); - - tmp_rect = rect; - OffsetRect( &rect, rect.right - rect.left + 10, 0 ); - draw_axis_view( hdc, rect, L"Ry", state.lRy ); - rect = tmp_rect; - - OffsetRect( &rect, 0, rect.bottom - rect.top + 2 ); - draw_axis_view( hdc, rect, L"Z", state.lZ ); - - tmp_rect = rect; - OffsetRect( &rect, rect.right - rect.left + 10, 0 ); - draw_axis_view( hdc, rect, L"Rz", state.lRz ); - rect = tmp_rect; - - OffsetRect( &rect, 0, rect.bottom - rect.top + 2 ); - draw_axis_view( hdc, rect, L"S", state.rglSlider[0] ); - - tmp_rect = rect; - OffsetRect( &rect, rect.right - rect.left + 10, 0 ); - draw_axis_view( hdc, rect, L"Rs", state.rglSlider[1] ); - rect = tmp_rect; - - EndPaint( hwnd, &paint ); + *axis++ = (double)state.lX / 65535.0; + *axis++ = (double)state.lY / 65535.0; + *axis++ = (double)state.lZ / 65535.0; + *axis++ = (double)state.rglSlider[0] / 65535.0; + *axis++ = (double)state.lRx / 65535.0; + *axis++ = (double)state.lRy / 65535.0; + *axis++ = (double)state.lRz / 65535.0; + *axis++ = (double)state.rglSlider[1] / 65535.0;
+ paint_axes_view( hwnd, min( caps.dwAxes, ARRAY_SIZE(axes) ), axes, names ); return 0; }
@@ -507,9 +588,6 @@ LRESULT CALLBACK test_di_povs_window_proc( HWND hwnd, UINT msg, WPARAM wparam, L DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; IDirectInputDevice8W *device; DIJOYSTATE2 state = {0}; - PAINTSTRUCT paint; - RECT rect; - HDC hdc;
if ((device = get_selected_device())) { @@ -518,23 +596,7 @@ LRESULT CALLBACK test_di_povs_window_proc( HWND hwnd, UINT msg, WPARAM wparam, L IDirectInputDevice8_Release( device ); }
- hdc = BeginPaint( hwnd, &paint ); - - GetClientRect( hwnd, &rect ); - rect.bottom = rect.top + (rect.bottom - rect.top - 5) / 2 - 5; - rect.right = rect.left + (rect.bottom - rect.top); - - OffsetRect( &rect, 5, 5 ); - draw_pov_view( hdc, rect, state.rgdwPOV[0] ); - OffsetRect( &rect, rect.right - rect.left + 5, 0 ); - draw_pov_view( hdc, rect, state.rgdwPOV[1] ); - OffsetRect( &rect, rect.left - rect.right - 5, rect.bottom - rect.top + 5 ); - draw_pov_view( hdc, rect, state.rgdwPOV[1] ); - OffsetRect( &rect, rect.right - rect.left + 5, 0 ); - draw_pov_view( hdc, rect, state.rgdwPOV[2] ); - - EndPaint( hwnd, &paint ); - + paint_povs_view( hwnd, caps.dwPOVs, (UINT32 *)state.rgdwPOV ); return 0; }
@@ -548,12 +610,8 @@ LRESULT CALLBACK test_di_buttons_window_proc( HWND hwnd, UINT msg, WPARAM wparam if (msg == WM_PAINT) { DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; - UINT i, j, offs, size, step, space = 2; IDirectInputDevice8W *device; DIJOYSTATE2 state = {0}; - PAINTSTRUCT paint; - RECT rect; - HDC hdc;
if ((device = get_selected_device())) { @@ -562,39 +620,7 @@ LRESULT CALLBACK test_di_buttons_window_proc( HWND hwnd, UINT msg, WPARAM wparam IDirectInputDevice8_Release( device ); }
- if (caps.dwButtons <= 48) step = 16; - else step = 24; - - hdc = BeginPaint( hwnd, &paint ); - - GetClientRect( hwnd, &rect ); - FillRect( hdc, &rect, (HBRUSH)(COLOR_WINDOW + 1) ); - - size = (rect.right - rect.left - space) / step; - offs = (rect.right - rect.left - step * size - space) / 2; - OffsetRect( &rect, offs, offs ); - rect.right = rect.left + size - space; - rect.bottom = rect.top + size - space; - - for (i = 0; i < ARRAY_SIZE(state.rgbButtons) && i < caps.dwButtons;) - { - RECT first = rect; - - for (j = 0; j < step && i < caps.dwButtons; j++, i++) - { - WCHAR buffer[3]; - if (step == 24) swprintf( buffer, ARRAY_SIZE(buffer), L"%02x", i ); - else swprintf( buffer, ARRAY_SIZE(buffer), L"%d", i ); - draw_button_view( hdc, rect, state.rgbButtons[i], buffer ); - OffsetRect( &rect, size, 0 ); - } - - rect = first; - OffsetRect( &rect, 0, size ); - } - - EndPaint( hwnd, &paint ); - + paint_buttons_view( hwnd, min( caps.dwButtons, ARRAY_SIZE(state.rgbButtons) ), state.rgbButtons ); return 0; }
diff --git a/dlls/joy.cpl/joy.rc b/dlls/joy.cpl/joy.rc index 452b5abf527..1eb62d86ab3 100644 --- a/dlls/joy.cpl/joy.rc +++ b/dlls/joy.cpl/joy.rc @@ -107,6 +107,9 @@ FONT 8, "Ms Shell Dlg" { COMBOBOX IDC_WGI_DEVICES, 15, 10, 150, 60, CBS_DROPDOWNLIST | CBS_HASSTRINGS COMBOBOX IDC_WGI_INTERFACE, 175, 10, 131, 60, CBS_DROPDOWNLIST | CBS_HASSTRINGS + GROUPBOX "Axes", IDC_WGI_AXES, 15, 30, 214, 60 + GROUPBOX "POVs", IDC_WGI_POVS, 246, 30, 60, 60 + GROUPBOX "Buttons", IDC_WGI_BUTTONS, 15, 100, 291, 86 GROUPBOX "", IDC_WGI_GAMEPAD, 15, 30, 291, 60 AUTOCHECKBOX "Rumble", IDC_WGI_RUMBLE, 260, 30, 40, 10 } diff --git a/dlls/joy.cpl/joy_private.h b/dlls/joy.cpl/joy_private.h index 94f651e130a..7c02096dd55 100644 --- a/dlls/joy.cpl/joy_private.h +++ b/dlls/joy.cpl/joy_private.h @@ -31,6 +31,9 @@
#include "resource.h"
+extern void paint_axes_view( HWND hwnd, UINT32 count, double *axes, const WCHAR **names ); +extern void paint_povs_view( HWND hwnd, UINT32 count, UINT32 *povs ); +extern void paint_buttons_view( HWND hwnd, UINT32 count, BYTE *buttons ); extern void paint_gamepad_view( HWND hwnd, XINPUT_STATE *state );
extern INT_PTR CALLBACK test_di_dialog_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); @@ -42,6 +45,9 @@ extern INT_PTR CALLBACK test_xi_dialog_proc( HWND hwnd, UINT msg, WPARAM wparam, extern LRESULT CALLBACK test_xi_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam );
extern INT_PTR CALLBACK test_wgi_dialog_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); +extern LRESULT CALLBACK test_wgi_axes_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); +extern LRESULT CALLBACK test_wgi_povs_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); +extern LRESULT CALLBACK test_wgi_buttons_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); extern LRESULT CALLBACK test_wgi_gamepad_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam );
#endif /* __JOY_PRIVATE_H */ diff --git a/dlls/joy.cpl/main.c b/dlls/joy.cpl/main.c index 8cd51bcc5bf..d667ae6b5b0 100644 --- a/dlls/joy.cpl/main.c +++ b/dlls/joy.cpl/main.c @@ -518,6 +518,24 @@ static void register_window_class(void) .lpfnWndProc = &test_di_buttons_window_proc, .lpszClassName = L"JoyCplDInputButtons", }; + WNDCLASSW wgi_axes_class = + { + .hInstance = hcpl, + .lpfnWndProc = &test_wgi_axes_window_proc, + .lpszClassName = L"JoyCplWGIAxes", + }; + WNDCLASSW wgi_povs_class = + { + .hInstance = hcpl, + .lpfnWndProc = &test_wgi_povs_window_proc, + .lpszClassName = L"JoyCplWGIPOVs", + }; + WNDCLASSW wgi_buttons_class = + { + .hInstance = hcpl, + .lpfnWndProc = &test_wgi_buttons_window_proc, + .lpszClassName = L"JoyCplWGIButtons", + }; WNDCLASSW wgi_gamepad_class = { .hInstance = hcpl, @@ -529,11 +547,17 @@ static void register_window_class(void) RegisterClassW( &di_axes_class ); RegisterClassW( &di_povs_class ); RegisterClassW( &di_buttons_class ); + RegisterClassW( &wgi_axes_class ); + RegisterClassW( &wgi_povs_class ); + RegisterClassW( &wgi_buttons_class ); RegisterClassW( &wgi_gamepad_class ); }
static void unregister_window_class(void) { + UnregisterClassW( L"JoyCplWGIAxes", hcpl ); + UnregisterClassW( L"JoyCplWGIPovs", hcpl ); + UnregisterClassW( L"JoyCplWGIButtons", hcpl ); UnregisterClassW( L"JoyCplWGIGamepad", hcpl ); UnregisterClassW( L"JoyCplDInputAxes", hcpl ); UnregisterClassW( L"JoyCplDInputPOVs", hcpl ); diff --git a/dlls/joy.cpl/resource.h b/dlls/joy.cpl/resource.h index c1782ba49b7..894fa016b66 100644 --- a/dlls/joy.cpl/resource.h +++ b/dlls/joy.cpl/resource.h @@ -74,6 +74,9 @@ #define IDC_WGI_INTERFACE 2301 #define IDC_WGI_GAMEPAD 2302 #define IDC_WGI_RUMBLE 2303 +#define IDC_WGI_AXES 2304 +#define IDC_WGI_POVS 2305 +#define IDC_WGI_BUTTONS 2306
#define ICO_MAIN 100
diff --git a/dlls/joy.cpl/wginput.c b/dlls/joy.cpl/wginput.c index 621d38ca693..aeab155781c 100644 --- a/dlls/joy.cpl/wginput.c +++ b/dlls/joy.cpl/wginput.c @@ -59,8 +59,11 @@ struct raw_controller_state { UINT64 timestamp; double axes[6]; + INT32 axes_count; boolean buttons[32]; + INT32 button_count; GameControllerSwitchPosition switches[4]; + INT32 switches_count; };
struct device_state @@ -184,6 +187,9 @@ static DWORD WINAPI input_thread_proc( void *param ) { struct device_state state = {.iid = &IID_IRawGameController}; struct raw_controller_state *current = &state.raw_controller; + IRawGameController_get_AxisCount( raw_controller, ¤t->axes_count ); + IRawGameController_get_ButtonCount( raw_controller, ¤t->button_count ); + IRawGameController_get_SwitchCount( raw_controller, ¤t->switches_count ); IRawGameController_GetCurrentReading( raw_controller, ARRAY_SIZE(current->buttons), current->buttons, ARRAY_SIZE(current->switches), current->switches, ARRAY_SIZE(current->axes), current->axes, ¤t->timestamp ); @@ -206,6 +212,81 @@ static DWORD WINAPI input_thread_proc( void *param ) return 0; }
+LRESULT CALLBACK test_wgi_axes_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + TRACE( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + + if (msg == WM_PAINT) + { + static const WCHAR *names[] = { L"#0", L"#1", L"#2", L"#3", L"#4", L"#5", L"#6", L"#7" }; + struct device_state state; + UINT32 count; + + get_device_state( &state ); + + count = min( state.raw_controller.axes_count, ARRAY_SIZE(state.raw_controller.axes) ); + paint_axes_view( hwnd, count, state.raw_controller.axes, names ); + return 0; + } + + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +LRESULT CALLBACK test_wgi_povs_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + TRACE( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + + if (msg == WM_PAINT) + { + struct device_state state; + UINT32 count, povs[ARRAY_SIZE(state.raw_controller.switches)]; + + get_device_state( &state ); + + for (int i = 0; i < ARRAY_SIZE(state.raw_controller.switches); i++) + { + if (i >= state.raw_controller.switches_count) povs[i] = -1; + else switch (state.raw_controller.switches[i]) + { + case GameControllerSwitchPosition_Center: povs[i] = -1; break; + case GameControllerSwitchPosition_Up: povs[i] = 0; break; + case GameControllerSwitchPosition_UpRight: povs[i] = 4500; break; + case GameControllerSwitchPosition_Right: povs[i] = 9000; break; + case GameControllerSwitchPosition_DownRight: povs[i] = 13500; break; + case GameControllerSwitchPosition_Down: povs[i] = 18000; break; + case GameControllerSwitchPosition_DownLeft: povs[i] = 22500; break; + case GameControllerSwitchPosition_Left: povs[i] = 27000; break; + case GameControllerSwitchPosition_UpLeft: povs[i] = 31500; break; + } + } + + count = min( state.raw_controller.switches_count, ARRAY_SIZE(povs) ); + paint_povs_view( hwnd, count, povs ); + return 0; + } + + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +LRESULT CALLBACK test_wgi_buttons_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + TRACE( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + + if (msg == WM_PAINT) + { + struct device_state state; + UINT32 count; + + get_device_state( &state ); + + count = min( state.raw_controller.button_count, ARRAY_SIZE(state.raw_controller.buttons) ); + paint_buttons_view( hwnd, count, state.raw_controller.buttons ); + return 0; + } + + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + LRESULT CALLBACK test_wgi_gamepad_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { TRACE( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); @@ -451,13 +532,32 @@ static void update_wgi_devices( HWND hwnd )
static void update_device_views( HWND hwnd ) { - HWND gamepad, rumble; + HWND gamepad, rumble, axes, povs, buttons; struct device_state state;
get_device_state( &state );
gamepad = GetDlgItem( hwnd, IDC_WGI_GAMEPAD ); rumble = GetDlgItem( hwnd, IDC_WGI_RUMBLE ); + axes = GetDlgItem( hwnd, IDC_WGI_AXES ); + povs = GetDlgItem( hwnd, IDC_WGI_POVS ); + buttons = GetDlgItem( hwnd, IDC_WGI_BUTTONS ); + + if (!IsEqualGUID( state.iid, &IID_IRawGameController )) + { + ShowWindow( axes, SW_HIDE ); + ShowWindow( povs, SW_HIDE ); + ShowWindow( buttons, SW_HIDE ); + } + else + { + InvalidateRect( axes, NULL, TRUE ); + InvalidateRect( povs, NULL, TRUE ); + InvalidateRect( buttons, NULL, TRUE ); + ShowWindow( axes, SW_SHOW ); + ShowWindow( povs, SW_SHOW ); + ShowWindow( buttons, SW_SHOW ); + }
if (!IsEqualGUID( state.iid, &IID_IGamepad )) { @@ -476,14 +576,48 @@ static void update_device_views( HWND hwnd ) static void create_device_views( HWND hwnd ) { HINSTANCE instance = (HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE ); - HWND gamepad, rumble; + HWND gamepad, rumble, axes, povs, buttons; LONG margin; RECT rect;
gamepad = GetDlgItem( hwnd, IDC_WGI_GAMEPAD ); rumble = GetDlgItem( hwnd, IDC_WGI_RUMBLE ); + axes = GetDlgItem( hwnd, IDC_WGI_AXES ); + povs = GetDlgItem( hwnd, IDC_WGI_POVS ); + buttons = GetDlgItem( hwnd, IDC_WGI_BUTTONS ); + ShowWindow( gamepad, SW_HIDE ); ShowWindow( rumble, SW_HIDE ); + ShowWindow( axes, SW_HIDE ); + ShowWindow( povs, SW_HIDE ); + ShowWindow( buttons, SW_HIDE ); + + GetClientRect( axes, &rect ); + rect.top += 10; + + margin = (rect.bottom - rect.top) * 10 / 100; + InflateRect( &rect, -margin, -margin ); + + CreateWindowW( L"JoyCplWGIAxes", NULL, WS_CHILD | WS_VISIBLE, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, axes, NULL, NULL, instance ); + + GetClientRect( povs, &rect ); + rect.top += 10; + + margin = (rect.bottom - rect.top) * 10 / 100; + InflateRect( &rect, -margin, -margin ); + + CreateWindowW( L"JoyCplWGIPOVs", NULL, WS_CHILD | WS_VISIBLE, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, povs, NULL, NULL, instance ); + + GetClientRect( buttons, &rect ); + rect.top += 10; + + margin = (rect.bottom - rect.top) * 5 / 100; + InflateRect( &rect, -margin, -margin ); + + CreateWindowW( L"JoyCplWGIButtons", NULL, WS_CHILD | WS_VISIBLE, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, buttons, NULL, NULL, instance );
GetClientRect( gamepad, &rect ); rect.top += 10;