ArcanumKnightsKeyConfig.zip/DxLibKeyConfig/main.cpp
#include <limits.h>
#include <Windows.h>
#include <WinError.h>
#include <atlbase.h>
#include <atlapp.h>
#include <atlwin.h>
#include <atlcrack.h>
#include <atlctrls.h>
#include "resource.h"
#include "Consts.h"
#pragma comment(lib, "winmm.lib")
class CMainForm : public CDialogImpl<CMainForm> {
public:
enum {
IDD = IDD_MAINFORM,
};
private:
enum Timers {
TID_TIMER,
};
CEdit edits[4];
unsigned int buttons[4];
BEGIN_MSG_MAP(CMainForm)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_CLOSE(OnClose)
MSG_WM_DESTROY(OnDestroy)
COMMAND_ID_HANDLER_EX(IDOK, OnOK)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
MSG_WM_TIMER(OnTimer)
END_MSG_MAP()
CMainForm() {
}
LRESULT OnInitDialog(HWND hWnd, LPARAM lParam) {
edits[0] = GetDlgItem(IDC_EDIT1);
edits[1] = GetDlgItem(IDC_EDIT2);
edits[2] = GetDlgItem(IDC_EDIT3);
edits[3] = GetDlgItem(IDC_EDIT4);
edits[0].SetFocus();
for (unsigned int i = 0; i < _countof(edits); i++) {
SetButton(i, GetIniInt(INI_KEY_LIST[i], INI_DEFAULT_VALUE_LIST[i]));
}
SetTimer(TID_TIMER, 1000 / 60);
return 0;
}
void OnClose() {
DestroyWindow();
}
void OnDestroy() {
::PostQuitMessage(0);
}
void OnOK(UINT uNotifyCode, int nID, HWND hWndCtl) {
for (unsigned int i = 0; i < _countof(edits); i++) {
WriteIniInt(INI_KEY_LIST[i], buttons[i]);
}
DestroyWindow();
}
void OnCancel(UINT uNotifyCode, int nID, HWND hWndCtl) {
DestroyWindow();
}
void OnTimer(UINT_PTR nIDEvent) {
static JOYINFOEX prev = {0};
JOYINFOEX info;
info.dwSize = sizeof(info);
info.dwFlags = JOY_RETURNALL;
if (JOYERR_NOERROR != ::joyGetPosEx(JOYSTICKID1, &info)) {
return;
}
if (prev.dwSize == 0) {
prev = info;
return;
}
for (unsigned int i = 0; i < 24; i++) {
if ((info.dwButtons & (1 << i)) != 0 && (prev.dwButtons & (1 << i)) == 0) {
SetButton(GetFocusIndex(), i);
NextFocus();
break;
}
}
prev = info;
}
void SetButton(const unsigned int index, const unsigned int buttonId) {
if (index >= _countof(edits)) {
return;
}
buttons[index] = buttonId;
char displayName[64];
::sprintf(displayName, "Pad%d", buttonId + 1);
edits[index].SetWindowTextA(displayName);
}
unsigned int GetFocusIndex() const {
CWindow wnd = GetFocus();
for (unsigned int i = 0; i < _countof(edits); i++) {
if (wnd == edits[i]) {
return i;
}
}
return UINT_MAX;
}
void NextFocus() {
const unsigned int index = GetFocusIndex();
if (index >= _countof(edits)) {
return;
}
edits[(index + 1) % 4].SetFocus();
}
unsigned int GetIniInt(const char * const key, const unsigned int defaultValue) const {
char defaultString[32];
::sprintf(defaultString, "%d", defaultValue);
char result[32];
::GetPrivateProfileString(INI_SECTION_NAME, key, defaultString, result, _countof(result), GetIniFullPath());
return ::atoi(result);
}
bool WriteIniInt(const char * const key, const unsigned int value) const {
char valueString[32];
::sprintf(valueString, "%d", value);
return ::WritePrivateProfileStringA(INI_SECTION_NAME, key, valueString, GetIniFullPath()) != 0;
}
const char *GetIniFullPath() const {
static char result[MAX_PATH] = "";
if (result[0] == '\0') {
::GetCurrentDirectoryA(_countof(result), result);
::PathAppendA(result, INI_FILENAME);
}
return result;
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
CAppModule _Module;
_Module.Init(NULL, hInstance);
CMessageLoop theLoop;
_Module.AddMessageLoop(&theLoop);
CMainForm wnd;
wnd.Create(NULL, CWindow::rcDefault, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
const int nRet = theLoop.Run();
_Module.RemoveMessageLoop();
_Module.Term();
return nRet;
}