git-svn-id: http://apu.dw.local/svnusers/JoshHoltrop/pppc/trunk@56 8131a0b2-b21c-1c47-bd6a-f003126495bd
262 lines
6.8 KiB
C++
262 lines
6.8 KiB
C++
|
|
#include <windows.h>
|
|
#include <string.h>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <string>
|
|
#include "session_notification.h"
|
|
#include "pport.h"
|
|
#include "resources.h"
|
|
#include "parseCmdLine.h"
|
|
#include "pppc.h"
|
|
using namespace std;
|
|
|
|
#define SET_BIT(var,position,value) \
|
|
(var) = ((var) & (~(1 << (position)))) | ((value) << (position))
|
|
#define GET_BIT(var,position) \
|
|
(((var) >> (position)) & 0x1)
|
|
|
|
static LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
int WinMain(
|
|
HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPSTR lpCmdLine,
|
|
int nCmdShow)
|
|
{
|
|
/* parse command line into an array like sane operating systems supply */
|
|
vector<string> args = parseCmdLine(lpCmdLine);
|
|
|
|
const char * config_file = NULL;
|
|
/* process command line arguments */
|
|
for (int sz = args.size(), i = 0; i < sz; i++)
|
|
{
|
|
if (args[i][0] != '-')
|
|
{
|
|
config_file = args[i].c_str();
|
|
}
|
|
}
|
|
|
|
PPPC myPPPC(hInstance, config_file);
|
|
|
|
return myPPPC.mainLoop();
|
|
}
|
|
|
|
static LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_NCCREATE:
|
|
return 1;
|
|
case WM_CREATE:
|
|
break;
|
|
case WM_CLOSE:
|
|
::DestroyWindow(hWnd);
|
|
break;
|
|
case WM_DESTROY:
|
|
::PostQuitMessage(0);
|
|
break;
|
|
case WM_ICON_NOTIFY:
|
|
if (wParam == 0)
|
|
{
|
|
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);
|
|
|
|
// BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"
|
|
::PostMessage(hWnd, WM_NULL, 0, 0);
|
|
|
|
::DestroyMenu(hMenu);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void addMenuItem(HMENU hMenu, 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.cch = strlen(mii.dwTypeData);
|
|
if (::InsertMenuItem(hMenu, 0, TRUE, &mii) == 0)
|
|
{
|
|
cerr << "Warning: InsertMenuItem(): " << GetLastError() << endl;
|
|
}
|
|
}
|
|
|
|
PPPC::PPPC(HINSTANCE hInstance, const char * config_file)
|
|
{
|
|
m_pins = 0u;
|
|
|
|
if (config_file != NULL)
|
|
{
|
|
m_config.read(config_file);
|
|
}
|
|
|
|
event_start();
|
|
|
|
/* Load the application icon */
|
|
HICON icon = ::LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
|
|
if (icon == 0)
|
|
{
|
|
cerr << "Warning: LoadIcon(): " << GetLastError() << endl;
|
|
}
|
|
|
|
/* Create the TrayIconClass class */
|
|
WNDCLASSEX wcex;
|
|
memset(&wcex, 0, sizeof(wcex));
|
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
|
wcex.lpfnWndProc = (WNDPROC)WindowProc;
|
|
wcex.cbClsExtra = 0;
|
|
wcex.cbWndExtra = 0;
|
|
wcex.hInstance = hInstance;
|
|
wcex.hIcon = icon;
|
|
wcex.hCursor = 0;
|
|
wcex.hbrBackground = 0;
|
|
wcex.lpszMenuName = 0;
|
|
wcex.lpszClassName = "TrayIconClass";
|
|
wcex.hIconSm = 0;
|
|
|
|
RegisterClassEx(&wcex);
|
|
|
|
|
|
/* Create the tray icon window */
|
|
m_hWnd = ::CreateWindow("TrayIconClass", "", WS_POPUP,
|
|
CW_USEDEFAULT,CW_USEDEFAULT,
|
|
CW_USEDEFAULT,CW_USEDEFAULT,
|
|
NULL, 0,
|
|
hInstance, 0);
|
|
if (m_hWnd == NULL)
|
|
{
|
|
cerr << "Warning: CreateWindow(): " << GetLastError() << endl;
|
|
}
|
|
|
|
/* Create the notify icon data */
|
|
memset(&m_nid, 0, sizeof(m_nid));
|
|
m_nid.cbSize = sizeof(NOTIFYICONDATA);
|
|
m_nid.hWnd = m_hWnd;
|
|
m_nid.uID = 0;
|
|
m_nid.hIcon = icon;
|
|
m_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
|
m_nid.uCallbackMessage = WM_ICON_NOTIFY;
|
|
strncpy(m_nid.szTip, APP_NAME, sizeof(m_nid.szTip));
|
|
|
|
BOOL bResult = Shell_NotifyIcon(NIM_ADD, &m_nid);
|
|
if (bResult == 0)
|
|
{
|
|
cerr << "Warning: Shell_NotifyIcon(): " << GetLastError() << endl;
|
|
}
|
|
|
|
/* begin capturing session notifications */
|
|
session_notification_enable(m_hWnd);
|
|
}
|
|
|
|
BOOL PPPC::mainLoop()
|
|
{
|
|
BOOL bRet;
|
|
MSG msg;
|
|
bool running = true;
|
|
while(running)
|
|
{
|
|
bRet = GetMessage(&msg, NULL, 0, 0);
|
|
if (bRet == -1 || bRet == 0)
|
|
{
|
|
break;
|
|
}
|
|
switch (msg.message)
|
|
{
|
|
case WM_PAINT:
|
|
break;
|
|
case WM_CLOSE:
|
|
case WM_DESTROY:
|
|
case WM_QUIT:
|
|
running = false;
|
|
break;
|
|
case WM_WTSSESSION_CHANGE:
|
|
if (msg.wParam == WTS_SESSION_LOGON
|
|
|| msg.wParam == WTS_SESSION_UNLOCK)
|
|
{
|
|
event_unlock();
|
|
}
|
|
if (msg.wParam == WTS_SESSION_LOGOFF
|
|
|| msg.wParam == WTS_SESSION_LOCK)
|
|
{
|
|
event_lock();
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (LOWORD(msg.wParam)) /* menu entry index */
|
|
{
|
|
case 0: /* exit */
|
|
running = false;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
PPPC::~PPPC()
|
|
{
|
|
event_exit();
|
|
|
|
/* delete the tray icon */
|
|
Shell_NotifyIcon(NIM_DELETE, &m_nid);
|
|
|
|
/* stop listening for session notifications */
|
|
session_notification_disable(m_hWnd);
|
|
}
|
|
|
|
void PPPC::event_start()
|
|
{
|
|
for (int sz = m_config.entries.size(), i = 0; i < sz; i++)
|
|
{
|
|
switch (m_config.entries[i].on_start)
|
|
{
|
|
case Config::ON:
|
|
SET_BIT(m_pins, m_config.entries[i].pin, 1);
|
|
break;
|
|
case Config::OFF:
|
|
SET_BIT(m_pins, m_config.entries[i].pin, 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
update_pins();
|
|
}
|
|
|
|
void PPPC::event_exit()
|
|
{
|
|
update_pins();
|
|
}
|
|
|
|
void PPPC::event_lock()
|
|
{
|
|
update_pins();
|
|
m_previous_pins = m_pins;
|
|
}
|
|
|
|
void PPPC::event_unlock()
|
|
{
|
|
update_pins();
|
|
}
|
|
|
|
void PPPC::update_pins()
|
|
{
|
|
pport_write(m_pins);
|
|
}
|