Visual C++ 2008 Express Editionでアプリを作る(その11)

なければ作ればいい。と偉い人が言っていたので(本当は疲れたので)単純なWindows APIを呼び出す方法をとることにした。
SHFileOperationを実行するため、shell32.libを組み込んだ。
String^をLPCSTRに型変換するのは、Marshalクラスのメソッドを使うと実現出来るらしい。try {} finally {}で例外発生時も可能な限り解放するのが作法みたい。
Windows APIを呼び出す関数をextern "C" {}で囲んだのは必要ないな。
このMoveToTrashをDeleteの代わりに使う事で、取りあえず目的の動作が出来た。

#include <windows.h>
#include <string.h>
#include <locale.h>

(略)

#pragma comment(lib, "shell32.lib")
extern "C" {
int MyDelete(LPCTSTR files2)
{
  SHFILEOPSTRUCT sh_file_operation_struct;
  FILEOP_FLAGS   flags = FOF_ALLOWUNDO  | FOF_NOCONFIRMATION;
  int result = 1;

  // 文字列終端をNULLを2つにする
  LPTSTR files_null = (LPTSTR)calloc(lstrlen(files2) + 2, sizeof(TCHAR));
  lstrcpy(files_null, files2);

  ZeroMemory( &sh_file_operation_struct, sizeof(sh_file_operation_struct) );
  sh_file_operation_struct.wFunc  = FO_DELETE;
  sh_file_operation_struct.fFlags = flags;
  sh_file_operation_struct.pFrom  = files_null;
  result = SHFileOperation(&sh_file_operation_struct);
  free(files_null);
  return result;
}
};

int FileTool::MoveToTrash(String^ pathname)
{
  int result = 1;
  LPCTSTR files;
  
  //StringをLPCTSTRに変換する
  IntPtr p = System::Runtime::InteropServices::Marshal::StringToHGlobalAuto(pathname);
  files = static_cast<LPCTSTR>(p.ToPointer());
  try {
	result = MyDelete(files);
  } finally {
	System::Runtime::InteropServices::Marshal::FreeHGlobal(p);
  }
  return result;
}