diff --git a/StayAwake/SelectKeyCodesDlg.cpp b/StayAwake/SelectKeyCodesDlg.cpp
new file mode 100644
index 0000000..3106e01
--- /dev/null
+++ b/StayAwake/SelectKeyCodesDlg.cpp
@@ -0,0 +1,87 @@
+// CSelectKeyCodesDlg.cpp : implementation file
+//
+
+#include "pch.h"
+#include "StayAwake.h"
+#include "afxdialogex.h"
+#include "SelectKeyCodesDlg.h"
+
+static_assert(IDC_KEY_UNASSIGNED_10 - IDC_KEY_SCROLL_LOCK + 1 == LEN_KEYCODES_ROSTER, "Roster checkbox IDs must be consecutive");
+
+// CSelectKeyCodesDlg dialog
+
+IMPLEMENT_DYNAMIC(CSelectKeyCodesDlg, CDialogEx)
+
+CSelectKeyCodesDlg::CSelectKeyCodesDlg(CStayAwakeDlg* pCaller)
+ : CDialogEx(IDD_SELECT_KEYCODES_DIALOG, pCaller)
+ , m_pCaller(pCaller)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+CSelectKeyCodesDlg::~CSelectKeyCodesDlg()
+{
+}
+
+void CSelectKeyCodesDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CSelectKeyCodesDlg, CDialogEx)
+ ON_BN_CLICKED(IDC_KEY_SELECT_APPLY_BTN, &CSelectKeyCodesDlg::OnOK)
+ ON_BN_CLICKED(IDC_KEY_SELECT_ALL_BTN, &CSelectKeyCodesDlg::OnClickedKeySelectAllBtn)
+ ON_BN_CLICKED(IDC_KEY_SELECT_NONE_BTN, &CSelectKeyCodesDlg::OnClickedKeySelectNoneBtn)
+END_MESSAGE_MAP()
+
+
+BOOL CSelectKeyCodesDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ SetIcon(m_hIcon, TRUE); // Set big icon
+ SetIcon(m_hIcon, FALSE); // Set small icon
+
+ CheckAllBoxes(m_pCaller->GetSelectedKeyCodes());
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+void CSelectKeyCodesDlg::OnOK()
+{
+ wstring sSelectedKeyCodes{};
+
+ for (int i{}; i < LEN_KEYCODES_ROSTER; i++)
+ sSelectedKeyCodes += (IsDlgButtonChecked(IDC_KEY_SCROLL_LOCK + i)) ? L"1" : L"0";
+
+ if (sSelectedKeyCodes == wstring(LEN_KEYCODES_ROSTER, L'0'))
+ {
+ MessageBox(L"Please select at least one Key Code", L"Select multiple Key Codes", MB_ICONEXCLAMATION);
+ return;
+ }
+
+ if (!m_pCaller->SaveSelectedKeyCodes(sSelectedKeyCodes))
+ {
+ MessageBox(L"Unable to save to the StayAwake.ini file.", L"Select multiple Key Codes", MB_ICONEXCLAMATION);
+ return;
+ }
+
+ CDialogEx::OnOK();
+}
+
+void CSelectKeyCodesDlg::CheckAllBoxes(const wstring& sSelectedKeyCodes)
+{
+ for (int i{}; i < LEN_KEYCODES_ROSTER; i++)
+ CheckDlgButton(IDC_KEY_SCROLL_LOCK + i, sSelectedKeyCodes.at(i) == L'1');
+}
+
+void CSelectKeyCodesDlg::OnClickedKeySelectAllBtn()
+{
+ CheckAllBoxes(wstring(LEN_KEYCODES_ROSTER, L'1'));
+}
+
+void CSelectKeyCodesDlg::OnClickedKeySelectNoneBtn()
+{
+ CheckAllBoxes(wstring(LEN_KEYCODES_ROSTER, L'0'));
+}
diff --git a/StayAwake/SelectKeyCodesDlg.h b/StayAwake/SelectKeyCodesDlg.h
new file mode 100644
index 0000000..2a23998
--- /dev/null
+++ b/StayAwake/SelectKeyCodesDlg.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "Utils.h"
+#include "StayAwakeDlg.h"
+
+class CSelectKeyCodesDlg : public CDialogEx
+{
+ DECLARE_DYNAMIC(CSelectKeyCodesDlg)
+
+public:
+ explicit CSelectKeyCodesDlg(CStayAwakeDlg* pCaller);
+ virtual ~CSelectKeyCodesDlg();
+
+// Dialog Data
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_SELECT_KEYCODES_DIALOG };
+#endif
+
+protected:
+ CStayAwakeDlg* m_pCaller;
+ HICON m_hIcon;
+
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ virtual BOOL OnInitDialog();
+ afx_msg void OnClickedKeySelectAllBtn();
+ afx_msg void OnClickedKeySelectNoneBtn();
+ afx_msg void OnOK();
+
+ DECLARE_MESSAGE_MAP()
+
+private:
+ void CheckAllBoxes(const wstring& sSelectedKeyCodes);
+};
diff --git a/StayAwake/StayAwake.cpp b/StayAwake/StayAwake.cpp
index 4b3438b..05b9caf 100644
--- a/StayAwake/StayAwake.cpp
+++ b/StayAwake/StayAwake.cpp
@@ -36,7 +36,7 @@ BOOL CStayAwakeApp::InitInstance()
CStayAwakeDlg dlg;
m_pMainWnd = &dlg;
- INT_PTR nResponse = dlg.DoModal();
+ dlg.DoModal();
#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
ControlBarCleanUp();
diff --git a/StayAwake/StayAwake.h b/StayAwake/StayAwake.h
index 6ce67bc..dbb9e9f 100644
--- a/StayAwake/StayAwake.h
+++ b/StayAwake/StayAwake.h
@@ -6,7 +6,8 @@
#include "resource.h"
-#define LAST_CODE_UPDATE_TIME "Sep 17 2026 - 22:09:25"
+constexpr auto LAST_CODE_UPDATE_TIME = "Sep 19 2026 - 17:20:42";
+
class CStayAwakeApp : public CWinApp
{
diff --git a/StayAwake/StayAwake.rc b/StayAwake/StayAwake.rc
index 5bb70ce..c75652b 100644
Binary files a/StayAwake/StayAwake.rc and b/StayAwake/StayAwake.rc differ
diff --git a/StayAwake/StayAwake.vcxproj b/StayAwake/StayAwake.vcxproj
index 702da02..c9cac35 100644
--- a/StayAwake/StayAwake.vcxproj
+++ b/StayAwake/StayAwake.vcxproj
@@ -211,6 +211,7 @@
+
@@ -220,6 +221,7 @@
+
@@ -238,9 +240,7 @@
-
-
diff --git a/StayAwake/StayAwake.vcxproj.filters b/StayAwake/StayAwake.vcxproj.filters
index f1f6329..20383b7 100644
--- a/StayAwake/StayAwake.vcxproj.filters
+++ b/StayAwake/StayAwake.vcxproj.filters
@@ -39,6 +39,9 @@
Header Files
+
+ Header Files
+
@@ -56,6 +59,9 @@
Source Files
+
+ Source Files
+
@@ -71,12 +77,6 @@
Resource Files
-
- Resource Files
-
-
- Resource Files
-
Resource Files
diff --git a/StayAwake/StayAwakeDlg.cpp b/StayAwake/StayAwakeDlg.cpp
index ba45d76..3947d65 100644
--- a/StayAwake/StayAwakeDlg.cpp
+++ b/StayAwake/StayAwakeDlg.cpp
@@ -2,10 +2,14 @@
#include "framework.h"
#include "StayAwake.h"
#include "StayAwakeDlg.h"
+#include "SelectKeyCodesDlg.h"
#include "StayAwakeAboutDlg.h"
#include "afxdialogex.h"
#include "Utils.h"
+#include
+#pragma comment(lib, "Pathcch.lib")
+
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
@@ -22,6 +26,51 @@ void CStayAwakeDlg::DoDataExchange(CDataExchange* pDX)
CDialogEx::DoDataExchange(pDX);
}
+wstring CStayAwakeDlg::GetSelectedKeyCodes()
+{
+ const int bufSize{ LEN_KEYCODES_ROSTER + 1 };
+ wchar_t sBuf[bufSize]{};
+
+ GetPrivateProfileString(PREF_DEFAULTS, PREF_SELECTED_KEYCODES, L"N/A", sBuf, bufSize, m_IniFilePath);
+
+ wstring sKeyCodes{ sBuf };
+
+ if (sKeyCodes == L"N/A") {
+ UINT nLegacyKeyCode = GetPrivateProfileInt(PREF_DEFAULTS, PREF_LEGACY_KEYCODE, 99, m_IniFilePath);
+
+ if (nLegacyKeyCode == 99)
+ sKeyCodes = DEF_SELECTED_KEYCODES;
+ else
+ {
+ sKeyCodes = wstring(LEN_KEYCODES_ROSTER, L'0');
+ sKeyCodes.replace(nLegacyKeyCode % LEN_KEYCODES_ROSTER, 1, L"1");
+ }
+
+ WritePrivateProfileString(PREF_DEFAULTS, PREF_LEGACY_KEYCODE, nullptr, m_IniFilePath);
+ SaveSelectedKeyCodes(sKeyCodes);
+ }
+ else if (!CheckSelectedKeyCodes(sKeyCodes))
+ {
+ sKeyCodes = DEF_SELECTED_KEYCODES;
+ SaveSelectedKeyCodes(sKeyCodes);
+ }
+
+ return sKeyCodes;
+}
+
+bool CStayAwakeDlg::CheckSelectedKeyCodes(wstring sKeyCodes)
+{
+ return (sKeyCodes.length() == LEN_KEYCODES_ROSTER &&
+ sKeyCodes != wstring(LEN_KEYCODES_ROSTER, L'0') &&
+ sKeyCodes.find_first_not_of(L"01") == std::string::npos);
+}
+
+bool CStayAwakeDlg::SaveSelectedKeyCodes(wstring sKeyCodes)
+{
+ return CheckSelectedKeyCodes(sKeyCodes) &&
+ WritePrivateProfileString(PREF_DEFAULTS, PREF_SELECTED_KEYCODES, sKeyCodes.c_str(), m_IniFilePath);
+}
+
BEGIN_MESSAGE_MAP(CStayAwakeDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_MESSAGE(WM_POST_OPEN, &CStayAwakeDlg::OnPostOpen)
@@ -35,11 +84,11 @@ BEGIN_MESSAGE_MAP(CStayAwakeDlg, CDialogEx)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_MINIMIZE, &CStayAwakeDlg::OnMinimize)
ON_BN_CLICKED(IDC_EXIT, &CStayAwakeDlg::OnExit)
+ ON_BN_CLICKED(IDC_STAYAWAKE_KEYS_ROSTER_BTN, &CStayAwakeDlg::OnSetupKeyCodesRosterClicked)
ON_BN_CLICKED(IDC_STAYAWAKE_SET_INTERVAL_BTN, &CStayAwakeDlg::OnSetInterval)
ON_EN_KILLFOCUS(IDC_STAYAWAKE_INTERVAL_MIN, &CStayAwakeDlg::OnKillfocusIntervalMin)
ON_EN_KILLFOCUS(IDC_STAYAWAKE_INTERVAL_MAX, &CStayAwakeDlg::OnKillfocusIntervalMax)
ON_BN_CLICKED(IDC_ABOUT_BUTTON, &CStayAwakeDlg::OnClickedAboutButton)
- ON_CBN_SELCHANGE(IDC_STAYAWAKE_KEY_LIST, &CStayAwakeDlg::OnStayawakeKeyChange)
ON_BN_CLICKED(IDC_STAYAWAKE_PAUSE_RESUME_BTN, &CStayAwakeDlg::OnPauseResume)
ON_BN_CLICKED(IDC_START_MINIMIZED, &CStayAwakeDlg::OnStartMinimized)
END_MESSAGE_MAP()
@@ -76,19 +125,7 @@ BOOL CStayAwakeDlg::OnInitDialog()
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
- // Init KeyCodes List
- SendDlgItemMessage(IDC_STAYAWAKE_KEY_LIST, CB_ADDSTRING, NULL, (LPARAM)L"Scroll Lock cycling");
- SendDlgItemMessage(IDC_STAYAWAKE_KEY_LIST, CB_ADDSTRING, NULL, (LPARAM)L"Volume Down & Up");
-
- for (int i{ 1 }; i <= 10; i++) {
- SendDlgItemMessage(IDC_STAYAWAKE_KEY_LIST, CB_ADDSTRING, NULL, (LPARAM)(L"Unassigned Key #" + to_wstring(i)).c_str());
- }
-
- m_AwakeKeyCode = GetPrivateProfileInt(PREF_DEFAULTS, PREF_AWAKE_KEYCODE, m_AwakeKeyCode, PREF_INI_FILE);
- m_AwakeKeyCode %= 12;
-
- SendDlgItemMessage(IDC_STAYAWAKE_KEY_LIST, CB_SETCURSEL, m_AwakeKeyCode, NULL);
-
+ InitConfigFilePath();
InitIntervals();
SetDlgItemInt(IDC_STAYAWAKE_INTERVAL_MIN, m_IntervalMinSeconds, FALSE);
SetDlgItemInt(IDC_STAYAWAKE_INTERVAL_MAX, m_IntervalMaxSeconds, FALSE);
@@ -205,6 +242,17 @@ void CStayAwakeDlg::OnKillfocusIntervalMax()
}
+void CStayAwakeDlg::OnSetupKeyCodesRosterClicked()
+{
+ CSelectKeyCodesDlg dlgSelectKeyCodes(this);
+
+ if (dlgSelectKeyCodes.DoModal() == IDOK)
+ {
+ InitRoster();
+ if (!IsTimerPaused()) SimulateAwakeKeyPress();
+ }
+}
+
void CStayAwakeDlg::OnTimer(UINT_PTR nIDEvent)
{
SimulateAwakeKeyPress();
@@ -212,19 +260,33 @@ void CStayAwakeDlg::OnTimer(UINT_PTR nIDEvent)
}
+void CStayAwakeDlg::InitConfigFilePath()
+{
+ DWORD size = GetModuleFileNameW(nullptr, m_IniFilePath, MAX_PATH);
+
+ if (size > 0 && size < MAX_PATH &&
+ SUCCEEDED(PathCchRemoveFileSpec(m_IniFilePath, MAX_PATH)) &&
+ SUCCEEDED(PathCchAppend(m_IniFilePath, MAX_PATH, PREF_INI_FILE)))
+ return;
+
+ wcscpy_s(m_IniFilePath, MAX_PATH, L".\\"); // last resort: working directory
+ wcscat_s(m_IniFilePath, MAX_PATH, PREF_INI_FILE);
+}
+
+
void CStayAwakeDlg::InitIntervals()
{
int nIntervalLegacy{}, nIntervalMin{}, nIntervalMax{};
- nIntervalLegacy = GetPrivateProfileInt(PREF_DEFAULTS, PREF_INTERVAL_LEGACY, DEF_PERIOD, PREF_INI_FILE);
+ nIntervalLegacy = GetPrivateProfileInt(PREF_DEFAULTS, PREF_INTERVAL_LEGACY, DEF_PERIOD, m_IniFilePath);
if (nIntervalLegacy < MIN_PERIOD || nIntervalLegacy > MAX_PERIOD)
nIntervalLegacy = DEF_PERIOD;
- nIntervalMin = GetPrivateProfileInt(PREF_DEFAULTS, PREF_INTERVAL_MINIMUM, nIntervalLegacy, PREF_INI_FILE);
+ nIntervalMin = GetPrivateProfileInt(PREF_DEFAULTS, PREF_INTERVAL_MINIMUM, nIntervalLegacy, m_IniFilePath);
if (nIntervalMin < MIN_PERIOD || nIntervalMin > MAX_PERIOD)
nIntervalMin = DEF_PERIOD;
- nIntervalMax = GetPrivateProfileInt(PREF_DEFAULTS, PREF_INTERVAL_MAXIMUM, nIntervalLegacy, PREF_INI_FILE);
+ nIntervalMax = GetPrivateProfileInt(PREF_DEFAULTS, PREF_INTERVAL_MAXIMUM, nIntervalLegacy, m_IniFilePath);
if (nIntervalMax < MIN_PERIOD || nIntervalMax > MAX_PERIOD)
nIntervalMax = DEF_PERIOD;
@@ -232,12 +294,26 @@ void CStayAwakeDlg::InitIntervals()
m_IntervalMaxSeconds = (nIntervalMin >= nIntervalMax) ? nIntervalMin : nIntervalMax;
}
+void CStayAwakeDlg::InitRoster()
+{
+ wstring sSelectedKeyCodes{ GetSelectedKeyCodes() };
+
+ m_RosterLength = 0;
+
+ for (int i{}; i < LEN_KEYCODES_ROSTER; i++)
+ {
+ if (sSelectedKeyCodes.at(i) == L'1')
+ m_RosterKeyCodes[m_RosterLength++] = i;
+ }
+}
+
void CStayAwakeDlg::InitAwakes()
{
+ InitRoster();
SimulateAwakeKeyPress();
SetDlgItemText(IDC_STAYAWAKE_PAUSE_RESUME_BTN, BTN_TEXT_PAUSE);
- WritePrivateProfileString(PREF_DEFAULTS, PREF_AWAKE_PAUSED, L"N", PREF_INI_FILE);
+ WritePrivateProfileString(PREF_DEFAULTS, PREF_AWAKE_PAUSED, L"N", m_IniFilePath);
}
void CStayAwakeDlg::InitTrayIcon()
@@ -298,9 +374,15 @@ void CStayAwakeDlg::OnDestroy()
void CStayAwakeDlg::SimulateAwakeKeyPress()
{
- switch (m_AwakeKeyCode)
+ if (!m_RosterLength) InitRoster();
+
+ UINT nAwakeKeyCode{ m_RosterKeyCodes[rand() % m_RosterLength] };
+ wstring sAwakeKeyCode{};
+
+ switch (nAwakeKeyCode)
{
case 1:
+ sAwakeKeyCode = L"Volume Down && Up";
keybd_event(VK_VOLUME_DOWN, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
keybd_event(VK_VOLUME_DOWN, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
Sleep(10);
@@ -318,18 +400,21 @@ void CStayAwakeDlg::SimulateAwakeKeyPress()
case 9:
case 10:
{
- BYTE keycode{ static_cast(VK_UNASSIGNED_01 + m_AwakeKeyCode - 2) };
+ sAwakeKeyCode = L"Unassigned Key #" + to_wstring(nAwakeKeyCode - 1);
+ BYTE keycode{ static_cast(VK_UNASSIGNED_01 + nAwakeKeyCode - 2) };
keybd_event(keycode, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
keybd_event(keycode, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
break;
}
case 11:
+ sAwakeKeyCode = L"Unassigned Key #10";
keybd_event(VK_UNASSIGNED_10, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
keybd_event(VK_UNASSIGNED_10, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
break;
default:
+ sAwakeKeyCode = L"Scroll Lock cycling";
keybd_event(VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
keybd_event(VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
Sleep(10);
@@ -341,6 +426,7 @@ void CStayAwakeDlg::SimulateAwakeKeyPress()
SYSTEMTIME lastTime{};
GetLocalTime(&lastTime);
SetDlgItemText(IDC_STAYAWAKE_LAST_EVENT, Utils::formatSystemTime(lastTime, L"Last StayAwake event").c_str());
+ SetDlgItemText(IDC_STAYAWAKE_LAST_KEYCODE, (L"[" + sAwakeKeyCode + L"]").c_str());
UINT nTimerSeconds{ m_IntervalMinSeconds };
if (m_IntervalMinSeconds != m_IntervalMaxSeconds)
@@ -370,8 +456,8 @@ void CStayAwakeDlg::OnSetInterval()
SetDlgItemInt(IDC_STAYAWAKE_INTERVAL_MAX, m_IntervalMaxSeconds, FALSE);
}
- WritePrivateProfileString(PREF_DEFAULTS, PREF_INTERVAL_MINIMUM, to_wstring(m_IntervalMinSeconds).c_str(), PREF_INI_FILE);
- WritePrivateProfileString(PREF_DEFAULTS, PREF_INTERVAL_MAXIMUM, to_wstring(m_IntervalMaxSeconds).c_str(), PREF_INI_FILE);
+ WritePrivateProfileString(PREF_DEFAULTS, PREF_INTERVAL_MINIMUM, to_wstring(m_IntervalMinSeconds).c_str(), m_IniFilePath);
+ WritePrivateProfileString(PREF_DEFAULTS, PREF_INTERVAL_MAXIMUM, to_wstring(m_IntervalMaxSeconds).c_str(), m_IniFilePath);
InitAwakes();
}
@@ -383,13 +469,6 @@ void CStayAwakeDlg::OnClickedAboutButton()
dlgAbout.DoModal();
}
-void CStayAwakeDlg::OnStayawakeKeyChange()
-{
- m_AwakeKeyCode = static_cast(SendDlgItemMessage(IDC_STAYAWAKE_KEY_LIST, CB_GETCURSEL, 0, 0));
- m_AwakeKeyCode %= 12;
- WritePrivateProfileString(PREF_DEFAULTS, PREF_AWAKE_KEYCODE, to_wstring(m_AwakeKeyCode).c_str(), PREF_INI_FILE);
-}
-
void CStayAwakeDlg::OnPauseResume()
{
if (IsTimerPaused())
@@ -401,7 +480,7 @@ void CStayAwakeDlg::OnPauseResume()
KillTimer(m_TimerID);
SetDlgItemText(IDC_STAYAWAKE_PAUSE_RESUME_BTN, BTN_TEXT_RESUME);
- WritePrivateProfileString(PREF_DEFAULTS, PREF_AWAKE_PAUSED, L"Y", PREF_INI_FILE);
+ WritePrivateProfileString(PREF_DEFAULTS, PREF_AWAKE_PAUSED, L"Y", m_IniFilePath);
ShowPausedInfo(false);
}
}
@@ -411,7 +490,7 @@ wstring CStayAwakeDlg::GetPreference(wstring key, wstring defaultVal)
const int bufSize{ MAX_PATH };
wstring ftBuf(bufSize, '\0');
- GetPrivateProfileString(PREF_DEFAULTS, key.c_str(), defaultVal.c_str(), ftBuf.data(), bufSize, PREF_INI_FILE);
+ GetPrivateProfileString(PREF_DEFAULTS, key.c_str(), defaultVal.c_str(), ftBuf.data(), bufSize, m_IniFilePath);
return wstring{ ftBuf.c_str() };
}
@@ -432,5 +511,5 @@ void CStayAwakeDlg::ShowPausedInfo(bool both)
void CStayAwakeDlg::OnStartMinimized()
{
WritePrivateProfileString(PREF_DEFAULTS, PREF_START_MINIMIZED,
- (IsDlgButtonChecked(IDC_START_MINIMIZED) == BST_CHECKED) ? L"Y" : L"N", PREF_INI_FILE);
+ (IsDlgButtonChecked(IDC_START_MINIMIZED) == BST_CHECKED) ? L"Y" : L"N", m_IniFilePath);
}
diff --git a/StayAwake/StayAwakeDlg.h b/StayAwake/StayAwakeDlg.h
index 61eb87d..06e50eb 100644
--- a/StayAwake/StayAwakeDlg.h
+++ b/StayAwake/StayAwakeDlg.h
@@ -11,9 +11,10 @@ constexpr auto VK_UNASSIGNED_10 = 0xE8;
constexpr auto BTN_TEXT_PAUSE = L"&Pause";
constexpr auto BTN_TEXT_RESUME = L"&Resume";
-constexpr auto PREF_INI_FILE = L".\\StayAwake.ini";
+constexpr auto PREF_INI_FILE = L"StayAwake.ini";
constexpr auto PREF_DEFAULTS = L"Defaults";
-constexpr auto PREF_AWAKE_KEYCODE = L"AwakeKeyCode";
+constexpr auto PREF_LEGACY_KEYCODE = L"AwakeKeyCode";
+constexpr auto PREF_SELECTED_KEYCODES = L"SelectedKeyCodes";
constexpr auto PREF_AWAKE_PAUSED = L"AwakePaused";
constexpr auto PREF_START_MINIMIZED = L"StartMinimized";
constexpr auto PREF_MULTI_INSTANCE = L"MultipleInstancesAllowed";
@@ -22,8 +23,11 @@ constexpr auto PREF_INTERVAL_MINIMUM = L"MinimumIntervalInSeconds";
constexpr auto PREF_INTERVAL_MAXIMUM = L"MaximumIntervalInSeconds";
constexpr auto MIN_PERIOD{ 10 };
-constexpr auto DEF_PERIOD{ 240 };
constexpr auto MAX_PERIOD{ 9990 };
+constexpr auto DEF_PERIOD{ 240 };
+
+constexpr auto LEN_KEYCODES_ROSTER{ 12 };
+constexpr auto DEF_SELECTED_KEYCODES = L"001111111111";
const wstring MIN_MAX_PERIOD = to_wstring(MIN_PERIOD) + L" and " + to_wstring(MAX_PERIOD);
const wstring INTERVAL_TOOLTIP = L"Number between " + MIN_MAX_PERIOD;
@@ -39,10 +43,15 @@ class CStayAwakeDlg : public CDialogEx
enum { IDD = IDD_STAYAWAKE_DIALOG };
#endif
- protected:
+protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+public:
+ wstring GetSelectedKeyCodes();
+ bool CheckSelectedKeyCodes(wstring sKeyCodes);
+ bool SaveSelectedKeyCodes(wstring sKeyCodes);
+
protected:
HICON m_hIcon;
@@ -51,21 +60,26 @@ class CStayAwakeDlg : public CDialogEx
DECLARE_MESSAGE_MAP()
private:
+ wchar_t m_IniFilePath[MAX_PATH]{};
bool m_bMinimized{};
UINT_PTR m_TimerID{42};
- UINT m_AwakeKeyCode{ 0 };
+
+ UINT m_RosterKeyCodes[LEN_KEYCODES_ROSTER]{};
+ UINT m_RosterLength{};
+
UINT m_IntervalMinSeconds{};
UINT m_IntervalMaxSeconds{};
+
NOTIFYICONDATA m_TrayData{};
CMenu m_menu;
afx_msg LRESULT OnPostOpen(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnTrayNotify(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnRestoreDialog(WPARAM wParam, LPARAM lParam);
+ afx_msg void OnSetupKeyCodesRosterClicked();
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnKillfocusIntervalMin();
afx_msg void OnKillfocusIntervalMax();
- afx_msg void OnStayawakeKeyChange();
afx_msg void OnSetInterval();
afx_msg void OnPauseResume();
afx_msg void OnMinimize() { MinimizeToTray(); };
@@ -77,7 +91,9 @@ class CStayAwakeDlg : public CDialogEx
afx_msg void OnDestroy();
afx_msg void OnStartMinimized();
+ void InitConfigFilePath();
void InitIntervals();
+ void InitRoster();
void InitAwakes();
void InitTrayIcon();
void MinimizeToTray();
diff --git a/StayAwake/resource.h b/StayAwake/resource.h
index 8e00494..2a41e31 100644
--- a/StayAwake/resource.h
+++ b/StayAwake/resource.h
@@ -6,37 +6,57 @@
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_STAYAWAKE_DIALOG 102
+#define IDD_SELECT_KEYCODES_DIALOG 103
#define IDR_MENU1 130
#define IDI_ICON1 133
#define IDR_MAINFRAME 133
#define IDB_ABOUT_BITMAP 134
-#define IDC_STAYAWAKE_KEY_LABEL 1001
-#define IDC_STAYAWAKE_KEY_LIST 1002
-#define IDC_STAYAWAKE_INTERVAL_MIN 1011
-#define IDC_STAYAWAKE_INTERVAL_MAX 1012
-#define IDC_STAYAWAKE_SET_INTERVAL_BTN 1013
-#define IDC_STAYAWAKE_LAST_EVENT 1014
-#define IDC_STAYAWAKE_NEXT_EVENT 1015
-#define IDC_STAYAWAKE_PAUSE_RESUME_BTN 1021
-#define IDC_MINIMIZE 1022
-#define IDC_EXIT 1023
-#define IDC_START_MINIMIZED 1024
-#define IDC_ABOUT_BUTTON 1025
-#define IDC_ABOUT_NAME 1031
-#define IDC_ABOUT_VERSION 1032
-#define IDC_ABOUT_BUILD_TIME 1033
-#define IDC_ABOUT_ATTRIBUTION 1034
-#define IDC_ABOUT_PROD_URL 1035
+
+#define IDC_STAYAWAKE_KEYS_ROSTER_BTN 1001
+#define IDC_STAYAWAKE_INTERVAL_MIN 1002
+#define IDC_STAYAWAKE_INTERVAL_MAX 1003
+#define IDC_STAYAWAKE_SET_INTERVAL_BTN 1004
+#define IDC_STAYAWAKE_LAST_EVENT 1005
+#define IDC_STAYAWAKE_NEXT_EVENT 1006
+#define IDC_STAYAWAKE_LAST_KEYCODE 1007
+#define IDC_STAYAWAKE_PAUSE_RESUME_BTN 1011
+#define IDC_MINIMIZE 1012
+#define IDC_EXIT 1013
+#define IDC_START_MINIMIZED 1014
+#define IDC_ABOUT_BUTTON 1015
+
+#define IDC_KEY_SCROLL_LOCK 1051
+#define IDC_KEY_VOLUME_UP_DOWN 1052
+#define IDC_KEY_UNASSIGNED_1 1053
+#define IDC_KEY_UNASSIGNED_2 1054
+#define IDC_KEY_UNASSIGNED_3 1055
+#define IDC_KEY_UNASSIGNED_4 1056
+#define IDC_KEY_UNASSIGNED_5 1057
+#define IDC_KEY_UNASSIGNED_6 1058
+#define IDC_KEY_UNASSIGNED_7 1059
+#define IDC_KEY_UNASSIGNED_8 1060
+#define IDC_KEY_UNASSIGNED_9 1061
+#define IDC_KEY_UNASSIGNED_10 1062
+#define IDC_KEY_SELECT_ALL_BTN 1071
+#define IDC_KEY_SELECT_NONE_BTN 1072
+#define IDC_KEY_SELECT_APPLY_BTN 1073
+
+#define IDC_ABOUT_NAME 1101
+#define IDC_ABOUT_VERSION 1102
+#define IDC_ABOUT_BUILD_TIME 1103
+#define IDC_ABOUT_ATTRIBUTION 1104
+#define IDC_ABOUT_PROD_URL 1105
+
#define IDM_EXIT 32771
#define IDM_RESTORE 32772
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 135
#define _APS_NEXT_COMMAND_VALUE 32773
#define _APS_NEXT_CONTROL_VALUE 1026
-#define _APS_NEXT_SYMED_VALUE 101
+#define _APS_NEXT_SYMED_VALUE 106
#endif
#endif