Drag and Dropに対応させる
上記前記事で紹介したプログラムをD&D対応にします。既にフォームは提示済みなので、Unit1.hとUnit1.cppを提示します。他にexif.cppとかexif.hが必要です。(自分で修正を加える必要があります。)
/---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include <FMX.Controls.Presentation.hpp>
#include <FMX.Dialogs.hpp>
#include <FMX.Memo.hpp>
#include <FMX.Memo.Types.hpp>
#include <FMX.ScrollBox.hpp>
#include <FMX.StdCtrls.hpp>
#include <FMX.Types.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE で管理されるコンポーネント
TOpenDialog *OpenDialog1;
TButton *Open;
TMemo *Memo1;
TLabel *Label1;
TCheckBox *NoDumpTables;
TCheckBox *FixDateTime;
TCheckBox *SnifGPSInfo;
void __fastcall OpenClick(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
virtual void __fastcall DragDrop(const Fmx::Types::TDragObject &Data, const System::Types::TPointF &Point);
virtual void __fastcall DragOver(const Fmx::Types::TDragObject &Data, const System::Types::TPointF &Point, Fmx::Types::TDragOperation &Operation);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif//---------------------------------------------------------------------------
#include <fmx.h>
#pragma hdrstop
#include <filesystem>
#include "exif.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
namespace fs = std::filesystem;
extern AnsiString getdatetime(void *array);
AnsiString datetime;
void PRINTF(char **ms, const char *fmt, ...) {
AnsiString output;
char buf[4096];
char *p = NULL;
int len, cnt;
va_list args;
va_start(args, fmt);
cnt = vsnprintf(buf, sizeof(buf)-1, fmt, args);
if (!ms) {
output.sprintf("%s\n", buf);
//Form1->Memo1->Lines->Add(output);
if( !(Form1->NoDumpTables->IsChecked) ){
Form1->Memo1->Lines->Text += output;
Form1->Memo1->Lines->Text += L"\n";
}
return;
}
else if (*ms) {
len = (int)(strlen(*ms) + cnt + 1);
p = (char*)malloc(len);
strcpy(p, *ms);
strcat(p, buf);
free(*ms);
} else {
len = cnt + 1;
p = (char*)malloc(len);
strcpy(p, buf);
}
*ms = p;
va_end(args);
}
int sample_removeGPSData(const char *srcJpgFileName,const char *outJpgFileName)
{
int sts, result;
void **ifdTableArray = createIfdTableArray(srcJpgFileName, &result);
if (!ifdTableArray) {
printf("createIfdTableArray: ret=%d\n", result);
return result;
}
// remove GPS IFD and 1st IFD if exist
removeIfdTableFromIfdTableArray(ifdTableArray, IFD_GPS);
removeIfdTableFromIfdTableArray(ifdTableArray, IFD_1ST);
sts = updateExifSegmentInJPEGFile(srcJpgFileName, outJpgFileName, ifdTableArray);
if (sts < 0) {
printf("updateExifSegmentInJPEGFile: ret=%d\n", sts);
}
freeIfdTableArray(ifdTableArray);
return sts;
}
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
bool SetFileCreationTime(String filePath, TDateTime dt) {
// Convert SYSTEMTIME to FILETIME
SYSTEMTIME newTime;
DateTimeToSystemTime(dt,newTime);
FILETIME ft;
if (!SystemTimeToFileTime(&newTime, &ft)) {
return false;
}
// Open file with write attributes permission
HANDLE hFile = CreateFileW(
filePath.w_str(),
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE) {
return false;
}
// Set creation time (leave last access and write times unchanged)
BOOL result = SetFileTime(hFile, &ft, NULL, NULL);
CloseHandle(hFile);
return (result != 0);
}
void Parse_File(String path)
{
String prefix = "nogps_";
String fullpath;
String filename;
String filepath;
String newname;
Form1->Memo1->Lines->Add(path);
fullpath = path;
//Memo1->Lines->Add("fullpath " + fullpath);
void **ifdArray;
TagNodeInfo *tag;
int i, result;
ifdArray = createIfdTableArray(AnsiString(fullpath).c_str(),&result);
for( i = 0 ; ifdArray[i] != NULL ; i++ ){
dumpIfdTable(ifdArray[i]);
}
//mpIfdTable(ifdArray[0]);
if( Form1->FixDateTime->IsChecked ){
//Form1->Memo1->Lines->Add("datetime is " + datetime);
TDateTime dt;
TFormatSettings fs;
fs = TFormatSettings::Create(); // Initialize with defaults
//fs.DateSeparator = ':';
fs.ShortDateFormat = "yyyy:mm:dd";
dt = StrToDateTime(datetime,fs);
if( !SetFileCreationTime(fullpath, dt) )
ShowMessage("file creation date set failed");
}
if( Form1->SnifGPSInfo->IsChecked ){
filename = ExtractFileName(fullpath);
//Memo1->Lines->Add("Extracted filename " + filename);
filepath = ExtractFilePath(fullpath);
//Memo1->Lines->Add("Extracted filepath " + filepath);
newname = filepath + prefix + filename;
//Memo1->Lines->Add("newname is " + newname);
// AnsiString(fname).c_str()
sample_removeGPSData(AnsiString(fullpath).c_str(), AnsiString(newname).c_str());
if( Form1->FixDateTime->IsChecked ){// should again set file creation time for output
//Form1->Memo1->Lines->Add("datetime is " + datetime);
TDateTime dt;
TFormatSettings fs;
fs = TFormatSettings::Create(); // Initialize with defaults
//fs.DateSeparator = ':';
fs.ShortDateFormat = "yyyy:mm:dd";
dt = StrToDateTime(datetime,fs);
if( !SetFileCreationTime(newname, dt) )
ShowMessage("file creation date set failed");
}
//Memo1->Lines->Add("datetime " + datetime);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OpenClick(TObject *Sender)
{
if( OpenDialog1->Execute()){
Parse_File(OpenDialog1->FileName);
}
}
bool TouchFileTimestamp(String path)
{
//Form1->Memo1->Lines->Add(path);
// at first extract exif.recordedtime
Parse_File(path); // where is data Memo1->Lines->Add(o2) in function
return true;
}
void DigDirectory(String path)
{
fs::path target_path = path.c_str();
try {
// directory_iteratorを使用してディレクトリ内を走査
for (const fs::directory_entry& entry : fs::directory_iterator(target_path)) {
// entry.path() でフルパスを取得し、filename() でファイル名のみを抽出
//std::cout << entry.path().filename() << std::endl;
//Form1->Memo1->Lines->Add( path + "\\" + entry.path().filename().c_str());
//Form1->Memo1->Lines->Add(entry.path().c_str());
TouchFileTimestamp(entry.path().c_str());
}
} catch (const fs::filesystem_error& e) {
// ディレクトリが存在しない場合などのエラー処理
//std::cerr << "エラーが発生しました: " << e.what() << std::endl;
ShowMessage("error");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DragDrop(const Fmx::Types::TDragObject &Data, const System::Types::TPointF &Point)
{
TForm::DragDrop(Data,Point);
for( int i = 0 ; i < Data.Files.Length ; i ++ ){
if(DirectoryExists(Data.Files[i]))
DigDirectory(Data.Files[i]);
else
//Memo1->Lines->Add(Data.Files[i]);
TouchFileTimestamp(Data.Files[i]);
}
}
void __fastcall TForm1::DragOver(const Fmx::Types::TDragObject &Data, const System::Types::TPointF &Point, Fmx::Types::TDragOperation &Operation)
{
TForm::DragOver(Data,Point,Operation);
Operation = TDragOperation::Copy;
}
exif.cとexif.hの作者の許諾が得られば、ソース全体やらプロジェクト全体を提示するかもしれません。バイナリの要望があればダウンロードできるようにしますので、コメント願います。



コメント