diff --git a/Config.h b/Config.h index c120192..fd468a9 100644 --- a/Config.h +++ b/Config.h @@ -29,6 +29,7 @@ class Config Config(); void read(const char * file); + size_t num_entries() const { return entries.size(); } protected: void reset(); diff --git a/pppc.cc b/pppc.cc index f133693..d21705d 100644 --- a/pppc.cc +++ b/pppc.cc @@ -18,6 +18,8 @@ using namespace std; static LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +static HMENU g_popupMenu; + int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -61,17 +63,13 @@ static LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if (LOWORD(lParam) == WM_RBUTTONUP) { - HMENU hMenu = ::CreatePopupMenu(); - addMenuItem(hMenu, "E&xit", 0); POINT pos; GetCursorPos(&pos); ::SetForegroundWindow(hWnd); - ::TrackPopupMenu(hMenu, 0, pos.x, pos.y, 0, hWnd, NULL); + ::TrackPopupMenu(g_popupMenu, 0, pos.x, pos.y, 0, hWnd, NULL); // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly" ::PostMessage(hWnd, WM_NULL, 0, 0); - - ::DestroyMenu(hMenu); } } break; @@ -79,14 +77,14 @@ static LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; } -void addMenuItem(HMENU hMenu, CHAR * itemstr, WORD id) +void addMenuItem(HMENU hMenu, const CHAR * itemstr, WORD id) { MENUITEMINFO mii; memset(&mii, 0, sizeof(mii)); mii.cbSize = sizeof(mii); mii.fMask = MIIM_STRING | MIIM_ID; mii.wID = id; - mii.dwTypeData = itemstr; + mii.dwTypeData = (CHAR *) itemstr; mii.cch = strlen(mii.dwTypeData); if (::InsertMenuItem(hMenu, 0, TRUE, &mii) == 0) { @@ -94,6 +92,24 @@ void addMenuItem(HMENU hMenu, CHAR * itemstr, WORD id) } } +HMENU addMenuSubMenu(HMENU hMenu, const CHAR * itemstr, WORD id) +{ + HMENU submenu = ::CreatePopupMenu(); + MENUITEMINFO mii; + memset(&mii, 0, sizeof(mii)); + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STRING | MIIM_SUBMENU | MIIM_ID; + mii.wID = id; + mii.dwTypeData = (CHAR *) itemstr; + mii.cch = strlen(mii.dwTypeData); + mii.hSubMenu = submenu; + if (::InsertMenuItem(hMenu, 0, TRUE, &mii) == 0) + { + cerr << "Warning: InsertMenuItem(): " << GetLastError() << endl; + } + return submenu; +} + PPPC::PPPC(HINSTANCE hInstance, const char * config_file) { m_pins = 0u; @@ -142,6 +158,21 @@ PPPC::PPPC(HINSTANCE hInstance, const char * config_file) cerr << "Warning: CreateWindow(): " << GetLastError() << endl; } + /* Create the right-click icon context menu */ + m_popupMenu = ::CreatePopupMenu(); + g_popupMenu = m_popupMenu; + addMenuItem(m_popupMenu, "E&xit", 0); + for (int sz = m_config.num_entries(), i = 0; i < sz; i++) + { + int config_id = i + 1; + HMENU submenu = addMenuSubMenu(m_popupMenu, + m_config.entries[i].name.c_str(), + (config_id << 8)); + addMenuItem(submenu, "Auto", (config_id << 8) | 0x1); + addMenuItem(submenu, "Manual: Off", (config_id << 8) | 0x2); + addMenuItem(submenu, "Manual: On", (config_id << 8) | 0x3); + } + /* Create the notify icon data */ memset(&m_nid, 0, sizeof(m_nid)); m_nid.cbSize = sizeof(NOTIFYICONDATA); @@ -211,7 +242,12 @@ BOOL PPPC::mainLoop() PPPC::~PPPC() { + ::DestroyMenu(m_popupMenu); + + /* TODO: turned off temporarily for debugging. Re-enable! */ +#if 0 event_exit(); +#endif /* delete the tray icon */ Shell_NotifyIcon(NIM_DELETE, &m_nid); @@ -222,7 +258,7 @@ PPPC::~PPPC() void PPPC::event_start() { - for (int sz = m_config.entries.size(), i = 0; i < sz; i++) + for (int sz = m_config.num_entries(), i = 0; i < sz; i++) { switch (m_config.entries[i].on_start) { @@ -241,7 +277,7 @@ void PPPC::event_start() void PPPC::event_exit() { - for (int sz = m_config.entries.size(), i = 0; i < sz; i++) + for (int sz = m_config.num_entries(), i = 0; i < sz; i++) { switch (m_config.entries[i].on_exit) { @@ -260,7 +296,7 @@ void PPPC::event_exit() void PPPC::event_lock() { - for (int sz = m_config.entries.size(), i = 0; i < sz; i++) + for (int sz = m_config.num_entries(), i = 0; i < sz; i++) { switch (m_config.entries[i].on_lock) { @@ -280,7 +316,7 @@ void PPPC::event_lock() void PPPC::event_unlock() { - for (int sz = m_config.entries.size(), i = 0; i < sz; i++) + for (int sz = m_config.num_entries(), i = 0; i < sz; i++) { switch (m_config.entries[i].on_unlock) { diff --git a/pppc.h b/pppc.h index 20ca4dd..62d7c92 100644 --- a/pppc.h +++ b/pppc.h @@ -26,9 +26,11 @@ class PPPC NOTIFYICONDATA m_nid; unsigned char m_pins; unsigned char m_previous_pins; + HMENU m_popupMenu; }; /* non class-member functions */ -void addMenuItem(HMENU hMenu, CHAR * itemstr, WORD id); +void addMenuItem(HMENU hMenu, const CHAR * itemstr, WORD id); +HMENU addMenuSubMenu(HMENU hMenu, const CHAR * itemstr, WORD id); #endif