LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { if (pCtrlDlgState->pCtrlMap->GetTargetDevice() == CONTROLS_KEYBOARD_INDEX) { HWND hEdit = GetFocus(); UINT nCtrlID = GetDlgCtrlID(hEdit); if (nCtrlID < CONTROLS_IDC_EDIT_BIGIN || nCtrlID > CONTROLS_IDC_EDIT_END) { return CallNextHookEx(pCtrlDlgState->pKeydownHook, nCode, wParam, lParam); } if (!(lParam&(1<<31))) { // key down HWND hDlg = GetParent(hEdit); const char *str = getVirtualKeyName(wParam); if (str) { if (nCtrlID >= IDC_EDIT_KEY_ANALOG_UP) { pCtrlDlgState->pCtrlMap->SetBindCode(wParam, CONTROLS_KEYBOARD_ANALOG_INDEX, nCtrlID - IDC_EDIT_KEY_ANALOG_UP); } else { pCtrlDlgState->pCtrlMap->SetBindCode(wParam); } SetWindowTextA(hEdit, str); RECT rc = getRedrawRect(hEdit); InvalidateRect(hDlg, &rc, false); } else MessageBoxA(hDlg, "Not supported!", "controller", MB_OK); } } return 1; }
LRESULT CALLBACK ButtonsEditProc(HWND hEdit, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_RBUTTONUP: { UINT nCtrlID = GetDlgCtrlID(hEdit); int deviceIdx = TabCtrl_GetCurSel(pCtrlDlgState->hCtrlTab); if (deviceIdx != CONTROLS_KEYBOARD_INDEX && nCtrlID >= IDC_EDIT_KEY_ANALOG_UP) return TRUE; HMENU hSubMenu = GetSubMenu(g_hPopupMenus, 4); POINT pos; pos.x = LOWORD(lParam); pos.y = HIWORD(lParam); ClientToScreen(hEdit, &pos); switch(TrackPopupMenuEx(GetSubMenu(g_hPopupMenus, 4), TPM_RETURNCMD, pos.x, pos.y, hEdit, NULL)) { case ID_CONTROLS_KEY_DISABLE: { if (nCtrlID < IDC_EDIT_KEY_ANALOG_UP) { pCtrlDlgState->pCtrlMap->SetDisableBind(deviceIdx, nCtrlID - CONTROLS_IDC_EDIT_BEGIN); } else if (deviceIdx == CONTROLS_KEYBOARD_INDEX) { pCtrlDlgState->pCtrlMap->SetDisableBind( CONTROLS_KEYBOARD_ANALOG_INDEX, nCtrlID - IDC_EDIT_KEY_ANALOG_UP); } SetWindowTextA(hEdit, "Disable"); RECT rc = getRedrawRect(hEdit); HWND hDlg = GetParent(hEdit); InvalidateRect(hDlg, &rc, false); break; } default: break; } return TRUE; } default : break; } return CallWindowProc(pCtrlDlgState->orgEditProc, hEdit, message, wParam, lParam); }
// Message handler for control box. LRESULT CALLBACK Controls(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: W32Util::CenterWindow(hDlg); { // IDC_EDIT_xxx is need continuous value to IDC_EDIT_KEY_ANALOG_RIGHT from IDC_EDIT_KEY_MENU. // it is total 16. // it is need the same order as the dinput_ctrl_map(and xinput/keyboard). if (CONTROLS_BUTTONS_COUNT != 16) { char mes[100]; snprintf(mes, 100, "CONTROLS_BUTTONS_COUNT(%d) is need 16.", CONTROLS_BUTTONS_COUNT); MessageBoxA(hDlg, mes, "Controls dialog init error.", MB_OK); } pCtrlDlgState = new ControlsDlgState(); ZeroMemory(pCtrlDlgState, sizeof(ControlsDlgState)); pCtrlDlgState->pCtrlMap = ControlMapping::CreateInstance(CONTROLS_BUTTONS_COUNT); if (!pCtrlDlgState->pCtrlMap) { MessageBoxA(hDlg, "Cannot Created ControlMapping instance.", "Controls dialog init error.", MB_OK); } pCtrlDlgState->pCtrlMap->SetTargetDevice(CONTROLS_KEYBOARD_INDEX); pCtrlDlgState->hCtrlTab = GetDlgItem(hDlg, IDC_TAB_INPUT_DEVICE); TCITEM tcItem; ZeroMemory(&tcItem, sizeof(tcItem)); tcItem.mask = TCIF_TEXT; tcItem.dwState = 0; tcItem.pszText = "Keyboard"; tcItem.cchTextMax = (int)strlen(tcItem.pszText)+1; tcItem.iImage = 0; TabCtrl_InsertItem(pCtrlDlgState->hCtrlTab, TabCtrl_GetItemCount(pCtrlDlgState->hCtrlTab),&tcItem); tcItem.pszText = "DirectInput"; tcItem.cchTextMax = (int)strlen(tcItem.pszText)+1; TabCtrl_InsertItem(pCtrlDlgState->hCtrlTab, TabCtrl_GetItemCount(pCtrlDlgState->hCtrlTab),&tcItem); tcItem.pszText = "XInput"; tcItem.cchTextMax = (int)strlen(tcItem.pszText)+1; TabCtrl_InsertItem(pCtrlDlgState->hCtrlTab, TabCtrl_GetItemCount(pCtrlDlgState->hCtrlTab),&tcItem); int tp_w = 0, tp_h = 0; // TODO: connect to keyboard device instead { HBITMAP hResBM = LoadImageFromResource(hInst, MAKEINTRESOURCE(IDB_IMAGE_PSP), "IMAGE"); pCtrlDlgState->hStaticPspImage = GetDlgItem(hDlg,IDC_STATIC_IMAGE_PSP); RECT clientRect, tabPageRect, imgRect; GetClientRect(hDlg, &clientRect); memcpy(&tabPageRect, &clientRect, sizeof(RECT)); TabCtrl_AdjustRect(pCtrlDlgState->hCtrlTab, FALSE, &tabPageRect); tp_w = tabPageRect.right - tabPageRect.left; tp_h = tabPageRect.bottom - tabPageRect.top; MoveWindow(pCtrlDlgState->hStaticPspImage, tabPageRect.left, tabPageRect.top, tp_w, tp_h, FALSE); HDC hDC = GetDC(pCtrlDlgState->hStaticPspImage); HBITMAP hMemBM = CreateCompatibleBitmap(hDC, tp_w, tp_h); HDC hResDC = CreateCompatibleDC(hDC); HDC hMemDC = CreateCompatibleDC(hDC); SelectObject(hResDC, hResBM); SelectObject(hMemDC, hMemBM); BITMAP bm; GetObject(hResBM, sizeof(BITMAP), &bm); SetStretchBltMode(hMemDC, HALFTONE); float scaleX = (float)bm.bmWidth / clientRect.right; float scaleY = (float)bm.bmHeight / clientRect.bottom; imgRect.left = (int)(tabPageRect.left * scaleX); imgRect.top = (int)(tabPageRect.top * scaleY); imgRect.right= (int)(bm.bmWidth - ((clientRect.right - tabPageRect.right) * scaleX)); imgRect.bottom = (int)(bm.bmHeight - ((clientRect.bottom - tabPageRect.bottom) * scaleY)); StretchBlt(hMemDC, 0, 0, tp_w, tp_h, hResDC, imgRect.left, imgRect.top, imgRect.right - imgRect.left, imgRect.bottom - imgRect.top, SRCCOPY); if (pCtrlDlgState->hbmPspImage) DeleteObject(pCtrlDlgState->hbmPspImage); pCtrlDlgState->hbmPspImage = hMemBM; DeleteDC(hMemDC); DeleteDC(hResDC); ReleaseDC(pCtrlDlgState->hStaticPspImage, hDC); DeleteObject(hResBM); } for (u32 i = 0; i <= IDC_EDIT_KEYRIGHT - CONTROLS_IDC_EDIT_BIGIN; i++) { HWND hEdit = GetDlgItem(hDlg, CONTROLS_IDC_EDIT_BIGIN + i); SetWindowTextA(hEdit, getVirtualKeyName(pCtrlDlgState->pCtrlMap->GetBindCode(CONTROLS_KEYBOARD_INDEX, i))); } for (u32 i = 0; i <= CONTROLS_IDC_EDIT_END - IDC_EDIT_KEY_ANALOG_UP; i++) { HWND hEdit = GetDlgItem(hDlg, IDC_EDIT_KEY_ANALOG_UP + i); SetWindowTextA(hEdit, getVirtualKeyName(pCtrlDlgState->pCtrlMap->GetBindCode(CONTROLS_KEYBOARD_ANALOG_INDEX, i))); } ComboBox_AddString(GetDlgItem(hDlg, IDC_FORCE_INPUT_DEVICE), "None"); ComboBox_AddString(GetDlgItem(hDlg, IDC_FORCE_INPUT_DEVICE), "XInput"); ComboBox_AddString(GetDlgItem(hDlg, IDC_FORCE_INPUT_DEVICE), "DirectInput"); if ((g_Config.iForceInputDevice < 0) || (g_Config.iForceInputDevice > 1)) { ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_FORCE_INPUT_DEVICE), 0); } else { ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_FORCE_INPUT_DEVICE), (g_Config.iForceInputDevice + 1)); } pCtrlDlgState->orgPSPImageProc = (WNDPROC)GetWindowLongPtr(pCtrlDlgState->hStaticPspImage, GWLP_WNDPROC); SetWindowLongPtr(pCtrlDlgState->hStaticPspImage, GWLP_WNDPROC, (LONG_PTR)PSPImageProc); DWORD dwThreadID = GetWindowThreadProcessId(hDlg, NULL); pCtrlDlgState->pKeydownHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, dwThreadID); pCtrlDlgState->timerId = SetTimer(hDlg, TIMER_CONTROLS_BINDUPDATE, BINDUPDATE_INTERVAL_MS, 0); } return TRUE; case WM_TIMER: { if (wParam == TIMER_CONTROLS_BINDUPDATE && pCtrlDlgState->pCtrlMap->GetTargetDevice() != CONTROLS_KEYBOARD_INDEX) { HWND hEdit = GetFocus(); UINT nCtrlID = GetDlgCtrlID(hEdit); if (nCtrlID < CONTROLS_IDC_EDIT_BIGIN || nCtrlID > IDC_EDIT_KEYRIGHT) { break; } // device polling and update. int prevButton = pCtrlDlgState->pCtrlMap->GetBindCode(); pCtrlDlgState->pCtrlMap->UpdateState(); char str[CONTROLS_BUTTONNAME_MAX]; ZeroMemory(str, CONTROLS_BUTTONNAME_MAX * sizeof(char)); int buttonCode = pCtrlDlgState->pCtrlMap->GetBindCode(); if (buttonCode == -1 || prevButton == buttonCode) break; switch(pCtrlDlgState->pCtrlMap->GetTargetDevice()) { case CONTROLS_KEYBOARD_INDEX: { ; // leave it to KeyboardProc. } break; case CONTROLS_DIRECT_INPUT_INDEX: { if (buttonCode > 0xFF) { int n = 1; for (int i = buttonCode >> 8; i > 1; i >>= 1) { n++; } snprintf(str, CONTROLS_BUTTONNAME_MAX, "%s", controllist[(IDC_EDIT_KEYUP - CONTROLS_IDC_EDIT_BIGIN - 1) + n]); } else { snprintf(str, CONTROLS_BUTTONNAME_MAX, "%d", buttonCode + 1); } SetWindowTextA(hEdit, str); RECT rc = getRedrawRect(hEdit); InvalidateRect(hDlg, &rc, FALSE); } break; case CONTROLS_XINPUT_INDEX: { SetWindowText(hEdit, getXinputButtonName(buttonCode)); RECT rc = getRedrawRect(hEdit); InvalidateRect(hDlg, &rc, FALSE); } break; } }