Locking Workstation Turns Off Monitor(s) (I Just Had to Try Doing This)

System first week of year (used by popup calendar) adjustable via GUI

Popup calendar options for 1, 3, or 12 month view (still needs work but is there)

Added always on top option for calendar

Added display am/pm as a/p, A/P, and /p options

Build 90 - Added Font Quality option to resolve the Fuzzy Font Bugg, and Bouncing Alarm windows. (details)Okay... It's 12/23/2010, So I either have to either release this thing or change the name.Beta 8.5 Windows 2000 Support Returns! - Thanks to MSVS2008Beta 8 ... Same as first 8 Just repacked properly - Not a clue how I screwed that up.Beta 8 - End of High DPI Dialog Position Bugg (also added build # to About Tab)Beta 7.5 - Fixed Logic Error which caused Alarm AM/PM setting to be ignored.Beta 7.4 - Added Display (ISO) Week Numbers on Calendar Option, Close Calendar on Lose Focus Option, Calendar Dialog now dynamically resizes at runtime if/as needed (toggle Week Numbers to see), Added Miscellaneous Tab to Properties Dialog to Adjust Above.Beta 7.3 - Added Option to have Alarm Ring X TimesBeta 7.2 - Added Option to have Alarm Chime the Hour.Beta 7.1 - More Fun with the Alarm Tab Crash BuggBeta 7 - Rework of Alarms Page Control behavior & etc... (see thread for details)Beta 6 - This is a rough draft of the requested Time Synchronization feature (details to follow).Beta 5.5 - More mucking about with the infernal Hotkeys (which should finally be be nailed down at this point)Beta 5.2 - Fixed Loss of (HotKey) Focus BuggBeta 5 - Now with configurable HotKeys (I'm way to tired to post details)

Help file has been updated with new options - but it looks like hell Found this request for the Julian Date in an Email, so I tossed it in (Formatting Option JD)Added Hotkey Options for Stopwatch, Add/Edit Timers, & Timer Watch dialogs

6. The Properties Dialog Mouse Tab Crash Bugg is gone - Thanks to a T-Clock fan that (also happens to be a programmer) has been working with me via Email for the past few weeks.

5. There is an EasterEgg of sorts for the Win2k folk that (is easy to find in the registry) allows TC2010 to make the Desktop Icon Text Labels transparent.

4. Registry info structure has been modified slightly (Simplicity/Testing purposes) so TC2010 will not use/modify the TC3 configuration data.

3. Taskbar transparency has been brought back because (Um...) it seemed like the thing to do at the time. It has been tested and works on all the above.

2. It is stable, and has been tested on Win2k/XP/Server2k3 x64/7 x64 without any Shell hangs/crashes/etc.

1. Okay, so I finally managed to end up with something stable enough to share with the rest of the class ... There are a couple of things to be noted however: This is alpha so it ain't perfect.

Okay, So I've been trying to get this project back off the ground for a few years ... and as of late ... That's really been starting to bug me. Missing source code issues aside ...(long story documented elsewhere)... I still had the partially branded project file from the web server to work with. That copy however (actually all of them in retrospect...) had an issue with MSVS 2005 SP1, which caused a quite consistent shell crash on load. I confirmed this by compiling the code with MSVS 2005 (no service packs) and it did indeed run just fine. Hence the conclusion that either SP1 or something that SP1 didn't like about my code was the culprit.

I have spent the better part of the last 3 days hammering on this in an attempt to render that particular bugg nice and dead. I have succeeded. Hence (in a mild fit of artistic rage...) I have decided to display said buggs still twitching carcase here ... on the odd chance that someone may need to drive a similar stake through one of its cousins:

Quite true, but it was at least almost (but not quite) twice as much fun as trimming your toenails with a chainsaw...

But seriously... Being that I have multiple project files pointing at the same source pool, the 32-bit compile complained about the pointer conversion (might cause data loss (yada, yada, yada...)). So I had to make it conditional at compile time, which ends up being this:

What's up with having two casts (ie., (LONG)(LONG_PTR))? A single (LONG_PTR) ought to suffice, and work on both x86 and x64... reason for your old code crashing is probably that LONG is 32bit in both x86 and x64, so you get pointer truncation... whereas LONG_PTR is defined thus:

However, Originally I was using a single Line of code for both (e.g. no compile time switching), so I needed to get that single line to work on/for both the 32 & 64 bit versions ...(and I insist on the code compiling with zero errors or warnings)... Which is I think how I landed there. Did I mention that this (or rather that 4 year ago project) was my baptism by fire in the pointer casting department.

...Which works on both 32 & 64 bit test machines. I could try running a few tests with just (LONG_PTR)(LRESULT) for both after work if you think it would be cleaner, but for now I'm just glad to be done abusing my server.

Only x64 machines I have are my main (Win 7) dev machine and my (Win 2k3 R2) domain controller. Repeatedly crashing the shell on the dev machine makes it impossible to keep my notes in order ... So I've been torching the shell over & over via Terminal Services for the last few days on the Domain Controller. Which says a lot for TS as in over 100+ shell hangs/crashes the original session never disconnected once and the box is still stable.

Disclaimer: (Kids do not try this at home) This is not considered a good practice or even recommended behavior... (It's actually rather stupid)

Hm, just did a silly little test - obviously won't work runtime, but compiles clean with the following two compilers (VS2008 + SP1):Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86

...should work fine for older compilers as well, although there is a PlatformSDK dependency to have GWLP_* work (dunno when that was introduced, but iirc it works fine on VS2005).

Note that I prefer the C++ style cast operators, but C style (cast) just as well (they're less explicit and harder to grep for, though, and the C++ operators allow you to be more precise wrt. what/why you're casting).

Hm, just did a silly little test - obviously won't work runtime, but compiles clean with the following two compilers (VS2008 + SP1):Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86

...should work fine for older compilers as well, although there is a PlatformSDK dependency to have GWLP_* work (dunno when that was introduced, but iirc it works fine on VS2005).

It does, and is used/was required to get the origional (VS2k5) project off the ground

Note that I prefer the C++ style cast operators, but C style (cast) just as well (they're less explicit and harder to grep for, though, and the C++ operators allow you to be more precise wrt. what/why you're casting).

That decision was made for me as the origional (authors) code is pure C, which I haven't changed ... But have regretted more than once...

f0dder - After going through and tidying up the various pointer castings TC2010 is proving to be quite stable. I've even spent some quality time trying to crash it, and happily failed. Rather odd side note is that the strange behavior of the Mouse Tab of the Properties Dialog crashing the program seems to have disappeared. So I've tentatively (also) crossed that Bugg off the To-Do list for the moment.

Daleus - Thank You, I truly appreciate the encouragement. I got hooked on TClock back in the late 90s and am completely incapable of parting with it. If you are interested in a bit of (alpha/) beta testing ... I could be easily coerced into posting a download of TC2010 once I get a few more things ironed out.

As I'm sure you know, it's quite common in C to store pointers in int variables. While this might not be a good practice in general there are times when it makes sense, such as for SetWindowLongPtr() where all the API is interested in is storing a small blob of data - it doesn't care what that data is (the user of the API gets to decide what the data means).

The intent of the LONG_PTR/ULONG_PTR types is the same as C99's intptr_t and uintptr_t types which is to be able to declare an integer type that can hold a pointer - exactly for situations like Win64 where pointers are larger than normal ints. The C99 standard calls them "Integer types capable of holding object pointers".

On the other hand, Microsoft should have made it so that passing a LONG_PTR type (whether by casting or not) to SetWindowLongPtr() should not have caused a warning whether the build was for 32 or 64 bit. That's really where something fell down here. The whole point of a type like LONG_PTR is so that the conditional code that Stoic Joker ended up using wouldn't be necessary.

As I'm sure you know, it's quite common in C to store pointers in int variables. While this might not be a good practice in general there are times when it makes sense, such as for SetWindowLongPtr() where all the API is interested in is storing a small blob of data - it doesn't care what that data is (the user of the API gets to decide what the data means).

A void* is a better choice - it's opaque ("don't go around manipulating this like you woudl an int"), you don't run into trouble on platforms where sizeof(int) != sizeof(T*) (16- and 64-bit x86 platforms), et cetera. 8 of the 10 documented indices for Get/SetWindowLongPtr are pointer types.

On the other hand, Microsoft should have made it so that passing a LONG_PTR type (whether by casting or not) to SetWindowLongPtr() should not have caused a warning whether the build was for 32 or 64 bit. That's really where something fell down here. The whole point of a type like LONG_PTR is so that the conditional code that Stoic Joker ended up using wouldn't be necessary.

And, at least on VC2008, there is no warning when doing the single cast. Can't see why there would be with other versions of the compiler, either, really - but mistakingly using SetWindowLong (instead of SetWindowLongPtr) at 4am because you haven't had enough coffee... then yeah (or perhaps some flaky old PlatformSDK version - but I kinda doubt that as well).

The PSDK is a big effing mess with some of the worst C coding styles, it's a shame MS has never cleaned it up. Stuff like using enums instead of #defines, inline functions for the ApiNameA/W distinguishing, etc.

Okay, Just to show that I haven't dropped-the-ball...again... (Here's an update)

Before:

After:

Mouse Tab has been reorganized and I added a ListView of all currently configured mouse click options for clarity. Screen Shots were taken on my 64-bit Server 2003 Domain Controller - No crashes were experienced during testing...

Mouser - Sorry man, wasn't ignoring you, I've just been busy trying to keep the project rolling while I'm still in this window of opportunity (time wise). Most of what had been update/fixed was under the hood stuff. Biggest item being the Properties Dialog's habit of crashing the clock (and shell) any time the mouse options tab had been viewed. I should probably do a proper posting with one of the NANY release templates at some point to avoid confusion.

So... I decided to tackle the Timers part of T-Clock, as it has always kinda bugged me (OK, it was total shit to be honest... ) While not completely finished, it is working well enough to share. The Stopwatch part (what pathetic attempt at one there was) has been temporally removed until I can do it properly (which is next). Latest updated build of T-Clock available bottom of first post in thread.

Before:

After:

Multiple timers can be stopped and started from the UI (stopping a timer previously required restarting the clock), Timers can now be set for Days/Hours/Minutes/Seconds, instead of just minutes. Running timers menu now gives the names of the running timers and are click-able to open a current time remaining message. MessageBox will be replaced by a running "live" countdown eventually - but I ain't there yet.

10-second timer worked -- at least, when I specified a .wav file, I heard something at what seemed like around 10 seconds

60-second and 100-second timers seem to give me times rather longer than 60 or 100 seconds (at least when I choose the timer from the context menu, the dialog box that comes up says something like 18:wx:yz). Being able to specify values greater than or equal to 60 for seconds is a good feature IMHO because sometimes we are quoted values from external sources, and not having to manually convert those values to set timers would be much appreciated

Tab order among fields for the Timer dialog seemed odd to me. Here's the order I observed for when there are no timers yet:

Tab Order You got me! I knew I was forgetting something (Using forest for the trees defense).

the dialog box that comes up says something like 18:wx:yz

format of that is hh:mm:ss so it looks like it's counting down from 18 hours.

60 - 100 seconds timer? ...I ganged all the spinner controls together so that clicking up on 59 seconds would automatically set minutes to one. So as each spinner reaches it max (or min) value, it will start updating its neighbor control.

The intent behind the design was that 60 seconds be 1 minute, and 100 seconds be 1 minute 40 seconds.

I spent a lot of time trying to work out how to do this, and didn't think enough about should I do this perhaps? I can pull that (update yer neighbor) part if it's to confusing/annoying - or try tweaking it for clarity if it's saveable.

Yup. As a somewhat vague example, there are these sites that make you wait before letting you do certain things, and if you miss a window of opportunity you are made to wait another period of time. It has been my experience that the quoted wait times are often communicated in seconds. I've seen 500 seconds wait times, FWIW.

I ganged all the spinner controls together so that clicking up on 59 seconds would automatically set minutes to one. So as each spinner reaches it max (or min) value, it will start updating its neighbor control.

Aha. Thanks for the explanation.

A little more detail on what I did:

I put the focus in the seconds field, entered 100 and subsequently used tab to visit other fields, ensuring that the other time fields were 0. From what I can see, tabbing off of the seconds field does not appear to update the time fields. At the time when I click on the start button, what I see for time values consists of:

0 Days 0 Hours 0 Minutes 100 Seconds

If I visit the Timer dialog subsequently and copy-paste the seconds value elsewhere, I see a value of 65595.

I can pull that (update yer neighbor) part if it's to confusing/annoying - or try tweaking it for clarity if it's saveable.

I'm not sure yet. There is an element of convenience to having the conversion done automatically.

For comparison...

For reference, in a former life, I wrote a timer plugin for some program. The method I used there for specifying times was purely via a single text field. Some examples of expressions I supported were:

1h20m4s (1 hour 20 min 4 sec) 4m3s (4 min 3 sec) 500s (500 seconds)

1:30 (1 min 30 sec) 2:30:10 (2 hours 30 min 10 sec)

3 (3 min) 1.5 (1 min 30 sec) 20r (every 20 minutes)

The main emphasis was on being able to quickly create timers -- and to be honest, I find not having to tab to different controls more convenient for specifying times from scratch. However, I think that visually speaking, the spinner arrangement in T-Clock provides a stabler, more normalized feeling. I think it may be nicer for editing existing timers, and as far as reading an existing time specification is concerned I think it may be better than a single text field. (Perhaps a potentially nice addition might be for the dialog to also display at what time a timer will expire.)

I noticed that if I press the X button to remove a timer without stopping it first, it still appears under the T-Clock Timers submenu. After the timer expires, it goes away, but I guess there's no straight-forward way to get at it to stop it. Am I missing something obvious may be?

For future consideration

Ah, one more thing I forgot to mention in my previous post. After I deleted all timers, leave the timer dialog, and return to it, the File text field is empty (which makes some sense). Unfortunately, though, clicking on "..." brings up a File Open dialog pointing initially at the directory for the T-Clock binary. If it's doable, perhaps it'd be more convenient to have the directory location point to the most recently used location for a timer with a sound. What do you think?

Holy Hell, Mom Was Right - If you pick at a loose thread, he whole damn thing unravels... (I'll explain later)

Yup. As a somewhat vague example, there are these sites that make you wait before letting you do certain things, and if you miss a window of opportunity you are made to wait another period of time. It has been my experience that the quoted wait times are often communicated in seconds. I've seen 500 seconds wait times, FWIW.

A little more detail on what I did:

I put the focus in the seconds field, entered 100 and subsequently used tab to visit other fields, ensuring that the other time fields were 0. From what I can see, tabbing off of the seconds field does not appear to update the time fields. At the time when I click on the start button, what I see for time values consists of:

0 Days 0 Hours 0 Minutes 100 Seconds

If I visit the Timer dialog subsequently and copy-paste the seconds value elsewhere, I see a value of 65595.

if(day >42) day =7;// It was either Hitchhikers Guide to the Galaxy -or- the 49.7 day bugg :-)

}

Now you can stick anything anywhere & it'll convert it for you on-the-fly as needed.

I noticed that if I press the X button to remove a timer without stopping it first, it still appears under the T-Clock Timers submenu. After the timer expires, it goes away, but I guess there's no straight-forward way to get at it to stop it. Am I missing something obvious may be?

Yes, that would be the I'm obviously not that bright, part. The extra flurry of message boxes that I'm sure you noticed were supposed to remind me (test values) I hadn't finished coding that part. The next release will include the Auto-Suicide on Delete function - That I forgot to do earlier (...Thanks for reminding me... ).

So, do I really still need to explain the Thread Comment?

Rather bizzar side effect, when I reordered the controls in the .rc script to fix the Tab Order (which I've done many times) Tabs have now completely quit working (e.g. Key Has No Effect).

And etc. *Shrug* ...But that's enough whinning I gota get back to work