概要

 ファイルをエディットボックスにドラッグするとファイルの更新日時を表示します。
 日時を修正してOKボタンをクリックするファイルの作成日時・アクセス日時・更新日時を変更します。

テスト環境

コンパイラ

Visual C++ 2008/2013 Express 32bit/64bit マルチバイト/UNICODE

実行環境

Windows 10 Home Version 1803 64bit

プログラムソースの概要

_tWinMain

 コマンドラインの引数をチェックしダブルコーテーションで囲まれている場合は取り除きます。
 DialogBox APIによりダイアログボックスを表示します。

DlgProc1

WM_INITDIALOG

 ダイアログボックスの初期化時に呼び出されます。
 DragAcceptFiles APIを読み出すことによりファイルのドラッグ&ドラッグの受付を許可します。
 起動時の引数にファイルが指定されていた場合は、エディットボックスにファイル名を設定します。
 fileTimeGet関数によりファイルの更新日時を取得し表示します。

WM_DROPFILES

 ファイルがドラッグ&ドラッグされるとDlgProc1関数にWM_DROPFILESメッセージが発生するので、DragQueryFile関数で最初にファイルの個数を取得し、次にファイル名を取得します。
 最初の1個のファイル名のみエディットボックスに設定します。
 fileTimeGet関数によりファイルの更新日時を取得し表示します。

WM_COMMAND

ボタンがクリックされると、WM_COMMANDメッセージが発生します。
ID_OK
 DateTime_GetSystemtimeマクロにより年月日及び時刻それぞれSYSTEMTIME構造体へ取得します。
 年月日が格納されている構造体に時刻の構造体の時刻部分のみコピーします。
 SYSTEMTIME構造体をSystemTimeToFileTime APIでファイルタイム{ローカルタイム 64bit整数}に変換します。
 ローカルタイムをLocalFileTimeToFileTime APIでUTCのファイルタイムに変換します。
 SetFileTime APIでファイル・フォルダーの日時を変更します。
 CloseHandle APIでファイル・フォルダーを閉じます。
 EndDialog APIによりダイアログボックスを終了します。
IDCANCEL
 EndDialog APIによりダイアログボックスを終了します。

fileTimeGet

 日時を取得するためにCreateFile APIでファイルのハンドルを取得します。
 GetFileTime APIでファイルの作成日時・アクセス日時・更新日時を取得します。
 GetFileTime APIで取得できる日時はファイルタイムと呼ばれるもので1601年(関ヶ原の戦いの年)1月1日から100n秒(0.1μ秒=10-7秒)で表される64bitの整数です。
 まず取得された日時は協定世界時(UTC)ですのでFileTimeToLocalFileTime APIで日本時刻(64bit整数)に変換します。(9時間を加算)
 FileTimeToSystemTime APIによりローカルタイム{日本時刻(64bit整数)}を年月日・時分秒が分解されて扱いやすいSYSTEMTIME構造体に変換します。
 以下にminwinbase.hで定義されているSYSTEMTIME構造体を示します。
typedef struct _SYSTEMTIME {
    WORD wYear;         // 西暦
    WORD wMonth;        // 月
    WORD wDayOfWeek     // 曜日 日曜=0 土曜=6
    WORD wDay;          // 日
    WORD wHour;         // 時
    WORD wMinute;       // 分
    WORD wSecond;       // 秒
    WORD wMilliseconds; // ミリ秒
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
 DateTIme_SetSystemTimeマクロにより更新日時を表示します。

ソースコード

mtouch3.cpp

/	Date and Time Picker Controlサンプル ファイルの書き込み日時を修正
//	Visual C++ 2013 32/64bit
#include <windows.h>
#include <commctrl.h> 
#include <time.h>
#include <tchar.h>
#include "resource.h"

TCHAR* file = 0;
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
//	ファイルの更新日時を取得しダイアログに表示する
HANDLE fileTimeGet(HWND hDlg, TCHAR* fname);

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
						TCHAR* lpszCmdLine, int nCmdShow){
	TCHAR f[MAX_PATH];
	if (lpszCmdLine[0]){
		TCHAR nullz = _TEXT('¥0');
		if (lpszCmdLine[0]){
			if (lpszCmdLine[0] == _T('¥"')){
				_tcscpy_s(f, sizeof(f) / sizeof(TCHAR), lpszCmdLine + 1);
				f[_tcslen(f) - 1] = _T('¥0');
				file = f;
			}
			else
				file = lpszCmdLine;
		}
	}
	DialogBox(hInstance, TEXT("DLG"), 0, (DLGPROC)DlgProc1);
	return (int)0;
}

//	ダイアログボックスプロシージャー

LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
	TCHAR buf[MAX_PATH];
	static HANDLE hFile=0;
	SYSTEMTIME st,st2;
	FILETIME WriteTime;
	FILETIME localTime;

	switch (msg) {
		case WM_INITDIALOG:{
			DragAcceptFiles(hDlg, TRUE);
			if (file){
				SetWindowText(GetDlgItem(hDlg, IDC_EDIT105), file);
				hFile = fileTimeGet(hDlg, file);
			}
			return TRUE;
		}
		case WM_DROPFILES:{
			HDROP hDrop;
			hDrop = (HDROP)wParam;
			int fmax = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);
			DragQueryFile(hDrop, 0, buf, sizeof(buf) / sizeof(TCHAR));
			SetWindowText(GetDlgItem(hDlg, IDC_EDIT105),buf);
			DragFinish(hDrop);

			if (hFile)
				CloseHandle(hFile);
			hFile = fileTimeGet(hDlg,buf);
			break;
		}
		case WM_COMMAND:
			switch(LOWORD(wParam)){
				case IDOK:
					if (hFile){
						HWND hDate1 = GetDlgItem(hDlg, IDC_DTP100);
						DateTime_GetSystemtime(hDate1,&st);
						HWND hTime1 = GetDlgItem(hDlg, IDC_DTP102);
						DateTime_GetSystemtime(hTime1, &st2);
						st.wHour = st2.wHour;
						st.wMinute = st2.wMinute;
						st.wSecond = st2.wSecond;
						SystemTimeToFileTime(&st, &localTime);
						LocalFileTimeToFileTime(&localTime, &WriteTime);
						if (SetFileTime(hFile, &WriteTime, &WriteTime, &WriteTime) == 0){
							MessageBox(hDlg, _TEXT("ファイルの日時が変更できませんでした。"), _TEXT("エラー"), MB_OK);
						}
						CloseHandle(hFile);
						hFile = 0;
					}
					EndDialog(hDlg, TRUE);
					return TRUE;
				case IDCANCEL:
					if (hFile)
						CloseHandle(hFile);
					EndDialog(hDlg, FALSE);
					return FALSE;
				default:
					return FALSE;
			}
			default:
				return FALSE;
	}
	return TRUE;
}

//	ファイルの更新日時を取得しダイアログに表示する

HANDLE fileTimeGet(HWND hDlg, TCHAR* fname){
	SYSTEMTIME st;
	FILETIME CreationTime;
	FILETIME AccessTime;
	FILETIME WriteTime;
	FILETIME localTime;
	HANDLE hFile = CreateFile(fname, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE){
		MessageBox(hDlg, _TEXT("ファイルが開けません。"), _TEXT("エラー"), MB_OK);
		return 0;
	}
	//	現在のファイルの日時を取得表示
	GetFileTime(hFile, &CreationTime, &AccessTime, &WriteTime);

	FileTimeToLocalFileTime(&WriteTime, &localTime);	//	UTC→ローカルタイム
	FileTimeToSystemTime(&localTime, &st);	//	FILETIMEをSYSTEMTIMEに変換
	HWND hDate1 = GetDlgItem(hDlg, IDC_DTP100);
	DateTime_SetSystemtime(hDate1, GDT_VALID, &st);
	HWND hTime1 = GetDlgItem(hDlg, IDC_DTP102);
	DateTime_SetSystemtime(hTime1, GDT_VALID, &st);
	return hFile;
}

resource.h

#define	IDC_DTP100		100
#define	IDC_COMBOEX101	101
#define	IDC_DTP102		102
#define	IDC_EDIT105		105
#define	IDC_LABEL106	106

resource.rcp

#include <windows.h>
#include "resource.h"

DLG DIALOG DISCARDABLE 0, 0, 256, 120
EXSTYLE WS_EX_DLGMODALFRAME
STYLE WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT
CAPTION "ファイルの更新日時変更"
FONT 9, "MS Shell Dlg"
{
 CONTROL "ファイル名", IDC_LABEL106, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 8, 16, 70, 14
 CONTROL "ファイルをここへドラッグしてください", IDC_EDIT105, "EDIT", WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL, 8, 32,240, 14

 CONTROL "DTP100", IDC_DTP100, "SYSDATETIMEPICK32", WS_CHILD | WS_VISIBLE | DTS_RIGHTALIGN | DTS_LONGDATEFORMAT, 8, 64, 72, 14
 CONTROL "DTP100", IDC_DTP102, "SYSDATETIMEPICK32", WS_CHILD | WS_VISIBLE | DTS_RIGHTALIGN | DTS_TIMEFORMAT, 88, 64, 48, 14

 CONTROL "OK(&O)", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 66, 96, 54, 14
 CONTROL "キャンセル", IDCANCEL, "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 136, 96, 54, 14
}

実行ファイルとソースファイルのダウンロード