山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他複数のjpgファイルを精密にトリムするプログラム
概要
ドラッグドロップされた複数のjpgファイルを一括でトリムします。
ファイルをドラッグドロップした後、リストボックスのファイル名をダブルクリックすると画像が表示されます。
トリムの範囲は、矩形選択で大まかに選択し左・上・右・下それぞれのアップダウンコントロールでピクセル単位でトリム範囲の修正ができます。
トリムは右側のスタティックコントロールに拡大されて表示されるので精密のトリムが可能となります。
複数ファイルのトリム範囲はすべて同一となります。
以下に画面の説明を記載します。
マニフェストでの高DPIの宣言は不要です。
ファイルをドラッグドロップした後、リストボックスのファイル名をダブルクリックすると画像が表示されます。
トリムの範囲は、矩形選択で大まかに選択し左・上・右・下それぞれのアップダウンコントロールでピクセル単位でトリム範囲の修正ができます。
トリムは右側のスタティックコントロールに拡大されて表示されるので精密のトリムが可能となります。
複数ファイルのトリム範囲はすべて同一となります。
以下に画面の説明を記載します。
- 全削除:リストボックスからファイル名を削除します。
- 削除:リストボックスから選択されているファイル名を削除します。
- 参照:トリムする前のファイルをバックアップするフォルダーをコモンダイアログで選択します。
- ソース:ドラッグドロップされたファイルのフォルダー名にoldを付加したバックアップフォルダー名を作成します。
- 矩形選択:矩形選択を開始します。画像上でマウスの左ボタンを押すと左上座標が選択されます。左ボタンを離すと右下座標が確定となります。
- 上・左・右・下:マージを指定します。
- 等倍・2倍・4倍:右に表示されるカーソル位置の拡大画面の倍率を変更します。単位はデバイスの解像度となります。
マニフェストでの高DPIの宣言は不要です。
テスト環境
コンパイラ
Visual C++ 2008/2013 Express 32/64bit UNICODE動作確認
Windows 7Windows 8.1
Windows 10 Version 1803
動作例
本プログラムを起動した状態
プログラムソースの概要
gjpgcut1.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により終了処理を実行します。
DlgProc
WM_INITDIALOG
ダイアログボックスの初期化時に呼び出されます。以下の処理はWindows 10 Version 1703以降では実行しません。
- ダイアログボックスの座標単位とスクリーン座標の変換に必要な定数をGetActualDialogBaseUnitsで取得
- scaleChange関数でダイアログボックス内の各コントロールの大きさ等を変更
UDM_SETBUDDYメッセージによりアップダウンコントロールとエディットボックスをリンクさせます。
WM_DROPFILES
ファイルがドラッグ&ドラッグされるとDlgProc関数にWM_DROPFILESメッセージが発生するので、DragQueryFile関数で最初にファイルの個数を取得し、次にファイル名を取得します。取得されたファイル名は、リストボックスに登録します。
WM_DPICHANGED
引数から現DPIを取得しscaleChange関数でダイアログボックス内の各コントロールの大きさ等を変更します。Windows 10 Version 1703以降では何もせずにWindowsに制御を渡します。WM_NCCREATE
Wndows10(Version1607)の時だけ非クライアント領域の処理するためEnableNonClientDpiScaling関数を呼び出します。WM_PAINT
再描画が必要な時に呼び出さセれます。基本的にはダイアログボックスの再描画はWindowsが自動的に行ってくれます。ここでは、ダイアログボックス真ん中のコントロールに表示している画像を描画しています。
メモリ上にjpgのイメージがロードされているときは、hdcBMPデバイスコンテキストが有効なのでコントロールのウィンドウハンドルを取得しこのコントロールの大きさで縦横比を変化させずに収まる最大サイズで描画します。矩形領域が選択されているときは描画のペンをXOR(2回描画する元に戻る)にして選択領域外を描画します。
WM_MOUSEMOVE
ダイアログボックス上のマウスカーソルが移動したときに呼び出されます。矩形領域が選択中の場合、変数captureがtureにセットされています。
引数lParamにダイアログボックスに対するクライアント座標が格納されていますので取り出して、ClientToScreenでスクリーン座標に変換後ScreenToClientでダイアログの真ん中のイメージを表示するコントロールに対するクライアント座標に変換します。
イメージは通常縮小されて表示されているのでwin2img_xy関数によりクライアント座標からイメージ上の座標に変換します。
変数sel_rect_flagがtrueの場合
すでに左上座標が選択され現在右下座標が移動中となります。描画のペンをXOR(旧領域を再描画し新領域を描画することにより移動したことになる)にして選択領域外を描画します。
zoom_win関数によりダイアログボックス右側にカーソル領域を中心として等倍または指定倍率でイメージを表示します。
変数ileft,itop,iright,ibotoomはイメージ上のトリムするピクセル数、変数wleft,wtop,wright,wbottomはコントロール上のトリムするピクセル数を表しています。
変数sel_rect_flagがfalseの場合
左上のトリム範囲をダイアログボックスに表示します。zoom_win関数によりダイアログボックス右側にカーソル領域を中心として等倍または指定倍率でイメージを表示します。
WM_LBUTTONDOWN
ダイアログボックス上でマウスの左ボタンが押された場合に呼び出されます。引数lParamにダイアログボックスに対するクライアント座標が格納されていますので取り出して、ClientToScreenでスクリーン座標に変換後ScreenToClientでダイアログの真ん中のイメージを表示するコントロールに対するクライアント座標に変換します。
win2img_xy関数により座標をチェックし有効な場合、変数sel_rect_flagをtrueにセットします。
このメッセージにより左上座標が選択されたことになります。
WM_LBUTTONUP
ダイアログボックス上でマウスの左ボタンが離された場合に呼び出されます。SetCursor APIによりカーソルの形状を矢印に戻します。
WM_VKEYTOITEM
リソースファイルでリストボックスのスタイルにLBS_WANTKEYBOARDINPUTを指定しているのでリストボックスのキー操作が親ウィンドウであるダイアログに通知されます。VK_DELETE
リストボックス上でDELETEキーが押されたときに呼び出されます。WM_COMMANDメッセージで削除ボタンが押された時のメッセージを送信します。
VK_UP
リストボックス上で上矢印キーが押されたときに呼び出されます。LB_GETCURSELメッセージでリストボックス上でアイテムが選択状態であることを確認して一番上でない場合はLB_SETCURSELメッセージで1個上のアイテムを指定し選択アイテムを1個上にします。
VK_DOWN
リストボックス上で下矢印キーが押されたときに呼び出されます。LB_GETCURSELメッセージでリストボックス上でアイテムが選択状態であることを確認して一番下でない場合はLB_SETCURSELメッセージで1個下のアイテムを指定し選択アイテムを1個下にします。
VK_HOME
リストボックス上でHOMEキーが押されたときに呼び出されます。LB_GETCURSELメッセージでリストボックス上でアイテムが選択状態であることを確認してLB_SETCURSELメッセージで一番上のアイテムを指定します。
WM_COMMAND
ボタンがクリックされると、WM_COMMANDメッセージが発生します。ICD_BUTTON_ZOOM1(等倍)
ICD_BUTTON_ZOOM2(2倍)
ICD_BUTTON_ZOOM4(4倍)
等倍,2倍,4倍ボタンがクリックされたときに呼び出されます。zoom_win関数によりダイアログボックスの右側の詳細ウィンドウに該当する倍率で表示します。
IDC_BUTTON_DEL(削除)
リストボックスで選択されているアイテムを削除します。LB_GETCURSELメッセージでリストボックス上でアイテムが選択状態であることを確認してLB_DELETESTRINGメッセージで削除します。削除すると1行ずれるので一番下のアイテムの場合は1個上を、一番下でない場合は現位置(削除後の新しいアイテム)のアイテムをLB_SETCURSELメッセージで選択し直します。
IDC_BUTTON_ALL_DEL(全削除)
リストボックスの全アイテムを削除します。LB_RESETCONTENTメッセージによりリストボックスのアイテムを全部削除します。
メモリ上にイメージがロードされている場合は解放します。
IDC_LISTBOX1
リストボックスのメッセージです。ダブルクリックの時発生するLBN_DBCLKメッセージを処理しています。ダブルクリックで選択されたアイテム番号をLB_GETCURSELで取得し、その番号のアイテムをLB_GETTEXTで取得します。
メモリ上にイメージがロードされている場合は解放してload_imgでイメージをロードします。
UDM_SERANGEメッセージによりアップダウンコントロールの範囲を0からイメージサイズまでに設定します。
UDM_SETPOSメッセージによりアップダウンコントロールの現在の値を0に設定します。
StrechBlt APIによりダイアログボックスの真ん中のスタティックコントロールに縦横比を維持した最大の大きさになるように拡大縮小して表示します。
IDC_BUTTON_RECT(矩形選択)
矩形選択ボタンがクリックされて時に呼び出されます。SetCaptureによりダイアログボックスにマウスキャプチャを設定します。
SetCursor APIによりカーソルを十字に変更します。
メモリにロードされたイメージを表示し、変数captureをtrueにします。
IDC_BUTTON_DIR(参照(B))
トリムする前にファイルをバックアップするフォルダーを取得するためにGetDir関数でコモンダイアログボックスを表示します。IDC_BUTTON_CDIR(ソース(S))
リストボックスの一番最初のアイテムをLB_GETTEXTメッセージで取得しGetFullPathNameによりフォルダー名のみ取り出しそのフォルダーの末尾にoldというフォルダー名を付加します。IDC_EDIT_LEFT,IDC_EDIT_TOP,IDC_EDIT_RIGHT,IDC_EDIT_BOTTOM
アップダウンコントロールのうち値が変更されたことを通知するEN_CHANGEメッセージのみ処理します。UDM_GETPOS32メッセージによりアップダウンコントロールの現在の値を取得し正常でない場合はメッセージの処理を行いません。
正常である場合は、ダイアログボックスの真ん中のコントロールの選択範囲と右側のコントロールの拡大されたイメージを変更します。
ID_OK(トリム(T))
トリムボタンをクリックした場合に呼び出されます。GetWindowText APIによりバックアップフォルダー名をエディットボックスから取得しCreateDirectory APIでそのフォルダーを作成します。
ファイル数をLB_GETCOUNTメッセージにより取得します。
プログレスバーの範囲をPBM_SETRANGEメッセージにより0からファイル数に設定します。
プログレスバーのステップ値をPBM_SETSTEPにより1にします。
全ファイルについて以下の処理をします。
- LB_GETTEXTメッセージによりファイル名を取得
- PathFindFileNameによりフォルダー名からファイル名のみの位置を取得
- バックアップフォルダー名をファイル名に結合してバックアップファイル名を作成
- MoveFile APIによりファイルのバックアップを取る。第1引数が元のファイルで第2引数が新しいファイルとなっており通常の_tcscpy等とは異なるので注意が必要。
- imgcut関数でイメージファイルをトリムする。
- PBM_STEPITでプログレスバーを1つ進める。
IDCANCEL(キャンセル(C))
メモリ上にイメージがロードされている場合は解放してから、EndDialog APIによりダイアログボックスを終了します。imgcut
jpgファイルより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で解放します。
load_img
jpgファイルよりGdiplus::Imageオブジェクトを作成します。Imageオブジェクトより画像ファイルの縦横サイズを取得し、ビットマップを作成します。(CreateDIBSection)
ウィンドウのデバイスコンテキストより互換性のあるメモリデバイスコンテキストを作成し(CreateCompatibleDC)、ビットマップを関連付けます。(SelectObject)
メモリデバイスコンテキストよりGdiplus::Graphicsオブジェクトを作成し、Gdiplus::ImageをGdiplus::Graphicsに描画(DrawImage)します。
Gdiplus::ImageとGdiplus::Graphics(デストラクタにより自動解放される)オブジェクトを解放します。
scaleChange
現在のフォントを取得しスケールに応じたフォントを新規に作成し設定します。スケールからダイアログボックスの大きさを計算し、AdjustWindowRectによりクライアントサイズから必要なウィンドウサイズを計算しSetWindowPosによりダイアログボックスの大きさを変更します。
各コントロールウィンドウをEnumChildWindowsで列挙します。
EnumWndProc
EnumChildWindowsから呼び出されるEnumWndProc関数によりスケールに応じた位置、サイズ、文字サイズを設定します。スケールからコントロールの大きさを計算し、AdjustWindowRectによりクライアントサイズから必要なウィンドウサイズを計算しSetWindowPosによりダイアログボックスの大きさを変更します。
コントロールのフォントをWM_SETTEXTメッセージにより変更します。
GetActualDialogBaseUnits
ダイアログボックス座標の計算に必要な単位を取得します。YogaPro3では横が13、縦が31ピクセルが取得されました。
win10ver2
Windows 10のバージョンを取得する関数です。詳細は、Windows 10のバージョン番号をRtlGetVersionのビルド番号から取得するを参照してください。
ソースコード
gjpgcut1.cpp
// Jpegファイルを精密にトリムする
// 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;
bool capture = false; // trueの時、キャプチャー中
bool sel_rect_flag = false; // 矩形領域を選択中
bool capture_back = false;
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
int GetDir(HWND hWnd,TCHAR* path,TCHAR* root); // フォルダー名を取得するコモンコントロール
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid); // エンコーダーの取得
// jpegファイルをメモリデバイスコンテキストにロードする
bool load_img(TCHAR* fname, HDC* hdcBMP, HDC hdc, int* ix, int* iy);
// imageをdx,dyにジャストフィットする画像サイズ(縦横比維持)を*sx,*syに作成する
void image_just_size(int* sx, int* sy, int px, int py, int dx, int dy);
struct DLG_CHILD_SCALE{
HWND hDlg;
SIZE unit;
UINT oldScale;
UINT newScale;
HFONT hFont;
};
// DPIスケールの変更
HFONT scaleChange(HWND hDlg, int nowScale, int oldScale, SIZE& baseUnit, HFONT hFont);
// 各ウィンドウ(コントロールの移動及び大きさの変更
BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam);
// ダイアログ単位をピクセルに変換
BOOL GetActualDialogBaseUnits(HWND hDialog, SIZE *baseUnit);
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;
}
// クライアント座標(x,y)をイメージの座標(*px,*py)に変換
bool win2img_xy(int* px,int* py,int x, int y, int ix, int iy, int sx, int sy){
if (x < 0 || sx < x)
return false;
if (y < 0 || sy < y)
return false;
*px = x*ix / sx;
*py = y*iy / sy;
return true;
}
// イメージの座標(x,y)をクライアント座標(*wx,*wy)に変換
bool img2win_xy(int* wx,int* wy,int x, int y, int ix, int iy, int sx, int sy){
if (x < 0 || ix < x)
return false;
if (y < 0 || iy < y)
return false;
*wx=sx*x/ix;
*wy=sy*y/iy;
return true;
}
HWND hWnd;
BITMAPINFOHEADER bmih;
BYTE *pBits;
HBITMAP hBitmap, HOldBitmap;
int imgcut(TCHAR* dtc, TCHAR* src, int sx, int sy,int width,int height){
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(width, height); // 保存用
bmp->SetResolution(px_res, py_res);
Graphics* MyGraphics = Graphics::FromImage(bmp);
MyGraphics->DrawImage(srcImage, 0,0,sx,sy,width,height,UnitPixel);
srcImage->~Image();
#ifdef UNICODE
bmp->Save(dtc, &encoderClsid);
#else
WCHAR dtcFile[MAX_PATH];
MultiByteToWideChar(932,0,dtc,-1,dtcFile,sizeof(dtcFile)/sizeof(WCHAR));
bmp->Save(dtcFile, &encoderClsid);
#endif
delete bmp;
delete MyGraphics;
return 0;
}
// ズームウィンドウに表示 中心座標(ImageX,imageY) zoom_v:表示倍率
void zoom_win(HWND hWnd,HDC hdcBMP,int imageX,int imageY,int zoom_v,int cur_type){
RECT rc;
HDC zhdc = GetDC(hWnd);
GetWindowRect(hWnd,&rc);
int dx = rc.right - rc.left;
int dy = rc.bottom - rc.top;
SetStretchBltMode(zhdc, HALFTONE);
StretchBlt(zhdc, 0, 0, dx, dy, hdcBMP, imageX-dx/zoom_v/2, imageY-dy/zoom_v/2, dx/zoom_v, dy/zoom_v, SRCCOPY);
HPEN zhPen, zhOldPen;
HBRUSH zhBrush, zhOldBrush;
SetROP2(zhdc, R2_XORPEN);
zhPen = (HPEN)GetStockObject(NULL_PEN);
zhOldPen = (HPEN)SelectObject(zhdc, zhPen);
zhBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
zhOldBrush = (HBRUSH)SelectObject(zhdc, zhBrush);
POINT po[6];
switch(cur_type){
case 0:// 左上
po[0].x = 0; po[0].y = 0;
po[1].x = dx; po[1].y = 0;
po[2].x = dx; po[2].y = dy/2;
po[3].x = dx/2; po[3].y = dy/2;
po[4].x = dx/2; po[4].y = dy;
po[5].x = 0; po[5].y = dy;
Polygon(zhdc, po, 6);
break;
case 1:// 右下
po[0].x = 0; po[0].y = dy / 2;
po[1].x = dx / 2; po[1].y=dy / 2;
po[2].x = dx / 2; po[2].y = 0;
po[3].x = dx; po[3].y = 0;
po[4].x = dx; po[4].y = dy;
po[5].x = 0; po[5].y = dy;
Polygon(zhdc, po, 6);
break;
case IDC_EDIT_LEFT:// 左
Rectangle(zhdc, 0, 0, dx/2, dy);
break;
case IDC_EDIT_TOP:// 上
Rectangle(zhdc, 0, 0, dx, dy/2);
break;
case IDC_EDIT_RIGHT:// 右
Rectangle(zhdc, dx/2, 0, dx, dy);
break;
case IDC_EDIT_BOTTOM:// 下
Rectangle(zhdc, 0, dy/2, dx, dy);
break;
}
ReleaseDC(hWnd, zhdc);
DeleteObject(zhBrush);
}
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
TCHAR buf[MAX_PATH];
TCHAR dtc_dir[MAX_PATH];
TCHAR src_file[MAX_PATH*2];
TCHAR dtc_file[MAX_PATH*2];
TCHAR* p;
HDROP hDrop;
UINT fmax;
int i,num;
HDC hdc;
static Image* imageP = 0;
static int ix, iy; // ipgのサイズ
static int sx, sy; // ウィンドウに表示しているサイズ
static int ileft, itop, iright, ibottom;
static POINT pt;
static HDC hdcBMP;
static RECT rc;
static int imageX, imageY;
static int wtop,wbottom,wleft,wright;// トリムするクライアント座標
static int zoom_v=1;
static int zoom_cur=-1;
HPEN hPen, hOldPen;
HBRUSH hBrush;
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"));
}
SetWindowText(GetDlgItem(hDlg, IDC_EDIT_DIR), _TEXT("C:¥¥"));
SendMessage(GetDlgItem(hDlg, IDC_SPIN_LEFT), UDM_SETBUDDY, (WPARAM)GetDlgItem(hDlg, IDC_EDIT_LEFT), 0);
SendMessage(GetDlgItem(hDlg, IDC_SPIN_RIGHT), UDM_SETBUDDY, (WPARAM)GetDlgItem(hDlg, IDC_EDIT_RIGHT), 0);
SendMessage(GetDlgItem(hDlg, IDC_SPIN_TOP), UDM_SETBUDDY, (WPARAM)GetDlgItem(hDlg, IDC_EDIT_TOP), 0);
SendMessage(GetDlgItem(hDlg, IDC_SPIN_BOTTOM), UDM_SETBUDDY, (WPARAM)GetDlgItem(hDlg, IDC_EDIT_BOTTOM), 0);
EnableWindow(GetDlgItem(hDlg,IDC_BUTTON_RECT), FALSE);
def_dir[0] = _T('¥0');
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_PAINT:{
PAINTSTRUCT ps;
if (hdcBMP){
HWND hWnd;
hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
image_just_size(&sx, &sy, ix, iy, (rect.right - rect.left), (rect.bottom - rect.top));
SetStretchBltMode(hdc, HALFTONE);
StretchBlt(hdc, 0, 0, sx, sy, hdcBMP, 0, 0, ix, iy, SRCCOPY);
HBRUSH hBrush, hOldBrush;
SetROP2(hdc, R2_XORPEN);
hPen = (HPEN)GetStockObject(NULL_PEN);
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
img2win_xy(&wleft, &wtop, ileft, itop, ix, iy, sx, sy);
img2win_xy(&wright, &wbottom, iright, ibottom, ix, iy, sx, sy);
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
SelectObject(hdc, hOldBrush);
DeleteObject(hBrush);
EndPaint(hWnd, &ps);
}
return FALSE;
}
case WM_MOUSEMOVE:
if (capture == true) {
POINTS pos;
pos = MAKEPOINTS(lParam);
pt.x = pos.x;
pt.y = pos.y;
ClientToScreen(hDlg, &pt);
HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
ScreenToClient(hWnd, &pt);
if (win2img_xy(&imageX, &imageY, pt.x, pt.y, ix, iy, sx, sy) == true){
if (sel_rect_flag == true){
HDC hdc = GetDC(hWnd);
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
SetROP2(hdc, R2_XORPEN);
hPen = (HPEN)GetStockObject(NULL_PEN);
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
if (capture_back == true){
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
}
wright = pt.x;
wbottom = pt.y;
iright=imageX;
ibottom=imageY;
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur=1);
DeleteObject(hBrush);
capture_back = true;
ReleaseDC(hWnd, hdc);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("%0.4d"), ix-imageX);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT_RIGHT), buf);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("%0.4d"), iy-imageY);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT_BOTTOM), buf);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("サイズ %0.4d*%0.4d"), imageX-ileft, imageY-itop);
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), buf);
}else{
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur=0);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("%0.4d"), imageX);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT_LEFT), buf);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("%0.4d"), imageY);
SetWindowText(GetDlgItem(hDlg, IDC_EDIT_TOP), buf);
}
}
}
break;
case WM_LBUTTONUP:
if (capture == true) {
capture = false;
sel_rect_flag = false;
SetCursor(LoadCursor(NULL, IDC_ARROW));
ReleaseCapture();
}
break;
case WM_LBUTTONDOWN:
if (capture == true) {
POINTS pos;
pos = MAKEPOINTS(lParam);
pt.x = pos.x;
pt.y = pos.y;
ClientToScreen(hDlg, &pt);
HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
ScreenToClient(hWnd, &pt);
if (win2img_xy(&imageX, &imageY, pt.x, pt.y, ix, iy, sx, sy) == true){
sel_rect_flag = true;
capture_back = false;
wleft = pt.x;
wtop = pt.y;
ileft =imageX;
itop = imageY;
}
}
break;
case WM_VKEYTOITEM:
switch (LOWORD(wParam)){
case VK_DELETE:
SendMessage(hDlg, WM_COMMAND, IDC_BUTTON_DEL, 0);
return -2;
case VK_UP:
num = (int)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCURSEL, NULL, NULL);
if (num == LB_ERR)
break;
if (0 < num){
--num;
SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_SETCURSEL, (WPARAM)num, 0L);
}
return -2;
case VK_DOWN:
num = (int)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCURSEL, NULL, NULL);
if (num == LB_ERR)
break;
fmax = (UINT)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCOUNT, 0, 0);
if ((UINT)num < fmax - 1){
++num;
SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_SETCURSEL, (WPARAM)num, 0L);
}
return -2;
case VK_HOME:
num = (int)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCURSEL, NULL, NULL);
if (num == LB_ERR)
break;
SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_SETCURSEL, (WPARAM)0, 0L);
return -2;
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
#ifdef _DEBUG
case IDC_BUTTON_DEBUG_ZOOM12:
SendMessage(hDlg, WM_DPICHANGED, MAKELONG(192,192), 0);
break;
case IDC_BUTTON_DEBUG_ZOOM23:
SendMessage(hDlg, WM_DPICHANGED, MAKELONG(288, 288), 0);
break;
case IDC_BUTTON_DEBUG_ZOOM21:
SendMessage(hDlg, WM_DPICHANGED, MAKELONG(96, 96), 0);
break;
#endif
case IDC_BUTTON_ZOOM1:
zoom_v=1;
if(zoom_cur!=-1)
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur);
break;
case IDC_BUTTON_ZOOM2:
zoom_v=2;
if(zoom_cur!=-1)
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur);
break;
case IDC_BUTTON_ZOOM4:
zoom_v=4;
if(zoom_cur!=-1)
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur);
break;
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:{
EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_RECT), FALSE);
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);
if (hdcBMP){
SelectObject(hdcBMP, HOldBitmap);
DeleteObject(hBitmap);
DeleteDC(hdcBMP);
hdcBMP = 0;
}
break;
}
case IDC_LISTBOX1:
if (HIWORD(wParam) == LBN_DBLCLK){ //リストボックスのアイテム上でダブルクリックをした場合
int num = (int)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCURSEL, NULL, NULL);
if(num==LB_ERR)
break;
HWND hWnd;
SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETTEXT, num, (WPARAM)buf);
hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
hdc = GetDC(hWnd);
if (hdcBMP){
SelectObject(hdcBMP, HOldBitmap);
DeleteObject(hBitmap);
DeleteDC(hdcBMP);
}
if (load_img(buf, &hdcBMP, hdc, &ix, &iy) == false){
break;
}
SendMessage(GetDlgItem(hDlg, IDC_SPIN_LEFT), UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG(ix,0));
SendMessage(GetDlgItem(hDlg, IDC_SPIN_RIGHT), UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG(ix,0));
SendMessage(GetDlgItem(hDlg, IDC_SPIN_TOP), UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG(iy,0));
SendMessage(GetDlgItem(hDlg, IDC_SPIN_BOTTOM), UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG(iy,0));
int zero=0;
SendMessage(GetDlgItem(hDlg, IDC_SPIN_LEFT), UDM_SETPOS, 0, (LPARAM)zero);
SendMessage(GetDlgItem(hDlg, IDC_SPIN_RIGHT), UDM_SETPOS, 0, (LPARAM)zero);
SendMessage(GetDlgItem(hDlg, IDC_SPIN_TOP), UDM_SETPOS, 0, (LPARAM)zero);
SendMessage(GetDlgItem(hDlg, IDC_SPIN_BOTTOM), UDM_SETPOS, 0, (LPARAM)zero);
hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
HDC hdc = GetDC(hWnd);
hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
RECT rect;
GetClientRect(hWnd, &rect);
image_just_size(&sx, &sy, ix, iy, (rect.right - rect.left), (rect.bottom - rect.top));
SetStretchBltMode(hdc, HALFTONE);
StretchBlt(hdc, 0, 0, sx, sy, hdcBMP, 0, 0, ix, iy, SRCCOPY);
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
ReleaseDC(hWnd, hdc);
EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_RECT), TRUE);
}
break;
case IDC_BUTTON_RECT:
SetCapture(hDlg);
SetCursor(LoadCursor(NULL, IDC_CROSS));
if (hdcBMP){
hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
HDC hdc = GetDC(hWnd);
hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
RECT rect;
GetClientRect(hWnd, &rect);
image_just_size(&sx, &sy, ix, iy, (rect.right - rect.left), (rect.bottom - rect.top));
SetStretchBltMode(hdc, HALFTONE);
StretchBlt(hdc, 0, 0, sx, sy, hdcBMP, 0, 0, ix, iy, SRCCOPY);
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
ReleaseDC(hWnd, hdc);
capture = true;
}
break;
case IDC_BUTTON_DIR:
if (def_dir[0] == _T('¥0'))
_tcscpy_s(def_dir,sizeof(def_dir)/sizeof(TCHAR),_TEXT("C:¥¥"));
GetDir(hDlg,buf,0);
SetWindowText(GetDlgItem(hDlg,IDC_EDIT_DIR) , buf);
return TRUE;
case IDC_BUTTON_CDIR:
fmax=(UINT)SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETCOUNT,0,0);
if(fmax){
SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETTEXT,0,(LPARAM)src_file);
TCHAR FullPath[MAX_PATH];
TCHAR* FilePart;
DWORD sz;
sz=GetFullPathName(src_file,sizeof(FullPath)/sizeof(TCHAR),FullPath,&FilePart);
if(0<sz){
*FilePart=_T('¥0');
_tcscat_s(FullPath,sizeof(FullPath)/sizeof(TCHAR),_TEXT("old"));
SetWindowText(GetDlgItem(hDlg,IDC_EDIT_DIR) , FullPath);
}
}
return TRUE;
case IDC_EDIT_LEFT:
if (HIWORD(wParam) == EN_CHANGE && capture == false) {
int err;
int num = (int)SendMessage(GetDlgItem(hDlg, IDC_SPIN_LEFT), UDM_GETPOS32, 0, (LPARAM)&err);
if (err == 0){ // エディットボックスの値が正常な範囲
HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
int wx,wy;
img2win_xy(&wx,&wy,num,iy/2,ix,iy,sx,sy);
HDC hdc = GetDC(hWnd);
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
SetROP2(hdc, R2_XORPEN);
hPen = (HPEN)GetStockObject(NULL_PEN);
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
if (capture_back == true){
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
}
wleft=wx;
imageX=num;
imageY=iy/2;
ileft=imageX;
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur=IDC_EDIT_LEFT);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("サイズ %0.4d*%0.4d"), iright-ileft, ibottom-itop);
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), buf);
DeleteObject(hBrush);
capture_back = true;
ReleaseDC(hWnd, hdc);
}else{ // エディットボックスの値が正常でない場合
Beep(1000, 200);
}
return TRUE;
}
break;
case IDC_EDIT_TOP:
if (HIWORD(wParam) == EN_UPDATE && capture == false) {
int err;
int num = (int)SendMessage(GetDlgItem(hDlg,IDC_SPIN_TOP), UDM_GETPOS32, 0, (LPARAM)&err);
if (err == 0){ // エディットボックスの値が正常な範囲
HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
int wx,wy;
img2win_xy(&wx,&wy,ix/2,num,ix,iy,sx,sy);
HDC hdc = GetDC(hWnd);
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
SetROP2(hdc, R2_XORPEN);
hPen = (HPEN)GetStockObject(NULL_PEN);
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
if (capture_back == true){
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
}
wtop=wy;
imageX=ix/2;
imageY=num;
itop=imageY;
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur=IDC_EDIT_TOP);
DeleteObject(hBrush);
capture_back = true;
ReleaseDC(hWnd, hdc);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("サイズ %0.4d*%0.4d"), iright-ileft, ibottom-itop);
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), buf);
}else{ // エディットボックスの値が正常でない場合
Beep(1000, 200);
}
return TRUE;
}
break;
case IDC_EDIT_RIGHT:
if (HIWORD(wParam) == EN_UPDATE && capture == false) {
int err;
int num = (int)SendMessage(GetDlgItem(hDlg,IDC_SPIN_RIGHT), UDM_GETPOS32, 0, (LPARAM)&err);
num=ix-num;
if (err == 0){ // エディットボックスの値が正常な範囲
HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
int wx,wy;
img2win_xy(&wx,&wy,num,iy/2,ix,iy,sx,sy);
HDC hdc = GetDC(hWnd);
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
SetROP2(hdc, R2_XORPEN);
hPen = (HPEN)GetStockObject(NULL_PEN);
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
if (capture_back == true){
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
}
wright=wx;
imageX=num;
imageY=iy/2;
iright=imageX;
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur=IDC_EDIT_RIGHT);
DeleteObject(hBrush);
capture_back = true;
ReleaseDC(hWnd, hdc);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("サイズ %0.4d*%0.4d"), iright-ileft,ibottom-itop);
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), buf);
}else{ // エディットボックスの値が正常でない場合
Beep(1000, 200);
}
return TRUE;
}
break;
case IDC_EDIT_BOTTOM:
if (HIWORD(wParam) == EN_UPDATE && capture == false) {
int err;
int num = (int)SendMessage(GetDlgItem(hDlg,IDC_SPIN_BOTTOM), UDM_GETPOS32, 0, (LPARAM)&err);
num=iy-num;
if (err == 0){ // エディットボックスの値が正常な範囲
HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_MAIN_IMAGE);
int wx,wy;
img2win_xy(&wx,&wy,ix/2,num,ix,iy,sx,sy);
HDC hdc = GetDC(hWnd);
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
SetROP2(hdc, R2_XORPEN);
hPen = (HPEN)GetStockObject(NULL_PEN);
hOldPen = (HPEN)SelectObject(hdc, hPen);
hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
if (capture_back == true){
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
}
wbottom=wy;
imageX=ix/2;
imageY=num;
ibottom=imageY;
Rectangle(hdc, 0, 0, sx, wtop);
Rectangle(hdc, 0, wtop - 1, wleft, wbottom + 1);
Rectangle(hdc, 0, wbottom, sx, sy);
Rectangle(hdc, wright, wtop - 1, sx, wbottom + 1);
zoom_win(GetDlgItem(hDlg, IDC_STATIC_ZOOM_IMAGE),hdcBMP,imageX,imageY,zoom_v,zoom_cur=IDC_EDIT_BOTTOM);
DeleteObject(hBrush);
capture_back = true;
ReleaseDC(hWnd, hdc);
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("サイズ %0.4d*%0.4d"), iright-ileft, ibottom-itop);
SetWindowText(GetDlgItem(hDlg, IDC_STATIC_TEXT), buf);
}else{ // エディットボックスの値が正常でない場合
Beep(1000, 200);
}
return TRUE;
}
break;
case IDOK:{
GetWindowText(GetDlgItem(hDlg,IDC_EDIT_DIR),dtc_dir,sizeof(dtc_dir)/sizeof(TCHAR));
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);
int width=iright-ileft;
int height=ibottom-itop;
CreateDirectory(dtc_dir,NULL);
for(i = 0; i < (int)fmax; i++){
SendMessage(GetDlgItem(hDlg,IDC_LISTBOX1) ,LB_GETTEXT,i,(LPARAM)src_file);
p=PathFindFileName(src_file);
_stprintf_s(dtc_file,sizeof(dtc_file)/sizeof(TCHAR),_TEXT("%s¥¥%s"),dtc_dir,p);
MoveFile(src_file,dtc_file);
imgcut(src_file, dtc_file,ileft,itop,width,height);
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:
if (hdcBMP){
SelectObject(hdcBMP, HOldBitmap);
DeleteObject(hBitmap);
DeleteDC(hdcBMP);
}
EndDialog(hDlg, FALSE);
return FALSE;
default:
return FALSE;
}
default:
return FALSE;
}
return TRUE;
}
// ディレクトリ名を取得するコモンダイアログを表示する
int __stdcall BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
int GetDir(HWND hWnd,TCHAR* path,TCHAR* root){
BROWSEINFO bInfo;
LPITEMIDLIST pIDList;
bInfo.hwndOwner = hWnd; // ダイアログの親ウインドウのハンドル
bInfo.pidlRoot =NULL; // ルートフォルダをデスクトップフォルダとする
bInfo.pszDisplayName =path; //szDisplayName; // フォルダ名を受け取るバッファへのポインタ
bInfo.lpszTitle =TEXT("保存するフォルダの選択"); // ツリービューの上部に表示される文字列
bInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE ; // 表示されるフォルダの種類を示すフラグ
bInfo.lpfn = BrowseCallbackProc; // BrowseCallbackProc関数のポインタ
bInfo.lParam = NULL;
pIDList = SHBrowseForFolder(&bInfo);
if(pIDList == NULL){
path[0]=_TEXT('¥0');
return FALSE; //何も選択されなかった場合
}else{
if(!SHGetPathFromIDList(pIDList, path))
return FALSE;//変換に失敗
CoTaskMemFree( pIDList );// pIDListのメモリを開放
return TRUE;
}
}
// 上記ダイアログのコールバック関数
int __stdcall BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData){
if(uMsg==BFFM_INITIALIZED){
SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,(LPARAM)def_dir ); // コモンダイアログの初期ディレクトリ
}
return 0;
}
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;
}
// jpegファイルをメモリデバイスコンテキストにロードする
bool load_img(TCHAR* fname, HDC* hdcBMP, HDC hdc, int* ix, int* iy){
Image* imageP;
#ifndef UNICODE
WCHAR wTitle[MAX_PATH];
MultiByteToWideChar(932, 0, szFile, -1, wTitle, sizeof(wTitle) / sizeof(TCHAR));
imageP = Bitmap::FromFile(wTitle);
#else
imageP = Bitmap::FromFile(fname);
#endif
if (imageP == 0){
*ix = 0;
*iy = 0;
*hdcBMP = 0;
return false;
}
bmih.biSize = sizeof(bmih);
bmih.biWidth = *ix = imageP->GetWidth();
bmih.biHeight = *iy = imageP->GetHeight();
bmih.biPlanes = 1;
bmih.biBitCount = 32;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, 0, (void**)&pBits, NULL, 0);
if (pBits == NULL){
MessageBox(hWnd, _TEXT("メモリが不足しています。"), _TEXT("Message"), MB_YESNO | MB_ICONQUESTION);
DeleteObject(hBitmap);
delete imageP;
*ix = 0;
*iy = 0;
return false;
}
*hdcBMP = CreateCompatibleDC(hdc);
HOldBitmap = (HBITMAP)SelectObject(*hdcBMP, hBitmap);
Graphics MyGraphics(*hdcBMP);
MyGraphics.DrawImage(imageP, 0, 0, imageP->GetWidth(), imageP->GetHeight());
delete imageP;
return true;
}
// imageをdx,dyにジャストフィットする画像サイズ(縦横比維持)を*sx,*syに作成する
void image_just_size(int* sx, int* sy, int px, int py, int dx, int dy){
double pxy = double(px) / double(py); // オリジナル横/縦
double dxy = double(dx) / double(dy); // 変換後横/縦
int dx2, dy2;
if (pxy>dxy){ // オリジナルが横が長いので横基準に縦を縮小する
dx2 = dx;
dy2 = (int)double(dx / pxy);
}
else{
dy2 = dy;
dx2 = (int)double(dy*pxy);
}
*sx = dx2;
*sy = dy2;
}
// 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;
}
// 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;
}
// 各ウィンドウ(コントロールの移動及び大きさの変更
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;
}
// ダイアログ単位をピクセルに変換
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;
}
resource.h
#define IDC_LISTBOX1 2001
#define IDC_EDIT_DIR 2002
#define IDC_BUTTON_DIR 2003
#define IDC_BUTTON_CDIR 2012
#define IDC_PROGBAR1 2010
#define IDC_LABEL1 2011
#define IDC_EDIT_TOP 2020
#define IDC_EDIT_LEFT 2021
#define IDC_EDIT_RIGHT 2022
#define IDC_EDIT_BOTTOM 2023
#define IDC_SPIN_TOP 2040
#define IDC_SPIN_LEFT 2041
#define IDC_SPIN_RIGHT 2042
#define IDC_SPIN_BOTTOM 2043
#define IDC_STATIC_MAIN_IMAGE 2030
#define IDC_STATIC_ZOOM_IMAGE 2031
#define IDC_BUTTON_RECT 2032
#define IDC_BUTTON_ALL_DEL 2035
#define IDC_BUTTON_DEL 2036
#define IDC_STATIC_TEXT 2034
#define IDC_BUTTON_ZOOM1 2060
#define IDC_BUTTON_ZOOM2 2061
#define IDC_BUTTON_ZOOM4 2062
#ifdef _DEBUG
#define IDC_BUTTON_DEBUG_ZOOM12 2200
#define IDC_BUTTON_DEBUG_ZOOM23 2205
#define IDC_BUTTON_DEBUG_ZOOM21 2210
#endif
resource.rc
#include <windows.h>
#include "resource.h"
DLG1 DIALOG DISCARDABLE 0, 0, 454, 267
STYLE DS_MODALFRAME | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX
CAPTION "精密画像トリム"
FONT 9, "MS Shell Dlg"
BEGIN
CONTROL "ListBox", IDC_LISTBOX1, "LISTBOX", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | LBS_NOTIFY | LBS_WANTKEYBOARDINPUT, 7, 26, 166, 128
LTEXT "ここへファイルをドラッグドロップしてください",-1,7,7,222,10
CONTROL "上", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 180, 9, 10, 12
CONTROL "", IDC_EDIT_TOP, "EDIT", WS_TABSTOP | WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER, 190, 7, 32, 12
CONTROL "Spin1", IDC_SPIN_TOP, "msctls_updown32", UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, 222, 7, 10, 12
CONTROL "", IDC_STATIC_TEXT, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 180, 133, 100, 12
CONTROL "左", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 232, 9, 10, 12
CONTROL "", IDC_EDIT_LEFT, "EDIT", WS_TABSTOP | WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER, 242, 7, 32, 12
CONTROL "Spin1", IDC_SPIN_LEFT, "msctls_updown32", UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, 274, 7, 10, 11
CONTROL "", IDC_STATIC_MAIN_IMAGE, "STATIC", WS_CHILD | WS_VISIBLE | SS_SUNKEN | SS_NOTIFY, 180, 26, 160, 100
CONTROL "右", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 284, 9, 10, 12
CONTROL "", IDC_EDIT_RIGHT, "EDIT", WS_TABSTOP | WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER, 294, 7, 32, 12
CONTROL "Spin1", IDC_SPIN_RIGHT, "msctls_updown32", UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, 326, 7, 10, 12
CONTROL "下", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 336, 9, 10, 7
CONTROL "", IDC_EDIT_BOTTOM, "EDIT", WS_TABSTOP | WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER, 346, 7, 32, 12
CONTROL "Spin1", IDC_SPIN_BOTTOM, "msctls_updown32", UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS, 378, 7, 10, 12
CONTROL "等倍", IDC_BUTTON_ZOOM1, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 347, 133, 34, 14
CONTROL "2倍", IDC_BUTTON_ZOOM2, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 381, 133, 33, 14
CONTROL "4倍", IDC_BUTTON_ZOOM4, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 415, 133, 34, 14
#ifdef _DEBUG
CONTROL "1→2倍", IDC_BUTTON_DEBUG_ZOOM12, "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 347, 175, 33, 14
CONTROL "2→3倍", IDC_BUTTON_DEBUG_ZOOM23, "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 381, 175, 33, 14
CONTROL "2→1倍", IDC_BUTTON_DEBUG_ZOOM21, "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 415, 175, 34, 14
#endif
CONTROL "", IDC_STATIC_ZOOM_IMAGE, "STATIC", WS_CHILD | WS_VISIBLE | SS_SUNKEN | SS_NOTIFY, 347, 26, 100, 100
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_BUTTON_RECT, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 281, 133, 50, 14
CONTROL "バックアップ", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 7, 175, 64, 12
CONTROL "参照(&B)", IDC_BUTTON_DIR, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 70, 175, 50, 14
CONTROL "ソース(&S)", IDC_BUTTON_CDIR, "BUTTON", WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 127, 175, 50, 14
CONTROL "", IDC_EDIT_DIR, "EDIT", WS_TABSTOP | WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL, 14, 189, 433, 12
CONTROL "", IDC_LABEL1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 7, 208, 440, 12
CONTROL "", IDC_PROGBAR1, "MSCTLS_PROGRESS32", WS_CHILD | WS_VISIBLE | WS_BORDER, 7, 220, 440, 12
DEFPUSHBUTTON "トリム(&T)",IDOK,115,246,50,14
PUSHBUTTON "キャンセル(&C)",IDCANCEL,225,246,50,14
END
Copyright (C) 2012 山本ワールド All Rights Reserved.