複数のjpgファイルを左右に分割するプログラム

icon 項目のみ表示/展開表示の切り替え

概要

 ドラッグドロップされた複数のjpgファイルを一括で左右に分割して保存します。
 分割後のファイル名は拡張子の前に左側はLを右側はRを付加して保存します。元のファイルは削除されます。
 本プログラムはVistaからサポートしている高DPIに対応するため複雑ことを行っています。
 マニフェストでの高DPIの宣言は不要です。

テスト環境

コンパイラ

Visual C++ 2008/2013 Express 32/64bit UNICODE

動作確認

Windows 7
Windows 8.1
Windows 10 Version 1803

動作例

本プログラムを起動した状態

プログラムソースの概要

gsplit.cpp

以下に主要な関数の処理を記述しています。

_tWinMain

 高DPIに対応するために以下の処理をしています。
SetThreadDpiAwarenessContext
 Windows 10 Version 1703より古い場合、プログラムの初期時にSetThreadDpiAwarenessContext APIが存在するかチェックし存在する場合、Windows10のバージョンをチェックします。
 バージョンが1607の場合は、非クライアント領域の大きさを変更させるためWM_NCCREATEメッセージ発生時にEnableNonClientDpiScalingを呼び出します。
 バージョンが1703以降の場合は、SetThreadDpiAwarenessContext APIでDPI_AWARENESS_PER_MONITOR_AWARE_V2を指定することにより Windowsに非クライアント領域の大きさの変更を自動にさせます。
SetProcessDPIAware
 SetThreadDpiAwarenessContext APIが使えない場合、SetProcessDPIAware API(Windows Vista以降)が使えるか確認します。
 事前にSetProcessDPIAware API(Windows Vista以降)を実行するとプログラム自身がスケーリング処理をすることになり正常なDPI値が返されます。実行しない場合、常に96DPIが返されます。Windows XPではこのAPIは存在しないので96DPIと仮定します。なおAPIが存在するかどうかは動的にライブラリをロードし関数のエントリポイントが存在するかどうかで判断しています。
 DPIはGetDpiForMonitor API(Windows 8.1以降)が使える場合はこの関数でウィンドウが属するモニターのDPIを、使えない場合GetDeviceCaps(hdc,LOGPIXELSX)によりディスクトップのDPIを取得します。
その他の処理
 GdiplusStartupによりGDI+の初期化をします。
 GetEncoderClsidによりjpegエンコーダを取得します。
 コマンドラインの引数の個数をチェックしダブルコーテーションで囲まれている場合は取り除きます。
 DialogBox APIによりダイアログボックスを表示します。
 GdiplusShutdownにより終了処理を実行します。

DlgProc1

WM_INITDIALOG
 ダイアログボックスの初期化時に呼び出されます。
 以下の処理はWindows 10 Version 1703以降では実行しません。
  1. ダイアログボックスの座標単位とスクリーン座標の変換に必要な定数をGetActualDialogBaseUnitsで取得
  2. scaleChange関数でダイアログボックス内の各コントロールの大きさ等を変更
 DragAcceptFiles APIを読み出すことによりファイルのドラッグ&ドラッグの受付を許可します。  
WM_DROPFILES
 ファイルがドラッグ&ドラッグされるとDlgProc1関数にWM_DROPFILESメッセージが発生するので、DragQueryFile関数で最初にファイルの個数を取得し、次にファイル名を取得します。
 取得されたファイル名は、リストボックスに登録します。
WM_DPICHANGED
 引数から現DPIを取得しscaleChange関数でダイアログボックス内の各コントロールの大きさ等を変更します。Windows 10 Version 1703以降では何もせずにWindowsに制御を渡します。
WM_NCCREATE
 Wndows10(Version1607)の時だけ非クライアント領域の処理するためEnableNonClientDpiScaling関数を呼び出します
WM_COMMAND
ボタンがクリックされると、WM_COMMANDメッセージが発生します。
IDC_BUTTON_DEL(削除)
 リストボックスで選択されているアイテムを名前だけ削除します。
 LB_GETCURSELメッセージでリストボックス上でアイテムが選択状態であることを確認してLB_DELETESTRINGメッセージで削除します。削除すると1行ずれるので一番下のアイテムの場合は1個上を、一番下でない場合は現位置(削除後の新しいアイテム)のアイテムをLB_SETCURSELメッセージで選択し直します。
IDC_BUTTON_ALL_DEL(全削除)
 リストボックスの全アイテムの名前だけを削除します。
 LB_RESETCONTENTメッセージによりリストボックスのアイテムを全部削除します。
 メモリ上にイメージがロードされている場合は解放します
ID_OK(OK(O))
 ファイル数をLB_GETCOUNTメッセージにより取得します。
 プログレスバーの範囲をPBM_SETRANGEメッセージにより0からファイル数に設定します。
 プログレスバーのステップ値をPBM_SETSTEPにより1にします。
 全ファイルについて以下の処理をします。
  1. LB_GETTEXTメッセージによりファイル名を取得
  2. imgcut関数でイメージファイルを左右に分割する。
  3. DeleteFile APIで元のファイルを削除する。
  4. PBM_STEPITでプログレスバーを1つ進める。
IDCANCEL(キャンセル(C))
 EndDialog APIによりダイアログボックスを終了します。

imgcut

 以下の処理をソースの左右の画像それぞれに実行します。
 左の画像にはLを右の画像にはRをファイル名に付加します。
 jpegファイルよりGdiplus::Imageオブジェクトを作成します。
 GDI+はunicodeしかサポートしないのでマルチバイトでコンパイルした場合は、unicodeに変換するコードを有効にします。
 GetHorizontalResolution,GetVerticalResolution関数によりソースファイルの解像度(DPI)を取得します。
 new Bitmapにより保存用のBitmapオブジェクトを作成します。
 SetResolutionでBitmapオブジェクトの解像度を設定します。
 Bitmapオブジェクトを元にGraphicsオブジェクトを作成します。
 DrawImage関数によりImageオブジェクトの指定領域をGraphicsオブジェクトに描画します。
 DrawImage関数には沢山のオーバーロードされた形式があります。
 描画が終了すればImageオブジェクトは不要なのでデストラクタでImageオブジェクトを解放します。
 Save関数によりBitmapオブジェクトをファイルに保存します。マルチバイトでコンパイルした場合は、unicodeに変換するコードを有効にします。
 Bitmapオブジェクト,Graphicsオブジェクトを解放します。

GetDir

 SHBrowseForFolder APIを呼び出し、フォルダーを選択するダイアログボックスを表示します。  初期化時にBrowseCallbackProc関数が呼び出されます。BFFM_INITIALIZEDメッセージの場合フォルダー選択の初期時のフォルダーを設定します。
 フォルダー名の選択が終了しOKボタンがクリックされると、SHBrowseForFolderが終了します。戻り値からSHGetPathFromIDListにより選択されたフォルダーのフルパスを取得できます。その後、SHBrowseForFolderで作成されたメモリをCoTaskMemFreeで解放します。

scaleChange

 現在のフォントを取得しスケールに応じたフォントを新規に作成し設定します。
 スケールからダイアログボックスの大きさを計算し、AdjustWindowRectによりクライアントサイズから必要なウィンドウサイズを計算しSetWindowPosによりダイアログボックスの大きさを変更します。
 各コントロールウィンドウをEnumChildWindowsで列挙します。

EnumWndProc

 EnumChildWindowsから呼び出されるEnumWndProc関数によりスケールに応じた位置、サイズ、文字サイズを設定します。
 スケールからコントロールの大きさを計算し、AdjustWindowRectによりクライアントサイズから必要なウィンドウサイズを計算しSetWindowPosによりダイアログボックスの大きさを変更します。
 コントロールのフォントをWM_SETTEXTメッセージにより変更します。

GetActualDialogBaseUnits

 ダイアログボックス座標の計算に必要な単位を取得します。
 YogaPro3では横が13、縦が31ピクセルが取得されました。

win10ver2

 Windows 10のバージョンを取得する関数です。
 詳細は、Windows 10のバージョン番号をRtlGetVersionのビルド番号から取得するを参照してください。

ソースコード

gsplit.cpp

// Jpegファイルを左右で2分割
// GDI+ランタイムが必要
// ファイルの指定は本ソフトにファイルをドラッグ&ドロップ

#include <windows.h>
#include <commctrl.h> 
#include <direct.h> 
#include <shlobj.h>
#include <shlwapi.h>
#include <gdiplus.h>
#include <stdio.h>
#include <tchar.h>
#include "resource.h"

#pragma comment(lib,"shlwapi.lib")
#pragma comment(lib,"gdiplus.lib")

#ifndef _DPI_AWARENESS_CONTEXTS_
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
#endif

typedef enum MONITOR_DPI_TYPE {
	MDT_EFFECTIVE_DPI = 0,
	MDT_ANGULAR_DPI = 1,
	MDT_RAW_DPI = 2,
	MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;


typedef HRESULT(_stdcall* GetDpiForMonitorFunc)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *);
typedef HRESULT(_stdcall* EnableNonClientDpiScalingFunc)(HWND);
typedef HRESULT(_stdcall* SetThreadDpiAwarenessContextFunc)(DPI_AWARENESS_CONTEXT);
typedef BOOL(_stdcall *SetProcessDPIAwareFunc)(VOID);

HMODULE hModUser32 = 0;
EnableNonClientDpiScalingFunc NcDpifunc = 0;
SetThreadDpiAwarenessContextFunc ThreadAwareFunc = 0;
EnableNonClientDpiScalingFunc NCCfunc = 0;

#ifndef _DPI_AWARENESS_CONTEXTS_

#define WM_DPICHANGED                   0x02E0

typedef enum _DPI_AWARENESS {
	DPI_AWARENESS_INVALID = -1,
	DPI_AWARENESS_UNAWARE = 0,
	DPI_AWARENESS_SYSTEM_AWARE = 1,
	DPI_AWARENESS_PER_MONITOR_AWARE = 2
} DPI_AWARENESS;

#define DPI_AWARENESS_CONTEXT_UNAWARE              ((DPI_AWARENESS_CONTEXT)-1)
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE         ((DPI_AWARENESS_CONTEXT)-2)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE    ((DPI_AWARENESS_CONTEXT)-3)
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)
#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED    ((DPI_AWARENESS_CONTEXT)-5)

#endif

using namespace Gdiplus;
GdiplusStartupInput gdiSI;
ULONG_PTR	gdiToken;
CLSID     encoderClsid;

LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid); //	エンコーダーの取得

TCHAR* file=0;
TCHAR def_dir[MAX_PATH];
int win10ver2(void);
int WIN10VER;

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst,TCHAR* lpszCmdLine, int nCmdShow){
	WIN10VER = win10ver2();
	hModUser32 = LoadLibrary(L"User32.dll");
	if (hModUser32){
		NCCfunc = (EnableNonClientDpiScalingFunc)GetProcAddress(hModUser32, "EnableNonClientDpiScaling");
		if (WIN10VER == 1607)	//	AnniversaryUpdate
			NCCfunc = (EnableNonClientDpiScalingFunc)GetProcAddress(hModUser32, "EnableNonClientDpiScaling");
		else
			NCCfunc = 0;
		ThreadAwareFunc = (SetThreadDpiAwarenessContextFunc)GetProcAddress(hModUser32, "SetThreadDpiAwarenessContext");
		if (ThreadAwareFunc){
			if (WIN10VER<1703)
				(*ThreadAwareFunc)(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
			if (1703 <= WIN10VER && WIN10VER<1809)
				(*ThreadAwareFunc)(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
			if (1809 <= WIN10VER)
				(*ThreadAwareFunc)(DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED);
		}
		else{	//	Windows Vista以降
			SetProcessDPIAwareFunc ProcessAwareFunc = (SetProcessDPIAwareFunc)GetProcAddress(hModUser32, "SetProcessDPIAware");
			if (ProcessAwareFunc)
				(*ProcessAwareFunc)();
		}
	}
	GdiplusStartup(&gdiToken, &gdiSI, NULL);
	if(GetEncoderClsid(L"image/jpeg", &encoderClsid)<0){
		MessageBox(0,TEXT("jpegエンコーダーが取得できませんでした。"),TEXT("エラー"),MB_OK);
		return (int)0;
	}
	TCHAR f[MAX_PATH];
	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;
	}
	if(DialogBox(hInstance, TEXT("DLG1"), 0, (DLGPROC)DlgProc1)){

	}
	GdiplusShutdown(gdiToken);
	if (hModUser32)
		FreeLibrary(hModUser32);
	return 0;
}

// srcファイルを左右で分割してdtcファイルに保存する。
int imgcut(TCHAR* dtc, TCHAR* src){
	Image* srcImage = 0;

#ifdef UNICODE
	srcImage = Bitmap::FromFile(src);
#else
	WCHAR srcFile[MAX_PATH];
	MultiByteToWideChar(932, 0, src, -1, srcFile, sizeof(srcFile) / sizeof(WCHAR));
	srcImage = Bitmap::FromFile(srcFile);
#endif

	if(srcImage == 0 || srcImage->GetLastStatus() != Gdiplus::Ok){
		srcImage->~Image();
		return -1;
	}
	float px_res = srcImage->GetHorizontalResolution();	//	jpgファイルの解像度DPI(横)
	float py_res = srcImage->GetVerticalResolution();	//	jpgファイルの解像度DPI(縦)
	Bitmap* bmp = new Bitmap(srcImage->GetWidth()/2, srcImage->GetHeight());		// 保存用
	bmp->SetResolution(px_res, py_res);

	Graphics*  MyGraphics = Graphics::FromImage(bmp);
	TCHAR buf[MAX_PATH];
	TCHAR* p;
	if(p=_tcsstr(dtc,_TEXT(".jpg"))){
		*p=0;
	}
	_tcscpy_s(buf, sizeof(buf) / sizeof(buf[0]), dtc);
	_tcscat_s(buf, sizeof(buf) / sizeof(buf[0]), _TEXT("L.jpg"));

	MyGraphics->DrawImage(srcImage, 0, 0, 0, 0, srcImage->GetWidth() / 2, srcImage->GetHeight(), UnitPixel);
	bmp->Save(buf, &encoderClsid);

	_tcscpy_s(buf, sizeof(buf) / sizeof(buf[0]), dtc);
	_tcscat_s(buf, sizeof(buf) / sizeof(buf[0]), _TEXT("R.jpg"));
	MyGraphics->DrawImage(srcImage, 0, 0, srcImage->GetWidth() / 2, 0, srcImage->GetWidth() / 2, srcImage->GetHeight(), UnitPixel);
	bmp->Save(buf, &encoderClsid);

	srcImage->~Image();

	delete bmp;
	delete MyGraphics;
	return 0;
}

BOOL GetActualDialogBaseUnits(HWND hDialog, SIZE *baseUnit){
	RECT rect;
	BOOL result;

	rect.left = 4;
	rect.top = 8;
	if (result = MapDialogRect(hDialog, &rect)) {
		baseUnit->cx = rect.left;
		baseUnit->cy = rect.top;
	}
	return result;
}

struct DLG_CHILD_SCALE{
	HWND hDlg;
	SIZE unit;
	UINT oldScale;
	UINT newScale;
	HFONT hFont;
};

//	各ウィンドウ(コントロールの移動及び大きさの変更
BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam){
	POINT pt;
	TCHAR name[16];
	GetClassName(hWnd, name, sizeof(name) / sizeof(name[0]));//リストビューのヘッダは孫ウィンドウ
	if (_tcscmp(name, _TEXT("SysHeader32")) == 0)
		return TRUE;
	DLG_CHILD_SCALE* d = (DLG_CHILD_SCALE*)lParam;
	pt.x = 0;
	pt.y = 0;
	ClientToScreen(hWnd, &pt);
	ScreenToClient(d->hDlg, &pt);
	RECT rc;
	GetClientRect(hWnd, &rc);
	int cx, cy, w, h;
	cx = MulDiv(pt.x, 4, d->unit.cx);
	cy = MulDiv(pt.y, 8, d->unit.cy);

	cx = MulDiv(cx, d->newScale, d->oldScale);
	cy = MulDiv(cy, d->newScale, d->oldScale);

	cx = MulDiv(cx, d->unit.cx, 4);
	cy = MulDiv(cy, d->unit.cy, 8);

	w = MulDiv(rc.right, d->newScale, d->oldScale);
	h = MulDiv(rc.bottom, d->newScale, d->oldScale);

	rc.left = cx;
	rc.top = cy;
	rc.right = cx + w;
	rc.bottom = cy + h;
	LONG style = GetWindowLong(hWnd, GWL_STYLE);
	LONG exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
	AdjustWindowRectEx(&rc, style, FALSE, exStyle);
	SetWindowPos(hWnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER);
	SendMessage(hWnd, WM_SETFONT, (WPARAM)d->hFont, MAKELPARAM(TRUE, 0));
	UpdateWindow(hWnd);

	return TRUE;
}
//	DPIスケールの変更
HFONT scaleChange(HWND hDlg, int nowScale, int oldScale, SIZE& baseUnit, HFONT hFont){
	LOGFONT lf;
	HWND hWnd;
	hWnd = GetWindow(hDlg, GW_CHILD);
	//hWnd = GetDlgItem(hDlg, IDC_END_ADR_EDIT);
	HDC hdc = GetDC(hWnd);
	HFONT hfont9 = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
	GetObject(hfont9, sizeof(LOGFONT), &lf);
	int height;
	height = lf.lfHeight * 100 / oldScale;
	lf.lfHeight = (height)*nowScale;
	lf.lfHeight /= 100;
	HFONT hFont2 = CreateFontIndirect(&lf);
	LOGFONT lfont;
	HFONT hFontOld = (HFONT)SelectObject(hdc, hFont2);

	TEXTMETRIC metrics;
	GetTextMetrics(hdc, &metrics);
	SelectObject(hdc, hFontOld);

	HFONT htemp = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0);
	GetObject(htemp, sizeof(LOGFONT), &lfont);
	ReleaseDC(hWnd, hdc);

	RECT rc;
	GetClientRect(hDlg, &rc);
	int w = rc.right - rc.left;
	int h = rc.bottom - rc.top;
	w = MulDiv(w, nowScale, oldScale);
	h = MulDiv(h, nowScale, oldScale);

	rc.left = 0;
	rc.top = 0;
	rc.right = w;
	rc.bottom = h;

	LONG style = GetWindowLong(hDlg, GWL_STYLE);
	AdjustWindowRectEx(&rc, style, FALSE, 0);

	SetWindowPos(hDlg, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER);

	DLG_CHILD_SCALE d;
	d.hDlg = hDlg;
	d.hFont = hFont2;
	d.newScale = nowScale;
	d.oldScale = oldScale;
	d.unit = baseUnit;

	EnumChildWindows(hDlg, EnumWndProc, (LPARAM)&d);

	InvalidateRect(hDlg, NULL, FALSE);
	UpdateWindow(hDlg);
	if (hFont)
		DeleteObject(hFont);
	return hFont = hFont2;
}

LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
	TCHAR buf[MAX_PATH];
	TCHAR src_file[MAX_PATH*2];

	HDROP hDrop;
	UINT fmax;
	int	i;
	static HFONT hFont = 0;
	static int nowDPIx = 96;
	static int nowDPIy = 96;
	static UINT nowScale = 100;
	static UINT initScale = 100;
	static int height;
	static HMODULE hMod;
	static GetDpiForMonitorFunc func = 0;
	static SIZE baseUnit;

	switch (msg) {
		case WM_INITDIALOG:
			DragAcceptFiles(hDlg, TRUE);
			if (WIN10VER < 1703){
				HMONITOR hMonitor = MonitorFromWindow(hDlg, MONITOR_DEFAULTTONULL);
				hMod = LoadLibrary(L"Shcore.dll");

				func = (GetDpiForMonitorFunc)GetProcAddress(hMod, "GetDpiForMonitor");
				if (func == 0)
					FreeLibrary(hMod);

				UINT hDPI, vDPI;
				if (func)
					(*func)(hMonitor, MDT_EFFECTIVE_DPI, &hDPI, &vDPI);
				else{
					HDC hdc = GetDC(NULL);	//	ディスクトップ
					hDPI = GetDeviceCaps(hdc, LOGPIXELSX);
					vDPI = GetDeviceCaps(hdc, LOGPIXELSY);
				}
				nowDPIx = hDPI;
				nowDPIy = vDPI;
				nowScale = MulDiv(nowDPIx, 100, 96);
				GetActualDialogBaseUnits(hDlg, &baseUnit);
				UINT oldScale = nowScale;
				hFont = scaleChange(hDlg, nowScale, oldScale, baseUnit, hFont);
			}
			if (file){
				SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) , LB_ADDSTRING , 0 , (LPARAM)file);
				SetWindowText(GetDlgItem(hDlg,IDC_LABEL1) , _TEXT("ファイル数 1"));
			}
			return TRUE;
		case WM_DROPFILES:
			hDrop = (HDROP)wParam;
			fmax = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);
			for(i = 0; i < (int)fmax; i++) {
				DragQueryFile(hDrop, i, buf, sizeof(buf)/sizeof(TCHAR));
				SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) , LB_ADDSTRING , 0 , (LPARAM)buf);
			}
			DragFinish(hDrop);
			fmax=(UINT)SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETCOUNT,0,0);
			_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),_TEXT("ファイル数 %i"),fmax);
			SetWindowText(GetDlgItem(hDlg,IDC_LABEL1) , buf);
			break;
		case WM_DPICHANGED:{
			if (WIN10VER < 1703){
				UINT oldScale = nowScale;
				nowDPIx = LOWORD(wParam);
				nowDPIy = HIWORD(wParam);
				nowScale = MulDiv(nowDPIx, 100, 96);
				hFont = scaleChange(hDlg, nowScale, oldScale, baseUnit, hFont);
			}
			break;
		}
		case WM_NCCREATE:{
			if (NCCfunc)
				(*NCCfunc)(hDlg);
			return FALSE;
		}
		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				case IDC_BUTTON_DEL:{
					int num = (int)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCURSEL, NULL, NULL);
					if (num == LB_ERR)
						break;
					SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_DELETESTRING, num, NULL);
					fmax = (UINT)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCOUNT, 0, 0);
					if ((UINT)num <= fmax - 1)
						SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_SETCURSEL, (WPARAM)num, 0L);
					else{
						SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_SETCURSEL, (WPARAM)--num, 0L);
					}
					_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("ファイル数 %i"), fmax);
					SetWindowText(GetDlgItem(hDlg, IDC_LABEL1), buf);
					break;
				}
				case IDC_BUTTON_ALL_DEL:{
					SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_RESETCONTENT, NULL, NULL);
					fmax = (UINT)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCOUNT, 0, 0);
					_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("ファイル数 %i"), fmax);
					SetWindowText(GetDlgItem(hDlg, IDC_LABEL1), buf);
					SendMessage(GetDlgItem(hDlg, IDC_PROGBAR1), PBM_SETPOS, 0, 0);
					break;
				}
				case IDOK:{
					fmax=(UINT)SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETCOUNT,0,0);
					SendMessage(GetDlgItem(hDlg,IDC_PROGBAR1),PBM_SETRANGE,0,MAKELPARAM(0,fmax));
					SendMessage(GetDlgItem(hDlg,IDC_PROGBAR1),PBM_SETSTEP,1,0);
					for(i = 0; i < (int)fmax; i++){
						SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETTEXT,i,(LPARAM)src_file);
						_tcscpy_s(buf,sizeof(buf)/sizeof(buf[0]),src_file);
						imgcut(buf, src_file);
						DeleteFile(src_file);
						SendMessage(GetDlgItem(hDlg,IDC_PROGBAR1),PBM_STEPIT,0,0);
						_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),_TEXT("ファイル数 %i/%i"),i,fmax);
						SetWindowText(GetDlgItem(hDlg,IDC_LABEL1) , buf);
					}
					return TRUE;
				}
				case IDCANCEL:
					EndDialog(hDlg,FALSE);
					return FALSE;
				default:
					return FALSE;
			}
			default:
				return FALSE;
	}
	return TRUE;
}

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
	UINT  num = 0;
	UINT  size = 0;
	ImageCodecInfo* pImageCodecInfo;
	GetImageEncodersSize(&num, &size);
	if(size == 0)
		return -1;
	pImageCodecInfo = (ImageCodecInfo*)new char[size];
	if(pImageCodecInfo == NULL)
		return -1;
	GetImageEncoders(num, size, pImageCodecInfo);
	for(UINT n=0; n<num; ++n) {
		if( wcscmp(pImageCodecInfo[n].MimeType, format) == 0 ) {
			*pClsid = pImageCodecInfo[n].Clsid;
			delete pImageCodecInfo;
			return n;
		}
	}
	delete pImageCodecInfo;
	return -1;
}
//	DLL内の関数へのポインタ型を定義
typedef void (WINAPI *RtlGetVersion_FUNC)(OSVERSIONINFOEXW*);

int win10ver2(void){
	int ver = 0;
	HMODULE hMod;
	OSVERSIONINFOEXW osw;
	hMod = LoadLibrary(TEXT("ntdll.dll"));
	RtlGetVersion_FUNC func;
	if (hMod){
		func = (RtlGetVersion_FUNC)GetProcAddress(hMod, "RtlGetVersion");
		if (func == 0){
			FreeLibrary(hMod);
			return FALSE;
		}
		ZeroMemory(&osw, sizeof(osw));
		osw.dwOSVersionInfoSize = sizeof(osw);
		func(&osw);
		FreeLibrary(hMod);
		if (osw.dwMajorVersion == 10){
			switch (osw.dwBuildNumber){
			case 10240: ver = 1507; break;
			case 10586: ver = 1511; break;
			case 14393: ver = 1607; break;
			case 15063: ver = 1703; break;
			case 16299: ver = 1709; break;
			case 17134: ver = 1803; break;
			case 17763: ver = 1809; break;
			default: ver = 1809; break;
			}
			return ver;
		}
	}
	return -1;
}

resource.h

#define IDC_LISTBOX1 2000

#define IDC_PROGBAR1 2010
#define IDC_LABEL1 2020

#define IDC_BUTTON_ALL_DEL 2030
#define IDC_BUTTON_DEL 2040


resource.rc

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


DLG1 DIALOG DISCARDABLE  0, 0, 380, 254
STYLE DS_MODALFRAME | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX
CAPTION "左右画像分割"
FONT 9, "MS Pゴシック"
BEGIN
	CONTROL "ListBox", IDC_LISTBOX1, "LISTBOX", WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_DISABLENOSCROLL , 7, 26, 366, 128
	LTEXT			"ここへファイルをドラッグドロップしてください",-1,7,7,222,10

	CONTROL "全削除", IDC_BUTTON_ALL_DEL, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 7, 154, 50, 14
	CONTROL "削除", IDC_BUTTON_DEL, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 70, 154, 50, 14

	CONTROL "", IDC_LABEL1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 7, 182, 366, 15
	CONTROL "", IDC_PROGBAR1, "MSCTLS_PROGRESS32", WS_CHILD | WS_VISIBLE | WS_BORDER, 7, 204, 366, 15

	DEFPUSHBUTTON	"OK(&O)",IDOK,115,233,50,14
	PUSHBUTTON	"キャンセル(&C)",IDCANCEL,225,233,50,14
END

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