Copy Date/Time to Windows Clipboard with C++

December 20, 2010 at 12:44 (c++, windows)

I was unable to find a suitable program to quickly generate a timestamp in the format I desired, so I decided to write one using C++, specifically MinGW’s g++ v4.5.0 along with <windows.h>. This is my first real experience with Windows-specific programming other than a few hello worlds, so it was instructive as well as frustrating. It took considerable time to discover and familiarise myself with SetClipboardData(). Eventually I was able to modify the code in this thread (which didn’t compile as-is) and obtain a working clipboard prototype very similar to this, which I didn’t find until afterward. After that, it was mainly a matter of understanding the functions in <ctime>.

The format I was after is this:

2010-12-20 07:44:19 UTC-5

However, the code can of course be easily modified for various other formats. Here is the code:

#include <cstdio>
#include <ctime>
#include <windows.h>

#define MAX_STR_LEN 30

int WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
    // tz_offset is double to allow unusual time zones, e.g.,
    // Nepal Time (NPT), which is UTC+05:45 and would be rendered
    // by this program as UTC+5.75
    HGLOBAL handle;
    char *buffer, time_str[MAX_STR_LEN];
    time_t rawtime, utc_as_local;
    tm *ptm;
    double tz_offset;
    int dec_places = 2, fpart;

    // prepare clipboard
    if (!OpenClipboard(NULL)) return 0;
    EmptyClipboard();

    // get and format current time
    time(&rawtime);
    ptm = gmtime(&rawtime);
    utc_as_local = mktime(ptm);
    ptm = localtime(&rawtime);
    tz_offset = difftime(rawtime, utc_as_local) / 3600;
    fpart = (int)(tz_offset * 100) % 100;
    if (fpart == 0) dec_places = 0;
    else if (fpart % 10 == 0) dec_places = 1;
    sprintf(time_str, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d UTC%+.*f",
            ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
            ptm->tm_hour, ptm->tm_min, ptm->tm_sec, dec_places,
            tz_offset);

    // copy data to clipboard
    handle = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,
                         strlen(time_str) + 1);
    buffer = (char*)GlobalLock(handle);
    strcpy(buffer, time_str);
    GlobalUnlock(handle);
    SetClipboardData(CF_TEXT, handle);

    // clean up
    CloseClipboard();
    return 0;
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: