FileCmp
Visual C++ 2005 Express Edition
Windows Server 2003 SP1 Platform SDK
Windowsアプリケーション / 空のプロジェクト
FileCmp.c
// マルチバイト文字セット #include
#include
#include
#define APPNAME "FileCmp" #define BUFFER_SIZE 1048576 #define IDC_EDT_FILE1 1 #define IDC_EDT_FILE2 2 #define IDC_LBL_MESSAGE 3 #define IDC_BTN_COMPARE 4 // グローバル変数 static HINSTANCE g_hInstance; static char g_acIniFile[_MAX_PATH]; static HWND g_hEdtFile1; static HWND g_hEdtFile2; static HWND g_hLblMessage; static HWND g_hBtnCompare; static WNDPROC WndProcFile1; static WNDPROC WndProcFile2; static char g_acFile1[_MAX_PATH]; static char g_acFile2[_MAX_PATH]; static char *g_apcMessage[] = { "info: ファイルの長さが同じです。", "info: File1にファイルをドロップしてください。", "info: File2にファイルをドロップしてください。", "info: 同じpathです。", "error: File1の情報取得に失敗しました。", "error: File2の情報取得に失敗しました。", "info: ファイルの長さが違います。", "error: File1のオープンに失敗しました。", "error: File2のオープンに失敗しました。", "NG: 不一致です。", "OK: 一致しました。", }; // プロトタイプ宣言 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnBtnCompare(); void OnSize(WPARAM wParam, LPARAM lParam); void OnGetMinMaxInfo(LPARAM lParam); void OnCreate(HWND hWnd); void OnDestroy(HWND hWnd); LRESULT CALLBACK WndProcFile(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnDropFiles(HWND hWnd, WPARAM wParam); int FileCheck(); int FileCompare(); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char acAppName[] = APPNAME; WNDCLASSEX wcex; HWND hWnd; MSG msg; char acDrive[_MAX_DRIVE]; char acDir[_MAX_DIR]; char acFname[_MAX_FNAME]; char acExt[_MAX_EXT]; int iX; int iY; int iWidth; int iHeight; g_hInstance = hInstance; _splitpath_s(__argv[0], acDrive, _MAX_DRIVE, acDir, _MAX_DIR, acFname, _MAX_FNAME, acExt, _MAX_EXT); _makepath_s(g_acIniFile, _MAX_PATH, acDrive, acDir, acFname, ".ini"); iX = GetPrivateProfileInt("General", "iX", 0, g_acIniFile); iY = GetPrivateProfileInt("General", "iY", 0, g_acIniFile); iWidth = GetPrivateProfileInt("General", "iWidth", 480, g_acIniFile); iHeight = GetPrivateProfileInt("General", "iHeight", 240, g_acIniFile); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = acAppName; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wcex); hWnd = CreateWindow( acAppName, // ClassName acAppName, // WindowName WS_OVERLAPPEDWINDOW, iX, // x iY, // y iWidth, // Width iHeight, // Height NULL, // WndParent NULL, // Menu g_hInstance, NULL); // Param if (hWnd == NULL) { return 0; } ShowWindow(hWnd, nCmdShow); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BTN_COMPARE: OnBtnCompare(); break; } break; case WM_SIZE: OnSize(wParam, lParam); break; case WM_GETMINMAXINFO: OnGetMinMaxInfo(lParam); break; case WM_CREATE: OnCreate(hWnd); break; case WM_DESTROY: OnDestroy(hWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } void OnBtnCompare() { int iRet; iRet = FileCheck(); if (iRet == 0) { iRet = FileCompare(); } SetWindowText(g_hLblMessage, g_apcMessage[iRet]); } void OnSize(WPARAM wParam, LPARAM lParam) { int iWidth; int iHeight; int iEdtHeight; if (wParam == SIZE_MINIMIZED) { return; } iWidth = LOWORD(lParam); iHeight = HIWORD(lParam); iEdtHeight = (iHeight - 56) / 2; MoveWindow(g_hEdtFile1, 8, 8, iWidth - 16, iEdtHeight, TRUE); MoveWindow(g_hEdtFile2, 8, 16 + iEdtHeight, iWidth - 16, iEdtHeight, TRUE); MoveWindow(g_hLblMessage, 8, iHeight - 32, iWidth - 104, 24, TRUE); MoveWindow(g_hBtnCompare, iWidth - 88, iHeight - 32, 80, 24, TRUE); } void OnGetMinMaxInfo(LPARAM lParam) { MINMAXINFO *pmmi; pmmi = (MINMAXINFO*)lParam; pmmi->ptMinTrackSize.x = 480; pmmi->ptMinTrackSize.y = 240; } void OnCreate(HWND hWnd) { g_hEdtFile1 = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_ACCEPTFILES, "EDIT", NULL, WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, hWnd, (HMENU)IDC_EDT_FILE1, g_hInstance, NULL); WndProcFile1 = (WNDPROC)(LONG_PTR)GetWindowLong(g_hEdtFile1, GWL_WNDPROC); SetWindowLong(g_hEdtFile1, GWLP_WNDPROC, (LONG)(LONG_PTR)WndProcFile); g_hEdtFile2 = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_ACCEPTFILES, "EDIT", NULL, WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL, 0, 0, 0, 0, hWnd, (HMENU)IDC_EDT_FILE2, g_hInstance, NULL); WndProcFile2 = (WNDPROC)(LONG_PTR)GetWindowLong(g_hEdtFile2, GWL_WNDPROC); SetWindowLong(g_hEdtFile2, GWL_WNDPROC, (LONG)(LONG_PTR)WndProcFile); g_hLblMessage = CreateWindow("STATIC", NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)IDC_LBL_MESSAGE, g_hInstance, NULL); g_hBtnCompare = CreateWindow("BUTTON", "Compare", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)IDC_BTN_COMPARE, g_hInstance, NULL); if (1 <= __argc) { SetWindowText(g_hEdtFile1, __argv[1]); } SetWindowText(g_hLblMessage, g_apcMessage[FileCheck()]); } void OnDestroy(HWND hWnd) { RECT rect; char acBuf[16]; GetWindowRect(hWnd, &rect); sprintf_s(acBuf, sizeof(acBuf), "%d", rect.left); WritePrivateProfileString("General", "iX", acBuf, g_acIniFile); sprintf_s(acBuf, sizeof(acBuf), "%d", rect.top); WritePrivateProfileString("General", "iY", acBuf, g_acIniFile); sprintf_s(acBuf, sizeof(acBuf), "%d", rect.right - rect.left); WritePrivateProfileString("General", "iWidth", acBuf, g_acIniFile); sprintf_s(acBuf, sizeof(acBuf), "%d", rect.bottom - rect.top); WritePrivateProfileString("General", "iHeight", acBuf, g_acIniFile); } LRESULT CALLBACK WndProcFile(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DROPFILES: OnDropFiles(hWnd, wParam); break; default: if (hWnd == g_hEdtFile1) { return CallWindowProc(WndProcFile1, hWnd, uMsg, wParam, lParam); } if (hWnd == g_hEdtFile2) { return CallWindowProc(WndProcFile2, hWnd, uMsg, wParam, lParam); } } return 0; } void OnDropFiles(HWND hWnd, WPARAM wParam) { HDROP hDrop; char acPath[_MAX_PATH]; hDrop = (HDROP)wParam; DragQueryFile(hDrop, 0, acPath, sizeof(acPath)); DragFinish(hDrop); SetWindowText(hWnd, acPath); SetWindowText(g_hLblMessage, g_apcMessage[FileCheck()]); } int FileCheck() { struct _stat stat1; struct _stat stat2; if (GetWindowText(g_hEdtFile1, g_acFile1, sizeof(g_acFile1)) <= 0) { return 1; } if (GetWindowText(g_hEdtFile2, g_acFile2, sizeof(g_acFile2)) <= 0) { return 2; } if (strcmp(g_acFile1, g_acFile2) == 0) { return 3; } if (_stat(g_acFile1, &stat1) != 0) { return 4; } if (_stat(g_acFile2, &stat2) != 0) { return 5; } if (stat1.st_size != stat2.st_size) { return 6; } return 0; } int FileCompare() { static char acBuf1[BUFFER_SIZE]; static char acBuf2[BUFFER_SIZE]; FILE *pfile1; FILE *pfile2; u_int uiRead1; u_int uiRead2; int iRetVal; if (fopen_s(&pfile1, g_acFile1, "rb") != 0) { return 7; } if (fopen_s(&pfile2, g_acFile2, "rb") != 0) { fclose(pfile1); return 8; } while (TRUE) { uiRead1 = (u_int)fread(acBuf1, 1, BUFFER_SIZE, pfile1); uiRead2 = (u_int)fread(acBuf2, 1, BUFFER_SIZE, pfile2); if (uiRead1 != uiRead2) { iRetVal = 6; break; } if (memcmp(acBuf1, acBuf2, uiRead1) != 0) { iRetVal = 9; break; } if (uiRead1 != BUFFER_SIZE) { iRetVal = 10; break; } } fclose(pfile2); fclose(pfile1); return iRetVal; }