![]()
![]()
C++BuilderのTIP集です。まだ、書き出しですが、徐々に増やしてゆく予定です。
目次
階層化した(親なし)ディレクトリを作成する関数
ショートパスを返す関数
FILETIME を TDateTime() に変更する関数
このページで公開されているチップは、すべてテスト済みです。
著作権は、放棄します。 自由にご使用いただいて結構です。
//ネストされたディレクトリを作成する
bool __fastcall CreateNestedDir(AnsiString ADir)
{
if(!DirectoryExists(ADir)) {
if(!CreateDir(ADir)) { //作成できない場合は、親を先に作る
if(!CreateNestedDir(ExtractFileDir(ADir))) return false;
return CreateDir(ADir);
}
return true;
}
return true;
}
//ショートパスを返す関数
AnsiString __fastcall ShortPathFileName(AnsiString fileName)
{
char *shortPath=(char*)alloca(fileName.Length()+1);
GetShortPathName(fileName.c_str(),shortPath,fileName.Length()+1);
return AnsiString(shortPath);
}
//相対パスを取得する関数AnsiString __fastcall RelativeFilePath(constAnsiString fileName,constAnsiString baseDir)
{
// SJIS漢字コード第2バイト目にパスキャラクタ'\'文字が含まれる場合があるため、
// 一時 WideString 型(UNICODE) に戻す。
WideString full_fileName =static_cast<WideString>(ExpandFileName(fileName));
WideString full_baseDir = static_cast<WideString>(ExpandFileName(baseDir));if(ExtractFilePath(full_baseDir)!=full_baseDir)
full_baseDir +='\\';int i=1;
for(i=1;i<=full_fileName.Length();i++)
if(towupper(full_fileName[i])!=towupper(full_baseDir[i]))
break;if(i==full_fileName.Length()+1) i = max(i-1,1);
do {
if(full_fileName[i]=='\\')break;
if(i==1)break; i--;
}while(towupper(full_fileName[i])==towupper(full_baseDir[i]));if(i==1)return full_fileName ; //全く一致しない
WideString relativePath
= full_fileName.SubString(i+1,full_fileName.Length()-i);int relCount =0;
//一致しない部分のパス区切り総計を求める
for(int j=i+1; j<= full_baseDir.Length(); j++) {
if(full_baseDir[j]=='\\') relCount++ ;
}for(int j=0 ; j<relCount ; j++) {
relativePath = "..\\"+ relativePath;
}return static_cast<AnsiString>(relativePath);
}
//整数を1024単位のキロ、メガ、ギガ、テラ表記へ変換する
AnsiString __fastcall IntToKMGT(__int64 val)
{
double bytes = double(val);
int unitno = -1;
while(bytes>1024){
bytes/=1024; unitno++;
}
AnsiString text;
if(unitno<0)
text = IntToStr(val);
else
text = FloatToStrF(bytes,ffFixed,5,2);
if(unitno>=0){
switch(unitno){
case 0: text+='K'; break;
case 1: text+='M'; break;
case 2: text+='G'; break;
case 3: text+='T'; break;
default:text+='?'; break;//テラの次は何?
}
}
return text;
}
//2メモリ域をスワップする
void__fastcall SwapMemory(void*lp1,void*lp2,DWORD size)
{
//スワップする必要がない
if( lp1==lp2 || NULL==lp1 || NULL==lp2 || 0==size )return;DWORD remSize = size&3 ; //4で割った余り
if(size>=4) {
asm{ //クロック数短縮のためアセンブラを使う
//BCBでアセンブラを組む場合は、汎用レジスタのpush/popの必要はありません。
mov ecx,size
shr ecx,2
mov edi,lp1
mov esi,lp2
//アセンブラにラベルをBCBで使用する場合、グローバルに展開されるので、
//↓重ならない名前をいちいち使用しなければなりません。
SwapMemory_LOOP:
mov eax,[edi+ecx*4-4]
mov ebx,[esi+ecx*4-4]
mov [esi+ecx*4-4],eax
mov [edi+ecx*4-4],ebx
dec ecx
jnz SwapMemory_LOOP
}
}if(remSize>0) { //残り3バイト以内のバイト数を複写する
int loc=(size&~3) ; //←最後の4バイトアラインのオフセット位置
for(DWORD i=0;i<remSize;i++) {
BYTE v =((BYTE*)lp1)[loc+i] ;
((BYTE*)lp1)[loc+i] = ((BYTE*)lp2)[loc+i] ;
((BYTE*)lp2)[loc+i] = v ;
}
}}
下図の緑線部分の領域(デスクトップクライアント)を取得する
![]()
//デスクトップのクライアント領域を取得する
TRect __fastcall GetDesktopClient()
{
RECT rect;ZeroMemory(&rect,sizeof(rect));
SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);return TRect(rect);
}
ファイルをダブルクリックした時の動作をシミュレートさせます。APIのShellExecute()関数のlpszOpパラメータにNULLを渡した場合、実行されるのはデフォルトに指定されているコマンドではなく、"open"(開く)コマンドであるため、ファイルをダブルクリックした時の動作を的確に処理させるためには、ShellExecuteEx()関数を変わりに使用する必要があります。
//ShellExecuteのデフォルトコマンドを実行する
bool __fastcall ShellExecuteDefault(AnsiString FileName,HWND Handle)
{
SHELLEXECUTEINFO info;
ZeroMemory(&info,sizeof(info));
info.cbSize =sizeof(SHELLEXECUTEINFO) ;
info.fMask =0 ;
info.hwnd = Handle ;
info.lpVerb ="";
info.lpFile = FileName.c_str();
info.lpParameters ="";
info.lpDirectory ="";
info.nShow = SW_SHOWNORMAL ;
info.hInstApp =0;
info.lpIDList = NULL ;
info.lpClass = NULL ;
info.hkeyClass =0;
info.dwHotKey =0;
info.hIcon =0;
return ShellExecuteEx(&info) ? true :false;
}<例>
//ホームページを表示する
ShellExecuteDefault("http://bronze.zero.jp/menisys/",Application->Handle);
//ファイルから日付情報を取得する
bool __fastcall GetFileNameTime(AnsiString FileName,
FILETIME *lpftCreation, FILETIME *lpftLastAccess,FILETIME *lpftLastWrite)
{
HANDLE hFile =
CreateFile(
FileName.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0,0);
if(!hFile)return false;
BOOL RESULT = GetFileTime(hFile,lpftCreation,lpftLastAccess,lpftLastWrite);
CloseHandle(hFile);
return RESULT?true:false;
}
//ファイルへ日付情報を設定する
bool __fastcall SetFileNameTime(AnsiString FileName,
FILETIME *lpftCreation, FILETIME *lpftLastAccess,FILETIME *lpftLastWrite)
{
HANDLE hFile =
CreateFile(
FileName.c_str(),
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0,0);
if(!hFile)return false;
BOOL RESULT = SetFileTime(hFile,lpftCreation,lpftLastAccess,lpftLastWrite);
CloseHandle(hFile);
return RESULT?true:false;
}
// FILETIME を TDateTime() に変更する
TDateTime FileTimeToDateTime(const FILETIME &FileTime)
{
SYSTEMTIME SystemTime ;
ZeroMemory(&SystemTime,sizeof(SYSTEMTIME));
FileTimeToSystemTime(&FileTime,&SystemTime);
return TDateTime(SystemTime.wYear,SystemTime.wMonth,SystemTime.wDay)
+ TDateTime(SystemTime.wHour,SystemTime.wMinute,SystemTime.wSecond,SystemTime.wMilliseconds);
}
まだ、整理していませんが、使ってください。 お役に立てれば幸いです。
//-----
//ファイルサイズを得る
long __fastcall GetFileSize(AnsiString FileName)
{
FILE *st = fopen(FileName.c_str(),"rb");
long file_size = filelength(_fileno(st));
fclose(st);
return file_size;
}
//-----
//マスクと一致するかどうか求める
bool __fastcall MatchesMaskEx(const AnsiString FileName, const AnsiString Mask)
{
AnsiString mask1, mask2 ;
AnsiString fn0, fn1, fn2;
int i, j, k ;
i = AnsiPosBackward('.',Mask) ;
j = Mask.Length();
if (i > 1) {
mask1 = Mask.SubString(1, (i - 1));
if ( j > i )
mask2 = Mask.SubString((i + 1), (j - i)) ;
else
mask2 = '*';
}else {
if (i == 0) {
mask1 = Mask;
mask2 = '*';
}else {
mask1 = '*';
if ( j > i )
mask2 = Mask.SubString((i + 1), (j - i)) ;
else
mask2 = '*' ;
}
}
fn0 = ExtractFileName(FileName);
i = AnsiPosBackward('.',fn0) ;
j = fn0.Length() ;
if ( i > 1 ) {
fn1 = fn0.SubString(1, (i - 1));
if ( j > i )
fn2 = fn0.SubString((i + 1), (j - i)) ;
else
fn2 = "";
}else {
if ( i == 0 ) {
fn1 = fn0;
fn2 = "";
}else {
fn1 = "";
if ( j > i )
fn2 = fn0.SubString((i + 1), (j - i)) ;
else
fn2 = "" ;
}
}
i = fn1.Length();
j = mask1.Length();
k = 1;
while ((i > 0) && (j > 0)) {
if (mask1[k] == '*') {
i = j = 0;
break;
}
if ( mask1[k] == '?' ) {
if ( StrByteType(fn1.c_str(), (k - 1)) != mbSingleByte )
i--;
}else {
if ( StrByteType(mask1.c_str(), (k - 1)) == mbSingleByte ) {
if ( toupper(mask1[k]) != toupper(fn1[k]) )
return false ;
}else {
if ( (i <= 1) || (mask1[k] != fn1[k]) ||
(mask1[k + 1] != fn1[k + 1]) )
return false ;
i-- ;
j-- ;
k++ ;
}
}
i-- ;
j-- ;
k++ ;
}
if ( (i > 0) || (j > 0) )
return false ;
i = fn2.Length();
j = mask2.Length();
k = 1;
while ( (i > 0) && (j > 0) ) {
if ( mask2[k] == '*' ) {
i = j = 0;
break;
}
if ( mask2[k] == '?' ) {
if ( StrByteType(fn2.c_str(), (k - 1)) != mbSingleByte )
i--;
}else {
if( StrByteType(mask2.c_str(), (k - 1)) == mbSingleByte ) {
if (toupper(mask2[k]) != toupper(fn2[k]))
return false ;
}else {
if ( (i <= 1) || (mask2[k] != fn2[k]) ||
(mask2[k + 1] != fn2[k + 1]) )
return false ;
i--;
j--;
k++;
}
}
i--;
j--;
k++;
}
if ( (i > 0) || (j > 0) )
return false ;
return true ;
}
//-----
//数値を2進法文字列に変換
AnsiString __fastcall DWORDToBin(DWORD value,int precision)
{
AnsiString retVal="";
AnsiString a1="1",a0="0";
for(int i=0;i<precision;i++) {
if(value&(1UL<<i)) retVal=a1+retVal;
else retVal=a0+retVal;
}
return retVal;
}
//-----
//2進法文字列を数値に変換
DWORD __fastcall BinToDWORD(const AnsiString string)
{
DWORD val=0;
int length=string.Length();
char *buff=(char*)alloca(length+1);
strcpy(buff,string.c_str());
for(int i=0;i<length;i++) {
val<<=1;
if(buff[i]=='1') val|=1;
else if(buff[i]!='0') {
throw EConvertError("`"+ string + "' は、2進表記文字列ではありません。");
}
}
return val;
}
//-----
//AnsiStringをロードする
AnsiString __fastcall LoadAnsiString(AnsiString FileName)
{
long length = GetFileSize(FileName);
FILE *fp=fopen(FileName.c_str(),"rb");
if(!fp) throw EFOpenError("\""+FileName+"\" ←ファイルをオープンできません!");
AnsiString Result;
Result.SetLength(length);
for(int i=0;i<length;i++) {
Result[i+1] = (char)getc(fp);
}
fclose(fp);
return Result;
}
//-----
//AnsiStringをセーブする
void __fastcall SaveAnsiString(AnsiString FileName,AnsiString TargetString)
{
FILE *fp = fopen(FileName.c_str(),"wb");
if(!fp) throw EFCreateError("\""+FileName+"\" ←ファイルを作成/書込できません!");
long length = TargetString.Length();
for(int i=0;i<length;i++) {
if(putc(TargetString[i+1],fp)==EOF) {
fclose(fp);
throw EFCreateError("\""+FileName+"\" ←ファイル作成/書込途中に、書けなくなりました!");
}
}
fclose(fp);
}
//-----
//Controlを中央に移動
void __fastcall ControlCentering(
TControl *Dest,TControl *Parent,bool Horizontal,bool Vertical)
{
int Left,Top,Width,Height;
if(!Parent) {
Left=0;
Top=0;
Width=Screen->Width;
Height=Screen->Height;
}else {
Left = Parent->Left ;
Top = Parent->Top ;
Width = Parent->Width ;
Height= Parent->Height ;
}
if(Horizontal)
Dest->Left = ( Width - Dest->Width )/2 + Left ;
if(Vertical)
Dest->Top = ( Height - Dest->Height )/2 + Top ;
}
//-----
//----------------------------------------------------------
//SJIS漢字高速判別ヘッダ部(jcype.h)
#ifndef jctypeH//----------------------------------------------------------
#define jctypeHextern const bool MNS_iskanji_table[256];
extern const bool MNS_iskanji2_table[256];
#define iskanji(c) ((bool)(MNS_iskanji_table[(unsigned char)(c)]))
#define iskanji2(c) ((bool)(MNS_iskanji2_table[(unsigned char)(c)]))#endif
const bool MNS_iskanji_table[256]={//----------------------------------------------------------
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,false,false,false
};const bool MNS_iskanji2_table[256]={
false,false,false,false,false,false,false,false, //0x00
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false, //0x10
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false, //0x20
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false, //0x30
false,false,false,false,false,false,false,false,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,false,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,true ,true ,true ,
true ,true ,true ,true ,true ,false,false,false
};
//-----
//文字列を、ファイル名として使用できる形に修正する
AnsiString __fastcall StrToValidFileName(const AnsiString S)
{
AnsiString Result="";
bool Kanji=false ;
for(int i=0;i<S.Length();i++) {
char c = S[i+1] ;
if(!Kanji) {
if(iskanji(c)) {
Kanji=true ;
}else if(iscntrl(c) ||
c=='\\' || c=='/' || c== ':' || c==';' || c==',' || c=='*' || c=='?' ||
c=='\"' || c=='<' || c== '>' || c=='|' ) {
c = '_';
}
}else Kanji= false ;
Result += c;
}
if(Result.Length()>MAX_PATH) Result=Result.SubString(1,MAX_PATH);
return Result ;
}
//-----
//---------------------------------------------------
//パッドデータを読む(ヘッダ部)
#define PAD_1
JOY_BUTTON32
#define PAD_2
JOY_BUTTON31
#define PAD_LEFT JOY_BUTTON27
#define PAD_RIGHT JOY_BUTTON28
#define PAD_UP JOY_BUTTON29
#define PAD_DOWN JOY_BUTTON30
#define PAD_A
JOY_BUTTON1
#define PAD_B
JOY_BUTTON2
#define PAD_C
JOY_BUTTON3
#define PAD_D
JOY_BUTTON4
#define PAD_E
JOY_BUTTON5
#define PAD_F
JOY_BUTTON6
#define PAD_G
JOY_BUTTON7
#define PAD_H
JOY_BUTTON8
#define PAD_I
JOY_BUTTON9
#define PAD_J
JOY_BUTTON10
#define PAD_K
JOY_BUTTON11
#define PAD_L
JOY_BUTTON12
#define PAD_M
JOY_BUTTON13
#define PAD_N
JOY_BUTTON14
#define PAD_O
JOY_BUTTON15
#define PAD_P
JOY_BUTTON16
#define PAD_Q
JOY_BUTTON17
#define PAD_R
JOY_BUTTON18
#define PAD_S
JOY_BUTTON19
#define PAD_T
JOY_BUTTON20
#define PAD_U
JOY_BUTTON21
#define PAD_V
JOY_BUTTON22
#define PAD_W
JOY_BUTTON23
#define PAD_X
JOY_BUTTON24
#define PAD_Y
JOY_BUTTON25
#define PAD_Z
JOY_BUTTON26
#define PAD_PLAYERS
(PAD_1|PAD_2)
#define PAD_DIRECTIONS
(PAD_LEFT|PAD_RIGHT|PAD_UP|PAD_DOWN)
#define PAD_BUTTONS
(~(DWORD)(PAD_DIRECTIONS|PAD_PLAYERS))
typedef struct
tagTPadKeyMaps {
bool Enabled;
int Left,Right,Up,Down;
int Buttons[26];
} TPadKeyMaps ;
extern TPadKeyMaps PadKeyMaps[2];
DWORD __fastcall PadRead(DWORD player /* PAD_1 or PAD_2 */ );
//---------------------------------------------------
//パッドデータを読む(ソース部)
TPadKeyMaps PadKeyMaps[2]={
{
true,
VK_LEFT,VK_RIGHT,VK_UP,VK_DOWN,
{'Z','X','C','A','S','D','Q','W','E',0
, 0,0
,0,
0,0
,0,
0,0
,0,
0
, 0,0
,0,
0,0
,0}
},{
true,
VK_NUMPAD4,VK_NUMPAD6,VK_NUMPAD8,VK_NUMPAD2,
{'N','M',',','H','J','K','Y','U','I',0
, 0,0
,0,
0,0
,0,
0,0
,0,
0
, 0,0
,0,
0,0
,0}
}
};
DWORD __fastcall PadRead(DWORD
player)
{
// JOY_BUTTON1〜26 まで対応。
// 4方向は、最上位ビットに割付けることとする。
const WORD keyPressed =(1<<15);
JOYINFOEX jie;
jie.dwSize=sizeof(jie);
jie.dwFlags=JOY_RETURNALL|JOY_RETURNCENTERED|JOY_USEDEADZONE;
const DWORD playerMask[2]={PAD_1,PAD_2};
for(int
i=0;i<2;i++){
if(player&playerMask[i]){
MMRESULT mmr=joyGetPosEx((i?JOYSTICKID2:JOYSTICKID1),&jie);
if(mmr==JOYERR_NOERROR){
if((int)jie.dwXpos-32768<-8192)
player |= PAD_LEFT;
if((int)jie.dwXpos-32768>+8192)
player |= PAD_RIGHT;
if((int)jie.dwYpos-32768<-8192)
player |= PAD_UP;
if((int)jie.dwYpos-32768>+8192)
player |= PAD_DOWN;
player|=jie.dwButtons&PAD_BUTTONS;
}
if(PadKeyMaps[i].Enabled){
if(GetKeyState(PadKeyMaps[i].Left)&keyPressed)
player |= PAD_LEFT ;
if(GetKeyState(PadKeyMaps[i].Right)&keyPressed)
player |= PAD_RIGHT ;
if(GetKeyState(PadKeyMaps[i].Up)&keyPressed)
player |= PAD_UP ;
if(GetKeyState(PadKeyMaps[i].Down)&keyPressed)
player |= PAD_DOWN ;
for(int
j=0;j<26;j++){
int
key = PadKeyMaps[i].Buttons[j];
if(
key != 0 ){
if(GetKeyState(key)&(1<<15)){
player |= 1<<j
;
}
}
}
}
}
}
return player;
}
//---------------------------------------------------