/********************************
* Projekt: Funkuhr DCF77 *
* Eigenschaftsseite „TrayIcon“ *
* Festlegung Erscheinungsbild *
* des Tray-Icons *
********************************/
#include "Funkuhr.h"
// Pfad zur EXE-Datei sowie Kommandozeilenargumente
// für Funkuhr.exe als Dienst;
static void binPath(TCHAR s[MAX_PATH]) {
int l;
GetModuleFileName(0,s,MAX_PATH);
PathQuoteSpaces(s);
l=lstrlen(s);
wnsprintf(s+l,MAX_PATH-l,T(" %d"),CmdLineOpt|0x18);
}
typedef enum {CHECK=-1,REMOVE,CREATE} ACTION;
static bool RunAsService(ACTION action) {
bool ret=false;
if ((LONG)WinVer<0) {
#ifndef UNICODE
HKEY k;
if (!RegCreateKey(HKEY_LOCAL_MACHINE,
T("Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"),&k)) {
switch (action) {
case CREATE: { // Setzen
TCHAR s[MAX_PATH];
binPath(s);
if (!RegSetValueEx(k,T("DCF77"),0,REG_SZ,(PBYTE)s,
(lstrlen(s)+1)*sizeof(TCHAR))) ret=true;
}break;
case REMOVE: { // Löschen
if (!RegDeleteValue(k,T("DCF77"))) ret=true;
}break;
case CHECK: { // Testen; der Pfad wird nicht geprüft
DWORD size=0;
if (!RegQueryValueEx(k,T("DCF77"),0,NULL,NULL,&size) && size) ret=true;
}break;
}
RegCloseKey(k);
}
#endif
}else{
// Unter Windows98SE kommt bei OpenSCManager Kode 120: "Die Funktion ist nur im Win32-Modus gültig"
// Daher wird in diesem Fall die Registrierung via RunServices bemüht
SC_HANDLE mgr=OpenSCManager(NULL,NULL,action==CREATE?SC_MANAGER_CREATE_SERVICE:SC_MANAGER_CONNECT);
if (mgr) {
SC_HANDLE srv=0;
switch (action) {
case CREATE: {
TCHAR s[MAX_PATH];
binPath(s);
// XP-Kommandozeile zu Fuß: "sc create DCF77 binPath=c:\programme\funkuhr\funkuhr.exe"
srv=CreateService(mgr,T("DCF77"),MBoxTitle,SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,SERVICE_ERROR_IGNORE,
s,NULL,NULL,NULL,NULL,NULL);
}break;
case REMOVE: {
srv=OpenService(mgr,T("DCF77"),DELETE);
// XP-Kommandozeile zu Fuß: "sc delete DCF77"
if (srv) DeleteService(srv);
}break;
case CHECK: {
srv=OpenService(mgr,T("DCF77"),READ_CONTROL);
}break;
}
if (srv) {
CloseServiceHandle(srv);
ret=true;
}
CloseServiceHandle(mgr);
}
}
return ret;
}
INT_PTR CALLBACK TrayIconDlgProc(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
DefHelpProc(Wnd,Msg,lParam,103);
switch (Msg) {
case WM_INITDIALOG: {
UINT id; // Minuten-Anzahl einsetzen
for (id=15; id<=16; id++) {
TCHAR t[128];
HWND w=GetDlgItem(Wnd,id);
GetWindowText(w,t,elemof(t));
wndSetText(w,t,Config.ToSilence);
}
CheckDlgButton(Wnd,11+Config.TrayIconVis,TRUE);
CheckDlgButton(Wnd,14,Config.TrayIconBlink);
id=15+Config.TrayIconAus;
CheckDlgButton(Wnd,id,TRUE);
if (id==18) CheckDlgButton(Wnd,17,TRUE);
if (Config.TrayIconAus<2) EnableDlgItem(Wnd,18,FALSE);
SendMessage(Wnd,WM_FUNKRECV,12,0); // setzen lassen
SendDlgItemMessage(Wnd,20,TBM_SETRANGE,0,MAKELONG(0,10));
SendDlgItemMessage(Wnd,20,TBM_SETPOS,1,Config.Piep);
}return TRUE;
case WM_NOTIFY: {
LPPSHNOTIFY psn=(LPPSHNOTIFY)lParam;
switch (psn->hdr.code) {
case PSN_SETACTIVE: {
HWND w=GetDlgItem(Wnd,20);
BOOL e=Config.Where!=2;
EnableWindow(w,e);
EnableWindow(GetPrevSibling(w),e);
SendMessage(Wnd,WM_FUNKRECV,12,0); // setzen lassen
// RunAsService() kann sich extern ändern,
// daher wenigstens bei Seitenwechsel aktualisieren
CheckDlgButton(Wnd,21,RunAsService(CHECK));
}break;
}
}break;
case WM_TIMER: { // nur 1 Timer
KillTimer(Wnd,wParam);
CheckDlgButton(Wnd,21,RunAsService(CHECK)); break;
}break;
case WM_COMMAND: switch ((BYTE)wParam) {
case 11:
case 12:
case 13: {
Config.TrayIconVis=(BYTE)wParam-11;
TrayIconVisChanged();
}break;
case 14: Config.TrayIconBlink=IsDlgButtonChecked(Wnd,14); break;
case 15:
case 16:
case 17:
case 18: {
BYTE b=(BYTE)wParam-15;
if (b==3 && !IsDlgButtonChecked(Wnd,18)) b=2;
EnableDlgItem(Wnd,18,b>=2);
if (b<2) CheckDlgButton(Wnd,18,FALSE);
if (Empfang.Ein==3) { // Empfangszeit-Timer nachführen 110908
if (Config.TrayIconAus==2 && b<2) SetTimer(MainWnd,102,Config.ToSilence*60000,NULL);
if (Config.TrayIconAus<2 && b>=2) KillTimer(MainWnd,102);
}
Config.TrayIconAus=b;
}break;
case 19: { // Keine AUTOCHECKBOX!! Übergänge: 0->1, 1->0, 2->1. Das Setzen erfolgt bei WM_FUNKRECV.
PostMessage(MainWnd,WM_SetActivity,IsDlgButtonChecked(Wnd,19)==1?0:3,0);
}break;
case 21: {
ACTION a=IsDlgButtonChecked(Wnd,21);
if (RunAsService(a)) {
if (a && !(CmdLineOpt&0x08)) SaveConf(HKEY_LOCAL_MACHINE,ALL);
}else{
DWORD ec=GetLastError();
PTSTR s;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,ec,0,(PTSTR)&s,0,NULL);
MBox(0,12,0,ec,s);
LocalFree(s);
}
SetTimer(Wnd,wParam,200,NULL); // Windows 2000 braucht zum Löschen etwas Zeit!
}break;
}break;
case WM_FUNKRECV: switch ((DWORD)wParam) {
case 12: { // Config.Ein geändert
UINT Check=2; // EIN, aber ohne Darstellung (stiller Empfang)
switch (Empfang.Ein) {
case 0: Check=0; break; // voll AUS
case 3: Check=1; break; // voll EIN
}
CheckDlgButton(Wnd,19,Check);
}break;
}break;
case WM_HSCROLL: switch ((BYTE)wParam) { // Schieberegler »Piep«
case SB_ENDSCROLL: {
Empfang.DauerPiep=false;
if (Config.Piep) {
if (AnimYes()) {
if (!Empfang.Signal) StopBeep();
}else DoneBeep();
}
}break;
default:{
BYTE NewPiep=(BYTE)SendMessage((HWND)lParam,TBM_GETPOS,0,0);
if (!Empfang.DauerPiep) {
Empfang.DauerPiep=true;
Config.Piep=NewPiep;
if (Config.Piep) {
if (AnimYes()) {
if (!Empfang.Signal) StartBeep();
}else goto initbeep;
}
}else if (Config.Piep!=NewPiep) {
if (Config.Piep && !NewPiep) DoneBeep(); // macht implizit StopBeep
Config.Piep=NewPiep;
if (Config.Piep) {
initbeep:
InitBeep((BYTE)(10-Config.Piep));
StartBeep();
}
}
}
}break;
}
return FALSE;
}
Vorgefundene Kodierung: UTF-8 | 0
|