예제 #1
0
파일: main.c 프로젝트: andrejtm/T-Clock
static void InjectClockHook(HWND hwnd) {
	static DWORD s_restart_ticks = 0;
	static int s_restart_num = 0;
	DWORD ticks = GetTickCount();
	if(ticks - s_restart_ticks < 30000){
		if(++s_restart_num >= 3){
			if(api.Message(0,
					"Multiple Explorer crashes or restarts detected\n"
					"It's possible that T-Clock is crashing your Explorer,\n"
					"automated hooking postponed.\n"
					"\n"
					"Take precaution and exit T-Clock now?","T-Clock",MB_YESNO,MB_ICONEXCLAMATION) == IDYES) {
				SendMessage(hwnd, WM_CLOSE, 0, 0);
				return;
			}
			s_restart_ticks = GetTickCount();
			s_restart_num = 0;
		}
	}else{
		s_restart_ticks = ticks;
		s_restart_num = 0;
	}
	api.Inject(hwnd);
	#ifndef _DEBUG
	EmptyWorkingSet(GetCurrentProcess());
	#endif
}
예제 #2
0
//======================================================
//-------------------------------+++--> Open "Calendar":
HWND CreateCalender(HWND hwnd)   //---------------+++-->
{
	INITCOMMONCONTROLSEX icex = {sizeof(icex), ICC_DATE_CLASSES};
	WNDCLASSEX wcx = {sizeof(wcx)};
	ATOM calclass;
	m_bAutoClose = api.GetInt(L"Calendar", L"CloseCalendar", 1);
	m_bTopMost = api.GetInt(L"Calendar", L"CalendarTopMost", 0);
	InitCommonControlsEx(&icex);
	
	wcx.style = 0;
	wcx.lpfnWndProc = Window_Calendar;
	wcx.cbClsExtra = 0;
	wcx.cbWndExtra = 0;
	wcx.hInstance = g_instance;
	wcx.hIcon = NULL;
	wcx.hIcon = LoadIcon(g_instance,MAKEINTRESOURCE(IDI_MAIN));
	wcx.hCursor = LoadCursor(NULL,IDC_ARROW);
	wcx.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME;
	wcx.lpszMenuName = NULL;
	wcx.lpszClassName = L"ClockFlyoutWindow";
	wcx.hIconSm = NULL;
	calclass = RegisterClassEx(&wcx);
	hwnd = CreateWindowEx(0, MAKEINTATOM(calclass), L"T-Clock: Calendar", (WS_CAPTION|WS_POPUP|WS_SYSMENU|WS_VISIBLE), 0,0,0,0, hwnd, 0, g_instance, NULL);
	return hwnd;
}
예제 #3
0
파일: main.c 프로젝트: andrejtm/T-Clock
static void CALLBACK ToggleCalendar_done(HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult){
	(void)uMsg;
	(void)lResult;
	hwnd = api.GetCalendar();
	if(!hwnd && api.OS >= TOS_WIN10){ // Win10 (new slow calendar)
		dwData = 50;
		do{ // min 6-12 iterations on my VM (also seen 50+ under load)
			Sleep(50);
			hwnd = api.GetCalendar();
		}while(!hwnd && --dwData);
	}
	// 11px padding is Win8 default, 0px is Win10
	if(hwnd)
		api.PositionWindow(hwnd, (api.OS<TOS_WIN10 && api.OS>=TOS_WIN7 ? 11 : 0));
}
예제 #4
0
파일: main.c 프로젝트: andrejtm/T-Clock
/*---------------------------------------------------------
-- show a message when TClock failed to customize the clock
---------------------------------------------------------*/
void InitError(int n)
{
	char s[160];
	
	wsprintf(s, "%s: %d", MyString(IDS_NOTFOUNDCLOCK), n);
	api.Message(NULL, s, "Error", MB_OK, MB_ICONEXCLAMATION);
}
예제 #5
0
파일: main.c 프로젝트: andrejtm/T-Clock
//=================================================================
//--------------------------+++--> toggle calendar (close or open):
void ToggleCalendar(int type)   //---------------------------+++-->
{
	HWND calendar = api.GetCalendar();
	int is_custom = api.GetInt("Calendar", "bCustom", 0);
	if(calendar){
		if(is_custom)
			SetForegroundWindow(calendar);
		return;
	}
	if(api.OS >= TOS_VISTA && (!is_custom && type!=1)){
		// Windows 10 workaround as SendMessage doesn't work any longer (no error given)
		SendMessageCallback(g_hwndClock, WM_USER+102, 1, 0, ToggleCalendar_done, 0);//1=open, 0=close
	}else{
		char cal[MAX_PATH];
		memcpy(cal, api.root, api.root_len+1);
		add_title(cal,"misc\\XPCalendar.exe");
		api.Exec(cal,NULL,g_hwndTClockMain);
	}
}
예제 #6
0
파일: main.c 프로젝트: andrejtm/T-Clock
//================================================================================================
//--------------------------------------------------+++--> The Main Application "Window" Procedure:
LRESULT CALLBACK WndProc(HWND hwnd,	UINT message, WPARAM wParam, LPARAM lParam)   //--------+++-->
{
	switch(message) {
	case WM_CREATE:
		InitAlarm();  // initialize alarms
		SetTimer(hwnd, IDTIMER_MAIN, 1000, NULL);
		InjectClockHook(hwnd);
		return 0;
		
	case WM_TIMER:
		if(wParam == IDTIMER_MAIN) OnTimerMain(hwnd);
		else if(wParam == IDTIMER_MOUSE) OnTimerMouse(hwnd);
		return 0;
		
	case WM_ENDSESSION:
		if(!wParam)
			break;
		/* fall through */
	case WM_DESTROY:
		KillTimer(hwnd, IDTIMER_MAIN);
		if(g_hwndSheet && IsWindow(g_hwndSheet))
			SendMessage(g_hwndSheet, WM_CLOSE, 0, 0);
		if(g_hDlgTimer && IsWindow(g_hDlgTimer))
			SendMessage(g_hDlgTimer, WM_CLOSE, 0, 0);
		if(g_hDlgStopWatch && IsWindow(g_hDlgStopWatch))
			SendMessage(g_hDlgStopWatch, WM_CLOSE, 0, 0);
		g_hwndSheet = g_hDlgTimer = g_hDlgStopWatch = NULL;
		EndAlarm();
		EndAllTimers();
		api.Exit(); // exit clock, remove injection
		if(message!=WM_ENDSESSION)
			PostQuitMessage(0);
		return 0;
	case WM_PAINT: {
//			HDC hdc;
//			PAINTSTRUCT ps;
//			hdc = BeginPaint(hwnd, &ps);
//			EndPaint(hwnd, &ps);
			return 0;}
	case WM_HOTKEY: // Feature Requested From eweoma at DonationCoder.com
		switch(wParam) { // And a Damn Fine Request it Was... :-)
		case HOT_WATCH:
			PostMessage(hwnd, WM_COMMAND, IDM_TIMEWATCH, 0);
			return 0;
			
		case HOT_TIMER:
			PostMessage(hwnd, WM_COMMAND, IDM_TIMER, 0);
			return 0;
			
		case HOT_STOPW:
			PostMessage(hwnd, WM_COMMAND, IDM_STOPWATCH, 0);
			return 0;
			
		case HOT_PROPR:
			PostMessage(hwnd, WM_COMMAND, IDM_SHOWPROP, 0);
			return 0;
			
		case HOT_CALEN:
			PostMessage(hwnd, WM_COMMAND, IDM_SHOWCALENDER, 0);
			return 0;
			
		case HOT_TSYNC:
			SyncTimeNow();
			return 0;
			
		} return 0;
		
		//==================================================
	case MAINM_CLOCKINIT: // Messages sent/posted from TCDLL.dll
		g_hwndClock = (HWND)lParam;
		api.InjectFinalize(); // injected, now remove hook
		return 0;
		
	case MAINM_ERROR:    // error
		InitError((int)lParam);
		SendMessage(hwnd, WM_CLOSE, 0, 0);
		return 0;
		
	case MAINM_EXIT:    // exit
		SendMessage(hwnd, WM_CLOSE, 0, 0);
		return 0;
		
	case MAINM_BLINKOFF:    // clock no longer blinks
		if(!g_bPlayingNonstop) StopFile();
		return 0;
		
	case MM_MCINOTIFY: // stop playing or repeat mci file (all but .wav, .pcb)
		OnMCINotify(hwnd);
		return 0;
	case MM_WOM_DONE: // stop playing wave
	case MAINM_STOPSOUND:
		StopFile();
		return 0;
		
	case WM_WININICHANGE:
		RefreshUs();
		return 0;
	// inform clock about DWM color change
	case WM_DWMCOLORIZATIONCOLORCHANGED:
		api.On_DWMCOLORIZATIONCOLORCHANGED((unsigned)wParam, (BOOL)lParam);
		PostMessage(g_hwndClock, WM_DWMCOLORIZATIONCOLORCHANGED, wParam, lParam);
		return 0;
		
	// context menu
	case WM_COMMAND:
		OnTClockCommand(hwnd, LOWORD(wParam)); // menu.c
		return 0;
		
	case WM_LBUTTONDOWN:
	case WM_RBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_XBUTTONDOWN:
		if(!g_bPlayingNonstop) PostMessage(hwnd, MAINM_STOPSOUND, 0, 0);
		/* fall through */
	case WM_LBUTTONUP:
	case WM_RBUTTONUP:
	case WM_MBUTTONUP:
	case WM_XBUTTONUP:
		OnMouseMsg(hwnd, message, wParam, lParam); // mouse.c
		return 0;
		
	case WM_WTSSESSION_CHANGE:
		switch(wParam) {
		case WTS_SESSION_LOCK:
			Sleep(500); // Eliminate user's interaction for 500 ms
			SendMessage(HWND_BROADCAST_nowarn, WM_SYSCOMMAND,SC_MONITORPOWER, 2);
			return 0;
		}
		break;
	default:
		if(message == g_WM_TaskbarCreated){
			InjectClockHook(hwnd);
		}
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}
예제 #7
0
파일: main.c 프로젝트: andrejtm/T-Clock
//========================================================================================
//	/exit		exit T-Clock 2010
//	/prop		show T-Clock 2010 properties
//	/SyncOpt	SNTP options
//	/Sync		synchronize the system clock with an NTP server
//	/start		start the Stopwatch (open as needed)
//	/stop		stop (pause really) the Stopwatch
//	/reset		reset Stopwatch to 0 (stop as needed)
//	/lap		record a (the current) lap time
//================================================================================================
//---------------------------------------------//---------------+++--> T-Clock Command Line Option:
void ProcessCommandLine(HWND hwndMain,const char* cmdline)   //-----------------------------+++-->
{
	int justElevated = 0;
	const char* p = cmdline;
	if(g_hwndTClockMain != hwndMain){
		g_hwndTClockMain = CreateWindow("STATIC",NULL,0,0,0,0,0,HWND_MESSAGE_nowarn,0,0,0);
		SubclassWindow(g_hwndTClockMain, MsgOnlyProc);
	}
	
	while(*p != '\0') {
		if(*p == '/') {
			++p;
			if(strncasecmp(p, "prop", 4) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_SHOWPROP, 0);
				p += 4;
			} else if(strncasecmp(p, "exit", 4) == 0) {
				SendMessage(hwndMain, MAINM_EXIT, 0, 0);
				p += 4;
			} else if(strncasecmp(p, "start", 5) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_START, 0);
				p += 5;
			} else if(strncasecmp(p, "stop", 4) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_STOP, 0);
				p += 4;
			} else if(strncasecmp(p, "reset", 5) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_RESET, 0);
				p += 5;
			} else if(strncasecmp(p, "pause", 5) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_PAUSE, 0);
				p += 5;
			} else if(strncasecmp(p, "resume", 6) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_RESUME, 0);
				p += 6;
			} else if(strncasecmp(p, "lap", 3) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_LAP, 0);
				p += 3;
			} else if(strncasecmp(p, "SyncOpt", 7) == 0) {
				NetTimeConfigDialog(justElevated);
				p += 7;
			} else if(strncasecmp(p, "Sync", 4) == 0) {
				p += 4;
				if(HaveSetTimePermissions()){
					SyncTimeNow();
				} else if(!justElevated){
					if(api.ExecElevated(GetClockExe(),"/UAC /Sync",NULL) != 0){
						MessageBox(0,"T-Clock must be elevated to set your system time,\nbut elevation was cancled", "Time Sync Failed", MB_OK|MB_ICONERROR);
					}
				}
				if(g_hwndTClockMain == hwndMain)
					SendMessage(hwndMain, MAINM_EXIT, 0, 0);
			} else if(strncmp(p, "Wc", 2) == 0) { // Win10 calendar "restore"
				if(p[2] == '1') // restore to previous
					api.SetSystemInt(HKEY_LOCAL_MACHINE, kSectionImmersiveShell, kKeyWin32Tray, 1);
				else // use the slow (new) one
					api.DelSystemValue(HKEY_LOCAL_MACHINE, kSectionImmersiveShell, kKeyWin32Tray);
				p += 2;
			} else if(strncmp(p, "UAC", 3) == 0) {
				justElevated = 1;
				p += 3;
			}
			continue;
		}
		++p;
	}
	
	if(g_hwndTClockMain != hwndMain){
		int timeout = 100; /**< timeout in 1/10th seconds to allow sounds up to 10 seconds before terminating */
		MSG msg;
		msg.message = 0;
		while(IsPlaying() && --timeout){
			while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
				if(msg.message==WM_QUIT)
					break;
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			if(msg.message==WM_QUIT)
				break;
			Sleep(100);
		}
		DestroyWindow(g_hwndTClockMain);
		g_hwndTClockMain = NULL;
	}
}
예제 #8
0
파일: main.c 프로젝트: andrejtm/T-Clock
//================================================================================================
//--------------------------------------------------==-+++--> Entry Point of Program Using WinMain:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASS wndclass;
	HWND hwndMain;
	MSG msg;
	int updated;
	
	(void)hPrevInstance;
	(void)nCmdShow;
	
	#if defined(__GNUC__) && defined(_DEBUG)
	#	ifdef _WIN64
	#		define LoadExcHndl() LoadLibraryExA("dbg\\64\\exchndl", NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
	#	else
	#		define LoadExcHndl() LoadLibraryExA("dbg\\exchndl", NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
	#	endif
	#else
	#	define LoadExcHndl()
	#endif
	LoadExcHndl(); // LOAD_WITH_ALTERED_SEARCH_PATH works :P At least since Win2k
	
	g_instance = hInstance;
	if(LoadClockAPI("misc/T-Clock" ARCH_SUFFIX, &api)){
		MessageBox(NULL, "Error loading: T-Clock" ARCH_SUFFIX ".dll", "API error", MB_OK|MB_ICONERROR);
		return 2;
	}
	chdir(api.root); // make sure we've got the right working directory
	
	// Make sure we're running Windows 2000 and above
	if(!api.OS) {
		MessageBox(NULL,"T-Clock requires Windows 2000 or newer","old OS",MB_OK|MB_ICONERROR);
		return 1;
	}
	
	// make sure ObjectBar isn't running -> From Original Code/Unclear if This is Still a Conflict. (test suggested not really.. no crash but no clock either :P)
	if(FindWindow("ObjectBar Main","ObjectBar")) {
		MessageBox(NULL,"ObjectBar and T-Clock can't be run together","ObjectBar detected!",MB_OK|MB_ICONERROR);
		return 1;
	}
	
	// Load ALL of the Global Resources
	g_hIconTClock = LoadIcon(api.hInstance, MAKEINTRESOURCE(IDI_MAIN));
	g_hIconPlay = LoadImage(g_instance, MAKEINTRESOURCE(IDI_PLAY), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
	g_hIconStop = LoadImage(g_instance, MAKEINTRESOURCE(IDI_STOP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
	g_hIconDel  = LoadImage(g_instance, MAKEINTRESOURCE(IDI_DEL), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
	
//	FindTrayServer(hwndMain);
	
	// Make sure we're not running 32bit on 64bit OS / start the other one
	#ifndef _WIN64
	if(IsWow64()){
		hwndMain = FindWindow(g_szClassName, NULL);
		if(hwndMain) { // send commands to existing instance
			ProcessCommandLine(hwndMain,lpCmdLine);
		}else{ // start new instance
			char clock64[MAX_PATH];
			memcpy(clock64, api.root, api.root_len+1);
			add_title(clock64,"Clock" ARCH_SUFFIX_64 ".exe");
			api.Exec(clock64,lpCmdLine,NULL);
		}
		return 0;
	}
	#endif // _WIN64
	
	// Do Not Allow the Program to Execute Twice!
	updated = 25; /**< wait up to 5 sec in 1/5th seconds for other instance */
	do{
		HANDLE processlock=CreateMutex(NULL,FALSE,g_szClassName); // we leak handle here, but Windows closes on process exit anyway (so why do it manually?)
		if(processlock && GetLastError()==ERROR_ALREADY_EXISTS){
			CloseHandle(processlock);
			hwndMain = FindWindow(g_szClassName, NULL);
			if(hwndMain) { // This One Sends Commands to the Instance
				ProcessCommandLine(hwndMain,lpCmdLine); // That is Currently Running.
				return 0;
			}
			Sleep(200);
			continue;
		}
		break;
	}while(updated--);
	
	// Update settings if required and setup defaults
	if((updated=CheckSettings())<0){
		return 1;
	}
	CancelAllTimersOnStartUp();
	
	// Message of the taskbar recreating - Special thanks to Mr.Inuya
	g_WM_TaskbarCreated = RegisterWindowMessage("TaskbarCreated");
	
	// register a window class
	wndclass.style         = 0;
	wndclass.lpfnWndProc   = WndProc;
	wndclass.cbClsExtra    = 0;
	wndclass.cbWndExtra    = 0;
	wndclass.hInstance     = g_instance;
	wndclass.hIcon         = g_hIconTClock;
	wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)(intptr_t)(COLOR_WINDOW+1);
	wndclass.lpszMenuName  = NULL;
	wndclass.lpszClassName = g_szClassName;
	g_atomTClock = RegisterClass(&wndclass);
	
	if(api.OS >= TOS_VISTA) { // allow non elevated processes to send control messages (eg, App with admin rights, explorer without)
		#define MSGFLT_ADD 1
		#define MSGFLT_REMOVE 2
		typedef BOOL (WINAPI* ChangeWindowMessageFilter_t)(UINT message,DWORD dwFlag);
		ChangeWindowMessageFilter_t ChangeWindowMessageFilter=(ChangeWindowMessageFilter_t)GetProcAddress(GetModuleHandle("user32"), "ChangeWindowMessageFilter");
		if(ChangeWindowMessageFilter){
			int msgid;
			ChangeWindowMessageFilter(g_WM_TaskbarCreated,MSGFLT_ADD);
			ChangeWindowMessageFilter(WM_COMMAND,MSGFLT_ADD);
			for(msgid=WM_MOUSEFIRST; msgid<=WM_MOUSELAST; ++msgid)
				ChangeWindowMessageFilter(msgid,MSGFLT_ADD);
			for(msgid=MAINMFIRST; msgid<=MAINMLAST; ++msgid)
				ChangeWindowMessageFilter(msgid,MSGFLT_ADD);
		}
	}
	
	// create a hidden window
	g_hwndTClockMain = hwndMain = CreateWindowEx(WS_EX_NOACTIVATE, MAKEINTATOM(g_atomTClock),NULL, 0, 0,0,0,0, NULL,NULL,g_instance,NULL);
	// This Checks for First Instance Startup Options
	ProcessCommandLine(hwndMain,lpCmdLine);
	
	GetHotKeyInfo(hwndMain);
	
	if(api.OS > TOS_2000) {
		if(api.GetInt("Desktop", "MonOffOnLock", 0))
			RegisterSession(hwndMain);
	}
	if(updated==1){
		PostMessage(hwndMain,WM_COMMAND,IDM_SHOWPROP,0);
	}
	while(GetMessage(&msg, NULL, 0, 0)) {
		if(!(g_hwndSheet && IsWindow(g_hwndSheet) && PropSheet_IsDialogMessage(g_hwndSheet,&msg))
		&& !(g_hDlgTimer && IsWindow(g_hDlgTimer) && IsDialogMessage(g_hDlgTimer,&msg))
		&& !(g_hDlgTimerWatch && IsWindow(g_hDlgTimerWatch) && IsDialogMessage(g_hDlgTimerWatch,&msg))
		&& !(g_hDlgStopWatch && IsWindow(g_hDlgStopWatch) && IsDialogStopWatchMessage(g_hDlgStopWatch,&msg))){
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	
	UnregisterHotKey(hwndMain, HOT_TIMER);
	UnregisterHotKey(hwndMain, HOT_WATCH);
	UnregisterHotKey(hwndMain, HOT_STOPW);
	UnregisterHotKey(hwndMain, HOT_PROPR);
	UnregisterHotKey(hwndMain, HOT_CALEN);
	UnregisterHotKey(hwndMain, HOT_TSYNC);
	
	UnregisterSession(hwndMain);
	
	EndNewAPI(NULL);
	
	return (int)msg.wParam;
}
예제 #9
0
파일: main.c 프로젝트: dubepaul/T-Clock
//========================================================================================
//	/exit		exit T-Clock 2010
//	/prop		show T-Clock 2010 properties
//	/SyncOpt	SNTP options
//	/Sync		synchronize the system clock with an NTP server
//	/start		start the Stopwatch (open as needed)
//	/stop		stop (pause really) the Stopwatch
//	/reset		reset Stopwatch to 0 (stop as needed)
//	/lap		record a (the current) lap time
//================================================================================================
//---------------------------------------------//---------------+++--> T-Clock Command Line Option:
void ProcessCommandLine(HWND hwndMain,const char* cmdline)   //-----------------------------+++-->
{
	int justElevated = 0;
	const char* p = cmdline;
	if(g_hwndTClockMain != hwndMain){
		g_hwndTClockMain = CreateWindow("STATIC",NULL,0,0,0,0,0,HWND_MESSAGE_nowarn,0,0,0);
		SubclassWindow(g_hwndTClockMain, MsgOnlyProc);
	}
	
	while(*p != '\0') {
		if(*p == '/') {
			++p;
			if(strncasecmp(p, "prop", 4) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_SHOWPROP, 0);
				p += 4;
			} else if(strncasecmp(p, "exit", 4) == 0) {
				SendMessage(hwndMain, MAINM_EXIT, 0, 0);
				p += 4;
			} else if(strncasecmp(p, "start", 5) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_START, 0);
				p += 5;
			} else if(strncasecmp(p, "stop", 4) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_STOP, 0);
				p += 4;
			} else if(strncasecmp(p, "reset", 5) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_RESET, 0);
				p += 5;
			} else if(strncasecmp(p, "pause", 5) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_PAUSE, 0);
				p += 5;
			} else if(strncasecmp(p, "resume", 6) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_RESUME, 0);
				p += 6;
			} else if(strncasecmp(p, "lap", 3) == 0) {
				SendMessage(hwndMain, WM_COMMAND, IDM_STOPWATCH_LAP, 0);
				p += 3;
			} else if(strncasecmp(p, "SyncOpt", 7) == 0) {
				if(HaveSetTimePermissions()){
					if(!SendMessage(hwndMain, WM_COMMAND, MAKEWPARAM(IDM_SNTP,1), 0)){
						NetTimeConfigDialog(justElevated);
					}
				}else{
					SendMessage(hwndMain, WM_COMMAND, IDM_SNTP, 0);
				}
				p += 7;
			} else if(strncasecmp(p, "Sync", 4) == 0) {
				p += 4;
				SendMessage(hwndMain, WM_COMMAND, MAKEWPARAM(IDM_SNTP_SYNC,justElevated), 0);
				if(g_hwndTClockMain == hwndMain)
					SendMessage(hwndMain, MAINM_EXIT, 0, 0);
			} else if(strncmp(p, "Wc", 2) == 0) { // Win10 calendar "restore"
				if(p[2] == '1') // restore to previous
					api.SetSystemInt(HKEY_LOCAL_MACHINE, kSectionImmersiveShell, kKeyWin32Tray, 1);
				else // use the slow (new) one
					api.DelSystemValue(HKEY_LOCAL_MACHINE, kSectionImmersiveShell, kKeyWin32Tray);
				p += 2;
			} else if(strncmp(p, "UAC", 3) == 0) {
				justElevated = 1;
				p += 3;
			}
			continue;
		}
		++p;
	}
	
	if(g_hwndTClockMain != hwndMain){
		const DWORD kTimeout = 10000;
		const DWORD kStartTicks = GetTickCount();
		DWORD timeout;
		MSG msg;
		msg.message = 0;
		for(;;){
			int have_ui = IsWindow(g_hwndSheet) || IsWindow(g_hDlgTimer) || IsWindow(g_hDlgTimerWatch) || IsWindow(g_hDlgSNTP) || IsWindow(g_hDlgStopWatch);
			if(have_ui)
				timeout = INFINITE;
			else if(IsPlaying())
				timeout = 200;
			else
				break;
			MsgWaitForMultipleObjectsEx(0, NULL, timeout, QS_ALLEVENTS, MWMO_INPUTAVAILABLE);
			while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
				if(msg.message == WM_QUIT)
					break;
				if(!(g_hwndSheet && IsWindow(g_hwndSheet) && PropSheet_IsDialogMessage(g_hwndSheet,&msg))
				&& !(g_hDlgTimer && IsWindow(g_hDlgTimer) && IsDialogMessage(g_hDlgTimer,&msg))
				&& !(g_hDlgTimerWatch && IsWindow(g_hDlgTimerWatch) && IsDialogMessage(g_hDlgTimerWatch,&msg))
				&& !(g_hDlgSNTP && IsWindow(g_hDlgSNTP) && IsDialogMessage(g_hDlgSNTP,&msg))
				&& !(g_hDlgStopWatch && IsWindow(g_hDlgStopWatch) && IsDialogStopWatchMessage(g_hDlgStopWatch,&msg))){
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
			}
			if(msg.message == WM_QUIT)
				break;
			if(!have_ui) {
				DWORD elapsed = GetTickCount() - kStartTicks;
				if(elapsed >= kTimeout)
					break;
			}
		}
		DestroyWindow(g_hwndTClockMain);
		g_hwndTClockMain = NULL;
	}
}
예제 #10
0
LRESULT CALLBACK Window_Calendar(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
	case WM_CREATE:{
		int iMonths,iMonthsPast;
		DWORD dwCalStyle;
		RECT rc; HWND hCal;
		size_t idx;
		size_t dirty = 0;
		
		iMonths = api.GetIntEx(L"Calendar", L"ViewMonths", 3);
		iMonthsPast = api.GetIntEx(L"Calendar", L"ViewMonthsPast", 1);
		
		if(api.GetInt(L"Calendar", L"ShowDayOfYear", 1)) {
			wchar_t szTitle[32];
			GetDayOfYearTitle(szTitle,iMonths);
			SetWindowText(hwnd,szTitle);
		}
		
		dwCalStyle = WS_CHILD|WS_VISIBLE;
		if(api.GetInt(L"Calendar",L"ShowWeekNums",0))
			dwCalStyle|=MCS_WEEKNUMBERS;
		
		hCal = CreateWindowEx(0, MONTHCAL_CLASS, L"", dwCalStyle, 0,0,0,0, hwnd, NULL, NULL, NULL);
		if(!hCal) return -1;
		
		for(idx=0; idx<CALENDAR_COLOR_NUM; ++idx){
			unsigned color = api.GetInt(L"Calendar", g_calendar_color[idx].reg, TCOLOR(TCOLOR_DEFAULT));
			if(color != TCOLOR(TCOLOR_DEFAULT)){
				dirty |= (1<<idx);
				MonthCal_SetColor(hCal, g_calendar_color[idx].mcsc, api.GetColor(color,0));
			}
		}
		if(dirty&~1)
			SetXPWindowTheme(hCal, NULL, L"");
		
		MonthCal_GetMinReqRect(hCal,&rc);//size for a single month
		if(iMonths>1){
			#define CALBORDER 4
			#define CALTODAYTEXTHEIGHT 13
			rc.right+=CALBORDER;
			rc.bottom-=CALTODAYTEXTHEIGHT;
			if(api.OS == TOS_2000){
				rc.right+=2;
				rc.bottom+=2;
			}
			switch(iMonths){
			/*case 1:*/ case 2: case 3:
			case 4: case 5:
				rc.right*=iMonths;
				break;
			case 6:
				rc.bottom*=3;
				/* fall through */
			case 7: case 8:
				rc.right*=2;
				if(iMonths!=6) rc.bottom*=4;
				break;
			case 9:
				rc.bottom*=3;
			case 11: case 12:
				rc.right*=3;
				if(iMonths!=9) rc.bottom*=4;
				break;
			case 10:
				rc.right*=5;
				rc.bottom*=2;
				break;
			}
			rc.right-=CALBORDER;
			rc.bottom+=CALTODAYTEXTHEIGHT;
			if(api.OS >= TOS_VISTA)
				MonthCal_SizeRectToMin(hCal,&rc);//removes some empty space.. (eg at 4 months)
		}else{
			if(rc.right<(LONG)MonthCal_GetMaxTodayWidth(hCal))
				rc.right=MonthCal_GetMaxTodayWidth(hCal);
		}
		SetWindowPos(hCal,HWND_TOP,0,0,rc.right,rc.bottom,SWP_NOZORDER|SWP_NOACTIVATE);
		if(iMonthsPast){
			SYSTEMTIME st,stnew; MonthCal_GetCurSel(hCal,&st); stnew=st;
			stnew.wDay=1;
			if(iMonthsPast>=stnew.wMonth){ --stnew.wYear; stnew.wMonth+=12; }
			stnew.wMonth-=(short)iMonthsPast;
			if(stnew.wMonth>12){ ++stnew.wYear; stnew.wMonth-=12; }  // in case iMonthsPast is negative
			MonthCal_SetCurSel(hCal,&stnew);
			MonthCal_SetCurSel(hCal,&st);
		}
		SetFocus(hCal);
		AdjustWindowRectEx(&rc,WS_CAPTION|WS_POPUP|WS_SYSMENU|WS_VISIBLE,FALSE,0);
		SetWindowPos(hwnd,HWND_TOP,0,0, rc.right-rc.left,rc.bottom-rc.top, SWP_NOMOVE);//force to be on top
		if(m_bTopMost)
			SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
		api.PositionWindow(hwnd, (api.OS<TOS_WIN10 && api.OS>=TOS_WIN7 ? 11 : 0));
		if(m_bAutoClose && GetForegroundWindow()!=hwnd)
			PostMessage(hwnd,WM_CLOSE,0,0);
		return 0;}
	case WM_ACTIVATE:
		if(!m_bTopMost){
			if(LOWORD(wParam)==WA_ACTIVE || LOWORD(wParam)==WA_CLICKACTIVE){
				SetWindowPos(hwnd,HWND_TOPMOST_nowarn,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
			}else{
				SetWindowPos(hwnd,HWND_NOTOPMOST_nowarn,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
				// actually it should be lParam, but that's "always" NULL for other process' windows
				SetWindowPos(GetForegroundWindow(),HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
			}
		}
		if(m_bAutoClose){
			if(LOWORD(wParam)!=WA_ACTIVE && LOWORD(wParam)!=WA_CLICKACTIVE){
				PostMessage(hwnd,WM_CLOSE,0,0);//adds a little more delay which is good
			}
		}
		break;
	case WM_DESTROY:
		Sleep(50);//we needed more delay... 50ms looks good (to allow T-Clock's FindWindow to work) 100ms is slower then Vista's native calendar
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}