[C++Builder] ファイル名がワイルドカードにマッチしているかを調べる
#include <Masks.hpp>
MatchesMask
| 固定リンク
#include <nmmintrin.h> // MMX-SSE4.2
#include <smmintrin.h> // MMX-SSE4.1
#include <intrin.h> // MMX-SSE3
#include <emmintrin.h> // MMX-SSE2
#include <xmmintrin.h> // MMX-SSE
#include <mmintrin.h> // MMX
| 固定リンク
C++ Builder 2009でTImageにPNG画像を読み込んでコンパイルすると以下のエラーがでる。TPNGImageを直接利用しても同様のエラー。
[ILINK32 エラー] Error: 未解決の外部参照 'Pnglang::_EPngInvalidCRCText' が C:\PROGRAM FILES\CODEGEAR\RAD STUDIO\6.0\LIB\OBJ\PNGIMAGE.OBJ から参 照されました
画像処理のパッケージがVCLJPGからVCLIMGに変更されたことが原因。
プロジェクトにPnglang.hppを追加するか(Program Files以下で検索すれば見つかる)、PNGImage.hppの適当なところに
#pragma link "vclimg.lib"
を書いておけば大丈夫
| 固定リンク
C++Builder 2009ではAnsiStringでコードページが指定できます。
typedef AnsiStringT<932> SJISString;
| 固定リンク
//非表示にする
#pragma warn -8056
//表示するようにする
#pragma warn .8056
VCの
#pragma warning(disable : 8056)
#pragma warning(default : 8056)
に対応
| 固定リンク
TForm *Dlg=CreateMessageDialog("元のファイルが上書きされます。続行し
てもよろしいですか?",mtWarning,TMsgDlgButtons() <<mbOk<<mbNoToAll<<mbYesToAll<<mbCancel);
Dlg->Caption="警告";
Dlg->ShowModal();
delete Dlg;
TMsgDlgBtn値、戻り値
mbOK、mrOk
mbCancel、mrCancel
mbYes、mrYes
mbNo、mrNo
mbAbort、mrAbort
mbRetry、mrRetry
mbIgnore、mrIgnore
mbAll、mrAll
mbNoToAll、mrNoToAll
mbYesToAll、mrYesToAll
| 固定リンク
デフォルトボタンを指定するには、以下のいずれかの値を使います。何も指定しなかった場合には、最初のボタンがデフォルトになります。
0x00000000 (MB_DEFBUTTON1)
最初のボタンをデフォルトにする
0x00000100 (MB_DEFBUTTON2)
2番目のボタンをデフォルトにする
0x00000200 (MB_DEFBUTTON3)
3番目のボタンをデフォルトにする
0x00000300 (MB_DEFBUTTON4)
4番目のボタンをデフォルトにする
例:
Application->MessageBoxA("続行しますか ?","確認",MB_OKCANCEL|MB_DEFBUTTON2);
| 固定リンク
//ヘッダファイル
class TForm1 : public TForm
{
:
private:
//実際にメッセージを処理する関数の宣言
//関数の中身はソースに自分で書く
void __fastcall WMDropFile(TWMDropFiles &Msg);
BEGIN_MESSAGE_MAP
//捕まえたいメッセージと、それを処理する関数を登録
VCL_MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFile)
END_MESSAGE_MAP(TComponent)
};
//ソースファイル
void __fastcall TForm1::FormCreate(TObject *Sender)
begin
DragAcceptFiles(Handle, true);
end;
void __fastcall TForm1::WMDropFile(TWMDropFiles &Msg)
{
//ドロップされたファイルを取得
int Count=DragQueryFile((void *)Msg.Drop, -1, NULL, 0);
for (int i=0;i<Count;i++) {
char Filename[MAX_PATH]={0};
DragQueryFile((void *)Msg.Drop, i, Filename, MAX_PATH);
//Filenameを処理
}
DragFinish((void *)Msg.Drop);
}
| 固定リンク
#pragma pack(push,1)
struct TAPP1Header {
WORD Maker;
WORD Size;
byte Magic[6];
};
#pragma pack(pop)
| 固定リンク
再描画に関連するメソッド
・Invalidate
再描画が必要であることを宣言します。実際の再描画は適当なタイミングで実施されます。
・Update
Invalidateなどで保留中の再描画を強制的に実施します。
・Repaint
Invalidateを呼び出した後、Updateを呼び出します。強制的に再描画します。
・Refresh
Repaintと同じです。
| 固定リンク
赤(R)、緑(G)、青(B)を取得するには、それぞれGetRValue、GetGValue、GetBValueを使う。
(例)
byte R=GetRValue(clBlue);
| 固定リンク
#include <GraphUtil.hpp>
void __fastcall ColorRGBToHLS(unsigned clrRGB, Word &Hue, Word &Luminance, Word &Saturation);
unsigned __fastcall ColorHLSToRGB(Word Hue, Word Luminance, Word Saturation);
| 固定リンク
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender) {
SetWindowLong(Edit1->Handle, GWL_STYLE, GetWindowLong(Edit1->Handle, GWL_STYLE)|ES_NUMBER);
}
さらに、ES_RIGHTを追加すれば右寄せになります。
| 固定リンク
HMODULE LoadLibrary(LPCTSTR lpFileName);
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
BOOL FreeLibrary(HMODULE hModule);
| 固定リンク
MouseDownイベントでVCLのCursorプロパティを変更しても、マウスのボタンが開放されるまでカーソルが変更されません。ボタンが押された瞬間に変更するにはWindows APIを使います。
::SetCursor(Screen->Cursors[crHourGlass]);
またMouseUpイベントにはカーソルを元に戻すコードを書きます。こちらは、VCLのCursorプロパティでもOKです。
Image1->Cursor=ceDefault;
| 固定リンク
----------------
1.まずカーソルデータが含まれたリソースファイルを作成 (参考:独自のリソースを使う)
mycursor.rc
MyCursor1 CURSOR "Cursor_1.cur"
MyCursor2 CURSOR "Cursor_2.cur"
このファイルをプロジェクトに追加する。
----------------
2.メインフォームのOnCreateでリソースからカーソルを読み込む
//カーソル定数
static const TCursor crMyCursor1=1;
static const TCursor crMyCursor2=2;
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Screen->Cursors[crMyCursor1] = LoadCursor(HInstance, "MyCursor1");
Screen->Cursors[crMyCursor2] = LoadCursor(HInstance, "MyCursor2");
}
カーソル定数はデフォルトの定数(crDefaultなど)と重ならないように定義する。カーソル定数はTCursor型で-32768から32367までの整数であり、BDS2006では-22から0までがデフォルトの定数に使用されている。
注意:カーソルを使い終わってもDestroyCursorを呼び出してはいけない。勝手に開放される。
----------------
3.使いたいことろで、
Image1->Cursor=crMyCursor1;
のように使う。
----------------
| 固定リンク
WM_SYSCOMMAND の wParamがSC_SCREENSAVE のとき1を返せばスクリーンセーバの起動を抑制できるようです。
ヘッダ
private:
void __fastcall WMSysCommand(TMessage &Msg);
BEGIN_MESSAGE_MAP
//捕まえたいメッセージと、それを処理する関数を登録
VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, WMSysCommand)
END_MESSAGE_MAP(TComponent)
ソース
//---------------------------------------------------------------------------
//スクリーンセーバの起動を抑制
void __fastcall TForm1::WMSysCommand(TMessage &Msg)
{
if (Msg.WParam==SC_SCREENSAVE) {
Msg.Result=1;
} else {
Msg.Result=DefWindowProc(Handle,Msg.Msg,Msg.WParam,Msg.LParam);
}
}
| 固定リンク
AnsiString __cdecl FormatEx(const char *format, ...)
{
va_list args;
va_start(args,format);
AnsiString Buf="";
Buf.vprintf(format,args);
va_end(args);
return Buf;
}
使い方は、
AnsiString Str=FormatEx("%sは%dです",buffer,i);
| 固定リンク
RemoveDir関数は空でないフォルダを削除することができません。空ではないフォルダを削除するにはSHFileOperationを使う方法もありますが、ここでは再帰的に削除する方法を示します。
bool __fastcall TForm1::ForceRemoveDir(AnsiString DirName)
{
TSearchRec sr;
int Attr=faAnyFile;
bool Result=true;
DirName=IncludeTrailingPathDelimiter(DirName);
if (FindFirst(DirName+"*",Attr,sr)==0) {
do {
if ((sr.Name==".")||(sr.Name=="..")) continue;
if ((sr.Attr&faDirectory)!=0)
Result=Result && ForceRemoveDir(DirName+sr.Name);
else
Result=Result && DeleteFile(DirName+sr.Name);
} while (FindNext(sr)==0);
FindClose(sr);
}
Result=Result && RemoveDir(ExcludeTrailingPathDelimiter(DirName));
return Result;
}
| 固定リンク
文字列に含まれる%SystemRoot%のような環境変数を展開する方法です。
ExpandEnvironmentString関数を使います。
char ExpandName[MAX_PATH];
ExpandEnvironmentStrings("%SystemRoot%\temp",ExpandName,sizeof(ExpandName));
| 固定リンク
TListViewのOnAdvancedCustomDrawSubItemやOnAdvancedCustomDrawItemイベントで処理をするとフォントがおかしくなることがあります。
その場合は、以下を書き加えてみてください。
if (ListView1->Canvas->Font->OnChange!=NULL) ListView1->Canvas->Font->OnChange(ListView1->Canvas->Font);
| 固定リンク
デスクトップやマイドキュメントなどの特殊フォルダの位置を取得する方法です。
以下はデスクトップの位置を取得する例です。
#include <shlobj.h>
TCHAR szPath[_MAX_PATH];
LPITEMIDLIST pidl;
IMalloc *pMalloc;
SHGetMalloc(&pMalloc);
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &pidl))) {
SHGetPathFromIDList(pidl,szPath);
pMalloc->Free(pidl);
}
pMalloc->Release();
| 固定リンク
//Header file
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
private: // ユーザー宣言
void __fastcall WMNCHitTest(TWMNCHitTest &Msg);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_NCHITTEST, TWMNCHitTest, WMNCHitTest)
END_MESSAGE_MAP(TComponent)
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//cpp file
void __fastcall TForm1::WMNCHitTest(TWMNCHitTest &Msg)
{
DefaultHandler(&Msg);
if (Msg.Result==HTCLIENT) { // クライアント領域がクリックされら
Msg.Result = HTCAPTION; //タイトルバーがクリックされたと Windows に思わせる
}
}
| 固定リンク
プロジェクトをコンパイルしようとしたところ「継承元の'Label2'が見つかりません.」というダイアログが表示され、コンパイルが出来なくなってしまいました。
調べてみたところ、IDEのバグのようでホームページ上で対処法が公開されていました。
http://support.codegear.com/jp/print/35919
対処法としては、プロジェクトファイルをエディタなどで開いて、次の2つのエレメントを削除した後、開きなおしたところコンパイル出来るようになりました。
<property category="build.node" name="libraries" value="..."/>
<property category="build.node" name="sparelibs" value="..."/>
詳細は、CodeGearのホームページをご覧ください。
| 固定リンク
#include <shlobj.h>
すると
FOLDERSETTINGSの宣言が複数見つかった
DESKBANDINFOの宣言が複数見つかった
:
というエラーがでます。
解決するには、「プロジェクト」-「オプション」から「パスと定義」の条件定義にNO_WIN32_LEAN_AND_MEANを追加します(BDS2006の場合)。
ソースの中で
#define NO_WIN32_LEAN_AND_MEAN
してもうまくいきませんでした。
| 固定リンク
ActionListは設計時にForm上に配置されているものとします。
TAction *Action=new TAction(ActionList1); //TActionを作る
Action->ActionList=ActionList1; //ActionListを設定する
| 固定リンク
//消す
do { } while (ShowCursor(FALSE)<0);
//表示する
do { } while (ShowCursor(TRUE)>=0);
| 固定リンク
// TFileTime型をTDateTime型に変換する
TDateTime __fastcall TForm1::FileTimeToDateTime(TFileTime FileTime)
{
TFileTime LocalTime;
TSystemTime SystemTime;
if ((FileTime.dwLowDateTime==0) && (FileTime.dwHighDateTime==0)) return 0;
FileTimeToLocalFileTime(&FileTime,&LocalTime);
FileTimeToSystemTime(&LocalTime,&SystemTime);
return SystemTimeToDateTime(SystemTime);
}
| 固定リンク
char *LangName=NULL;
LCID id=GetUserDefaultLCID();
int Len=GetLocaleInfo(id,LOCALE_SENGLANGUAGE,NULL,0);
if (Len>0) {
LangName=new char[Len+1];
ZeroMemory(LangName,Len+1);
GetLocaleInfo(id,LOCALE_SENGLANGUAGE,LangName,Len+1);
}
LOCALE_SENGLANGUAGEの部分を変えれば、国名(LOCALE_SENGCOUNTRY)や通貨名(LOCALE_SENGCURRNAME)、日付時刻の区切り文字(LOCALE_SDATE、LOCALE_STIME)などの各種ロケール情報を取得できます。
| 固定リンク
LCID LocaleID=GetUserDefaultLCID();
switch (LocaleID) {
case 1025: //Arabic (Saudi Arabia)
case 2049: //Arabic (Iraq)
case 3073: //Arabic (Egypt)
case 4097: //Arabic (Libya)
case 5121: //Arabic (Algeria)
case 6145: //Arabic (Morocco)
case 7169: //Arabic (Tunisia)
case 8193: //Arabic (Oman)
case 9217: //Arabic (Yemen)
case 10241: //Arabic (Syria)
case 11265: //Arabic (Jordan)
case 12289: //Arabic (Lebanon)
case 13313: //Arabic (Kuwait)
case 14337: //Arabic (U.A.E.)
case 15361: //Arabic (Bahrain)
case 16385: //Arabic (Qatar)
case 1026: //Bulgarian
case 1027: //Catalan
case 1028: //Chinese (Taiwan)
case 2052: //Chinese (PRC)
case 3076: //Chinese (Hong Kong)
case 4100: //Chinese (Singapore)
case 1029: //Czech
case 1030: //Danish
case 1031: //German (Standard)
case 2055: //German (Swiss)
case 3079: //German (Austrian)
case 4103: //German (Luxembourg)
case 5127: //German (Liechtenstein)
case 1032: //Greek
case 1033: //English (United States)
case 2057: //English (United Kingdom)
case 3081: //English (Australian)
case 4105: //English (Canadian)
case 5129: //English (New Zealand)
case 6153: //English (Ireland)
case 7177: //English (South Africa)
case 8201: //English (Jamaica)
case 9225: //English (Caribbean)
case 10249: //English (Belize)
case 11273: //English (Trinidad)
case 1034: //Spanish (Traditional Sort)
case 2058: //Spanish (Mexican)
case 3082: //Spanish (Modern Sort)
case 4106: //Spanish (Guatemala)
case 5130: //Spanish (Costa Rica)
case 6154: //Spanish (Panama)
case 7178: //Spanish (Dominican Republic)
case 8202: //Spanish (Venezuela)
case 9226: //Spanish (Colombia)
case 10250: //Spanish (Peru)
case 11274: //Spanish (Argentina)
case 12298: //Spanish (Ecuador)
case 13322: //Spanish (Chile)
case 14346: //Spanish (Uruguay)
case 15370: //Spanish (Paraguay)
case 16394: //Spanish (Bolivia)
case 17418: //Spanish (El Salvador)
case 18442: //Spanish (Honduras)
case 19466: //Spanish (Nicaragua)
case 20490: //Spanish (Puerto Rico)
case 1035: //Finnish
case 1036: //French (Standard)
case 2060: //French (Belgian)
case 3084: //French (Canadian)
case 4108: //French (Swiss)
case 5132: //French (Luxembourg)
case 1037: //Hebrew
case 1038: //Hungarian
case 1039: //Icelandic
case 1040: //Italian (Standard)
case 2064: //Italian (Swiss)
case 1041: //Japanese
case 1042: //Korean
case 2066: //Korean (Johab)
case 1043: //Dutch (Standard)
case 2067: //Dutch (Belgian)
case 1044: //Norwegian (Bokmal)
case 2068: //Norwegian (Nynorsk)
case 1045: //Polish
case 1046: //Portuguese (Brazil)
case 2070: //Portuguese (Portugal)
case 1048: //Romanian
case 1049: //Russian
case 1050: //Croatian
case 2074: //Serbian (Latin)
case 3098: //Serbian (Cyrillic)
case 1051: //Slovak
case 1052: //Albanian
case 1053: //Swedish
case 2077: //Swedish (Finland)
case 1054: //Thai
case 1055: //Turkish
case 1057: //Indonesian
case 1058: //Ukrainian
case 1059: //Belarusian
case 1060: //Slovenian
case 1061: //Estonian
case 1062: //Latvian
case 1063: //Lithuanian
case 1065: //Farsi
case 1066: //Vietnamese
case 1069: //Basque
case :1078 //Afrikaans
case 1080: //Faeroese
}
| 固定リンク
#include<FileCtrl.hpp> して
MinimizeNameやSelectDirectoryなどを使おうとすると、コンパイル時にリンクエラー、未解決の外部参照となる場合があります。原因はよくわかりませんが、vclx.lib(BDS2006の場合、それ以外の場合はお尻に数字がつく)というファイルをインストールしたディレクトリ以下から探してきて、プロジェクトに追加してやればコンパイルが通るようになります。
| 固定リンク
LOGFONT lf;
//TFont -> LOGFONT
GetObject(Canvas->Font->Handle, sizeof(LOGFONT), &lf);
//LOGFONT -> TFont
Canvas->Font->Handle = CreateFontIndirect(&lf);
| 固定リンク
if (ListView1->Selected!=NULL)
ListView1->Selected->MakeVisible(true);
| 固定リンク
//-----------------------------------------------------
void __fastcall ListupWindows(void)
{
//ウインドウの列挙
EnumWindows((WNDENUMPROC)EnumWindowsProc , NULL);
}
//------------------------------------------------------
BOOL CALLBACK EnumWindowsProc(HWND hwnd , LPARAM lp)
{
if ((GetWindow(hwnd,GW_OWNER)==NULL) && (IsWindowVisible(hwnd))) {
char buf[1024];
ZeroMemory(buf,1024);
GetWindowModuleFileName(hwnd,buf,1024);
/*
GetWindowText(hwnd , buf , 1024);
GetClassName(hwnd , buf , 1024);
DWORD processID=0;
GetWindowThreadProcessId(hwnd, &processID);
*/
Form1->ListBox1->Items->Add(Str);
}
return TRUE;
}
| 固定リンク
#include <Tlhelp32.h>
void EnumProcesses()
{
//プロセスの列挙
HANDLE hSnapShot;
PROCESSENTRY32 procEntry;
//システムのスナップショットを取得
hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
procEntry.dwSize =sizeof(procEntry);
if (Process32First (hSnapShot,&procEntry)!=NULL) {
do {
ListBox1->Items->Add(procEntry.szExeFile);
} while (Process32Next (hSnapShot,&procEntry));
}
CloseHandle(hSnapShot);
}
| 固定リンク
ListViewのヘッダーに画像を表示する方法です。文字列の左側に表示する場合はプロパティを設定するだけで簡単にできますが、文字列の右側に画像を表示する場合は以下の関数で実現できます。表示したい画像はあらかじめImageListにいれておきます。
void __fastcall TForm1::ShowImageToLvColumn(TListView *ListView,int ACol,int ImageIndex)
{
//ヘッダコントロールのハンドル取得
HWND ColumnHandle=ListView_GetHeader(ListView->Handle);
if (ColumnHandle==NULL) return;
//イメージリストを割り当て
if (!Header_SetImageList(ColumnHandle,ImageList1->Handle)) return;
//設定を取得
HD_ITEM hi;
hi.mask=HDI_FORMAT;
if (!Header_GetItem(ColumnHandle,ACol,&hi)) return;
//イメージを設定
hi.mask = HDI_IMAGE|HDI_FORMAT;
if (ImageIndex>=0) {
hi.fmt |= HDF_IMAGE|HDF_BITMAP_ON_RIGHT; // 取得しておいたフォーマットに HDF_IMAGE 追加
hi.iImage = ImageIndex; // ImageListのID
} else {
hi.fmt &= ~(HDF_IMAGE|HDF_BITMAP_ON_RIGHT);
hi.iImage = 0; //-1をいれるとエラーになる
}
Header_SetItem(ColumnHandle,ACol,&hi);
}
| 固定リンク
rcファイルを使ってアイコンリソースをEXEファイルに埋め込んだときに、アプリケーションのメインアイコンが変わってしまうことがあります。これは、Delphi,BCBはリソース名でリソースを並び替えてしまうためにおきる問題です。
解決策としては、Delphi,BCBではメインアイコンをMAINICONの名前で保持していますので、ソートした時に、これよりも後に来るような名前を付けます。例えば、
OREICON ICON "aaa.ico"
のような感じです。MよりもOの方がアルファベット順が後になります。
| 固定リンク
AnsiString __fastcall HTTPEncodeUTF8(const AnsiString AStr)
{
WideString WStr=AStr;
UTF8String UStr=UTF8Encode(AStr);
AnsiString Result="";
for (int i=1;i<=UStr.Length();i++) {
byte Ch=UStr[i];
if ((Ch>='A' && Ch<='Z') ||
(Ch>='a' && Ch<='z') ||
(Ch=='*') ||
(Ch=='@') ||
(Ch=='.') ||
(Ch=='_') ||
(Ch=='-')) {
Result=Result+(char)Ch;
} else if (Ch==' ') {
Result=Result+"+";
} else {
Result=Result+"%"+AnsiString().sprintf("%.2X",Ch);
}
}
return Result;
}
| 固定リンク
ListViewのHeaderにソートの方向を表す矢印(三角マーク)を表示したりするときに、役に立つと思います。
TreeViewEx1.ColumnImages[2]:=0;
のように設定すると2列目のヘッダにSmallImageに設定されているImageListの最初の画像が表示されます。消すときはColumnImages[2]:=-1のようにします。
| 固定リンク
TModalResult CheckMessageDialog(AnsiString Message, AnsiString Caption,
AnsiString CheckBoxCaption, bool &Checked,
TMsgDlgType DlgType, TMsgDlgButtons Buttons)
{
TForm *Dialog=CreateMessageDialog(Message, DlgType, Buttons);
if (!Caption.IsEmpty()) Dialog->Caption = Caption;
int LeftEdge=Dialog->ClientWidth;
int TopEdge =Dialog->ClientHeight;
if (Dialog->ControlCount>0) {
for (int i = 1; i < Dialog->ControlCount; i++) {
TControl *Ctrl=Dialog->Controls[i];
if (Ctrl->Left < LeftEdge) LeftEdge=Ctrl->Left;
if (Ctrl->Top < TopEdge) TopEdge =Ctrl->Top;
}
} else {
LeftEdge=20;
TopEdge=20;
}
TCheckBox * CheckBox = new TCheckBox(Dialog);
CheckBox->Parent = Dialog;
CheckBox->Caption = CheckBoxCaption;
CheckBox->Checked = Checked;
CheckBox->Left = LeftEdge;
CheckBox->Top = Dialog->ClientHeight;
CheckBox->Width = Dialog->Canvas->TextWidth(CheckBox->Caption)+30;
Dialog->ClientHeight = Dialog->ClientHeight + CheckBox->Height + TopEdge;
if (CheckBox->Width + LeftEdge*2 > Dialog->ClientWidth)
Dialog->ClientWidth = CheckBox->Width + LeftEdge*2;
TModalResult Result = Dialog->ShowModal();
Checked = CheckBox->Checked;
delete Dialog;
Dialog=NULL;
return Result;
}
使い方
bool Checked=false;
CheckMessageDialog("本当に削除してもよろしいですか ?\r\nC:\\tmp\\*.*",
"確認","今後は確認しない", Checked,
mtConfirmation, (TMsgDlgButtons() << mbYes << mbNo << mbHelp));
| 固定リンク
void __fastcall TForm1::ListView1AdvancedCustomDrawItem(
TCustomListView *Sender, TListItem *Item, TCustomDrawState State,
TCustomDrawStage Stage, bool &DefaultDraw)
{
if (Item->Index%2==0)
Sender->Canvas->Brush->Color=(TColor)RGB(240,240,255);
}
| 固定リンク
//header file
class TForm1 : public TForm
{
:
private: // ユーザー宣言
int *FStatusBarWidths;
:
};
//cpp file
//
| 固定リンク
Delphiでは割と簡単だったのですが。もっと簡単な方法があるのでしょうか?
AnsiString Str="<html>aaaa</html>";
SAFEARRAY *safe_array = SafeArrayCreateVector(VT_VARIANT,0,1);
VARIANT *variant;
SafeArrayAccessData(safe_array,(void **)&variant);
variant->vt = VT_BSTR;
variant->bstrVal = SysAllocString(WideString(Str));
SafeArrayUnaccessData(safe_array);
IHTMLDocument2 *Html=NULL;
CppWebBrowser1->Navigate(L"about:blank");
CppWebBrowser1->Document->QueryInterface(IID_IHTMLDocument2,(void **)&Html);
Html->write(safe_array);
Html->close();
Html->Release();
SafeArrayDestroy(safe_array);
| 固定リンク
int __fastcall TSortedObjectList::BinSearch(int Key)
{
if (FList->Count==0) return -1;
int LeftIdx=0;
int RightIdx=FList->Count-1;
while (LeftIdx<=RightIdx) {
int MidIdx=(LeftIdx+RightIdx)/2;
int MidVal=(int)FList->Items[MidIdx];
if (MidVal==Key) return MidIdx; //見つかった
else if (Key>MidVal) LeftIdx=MidIdx+1;
else RightIdx=MidIdx-1;
}
return -1;
}
void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (Key==VK_RETURN) {
SendMessage(Handle, WM_NEXTDLGCTL, 0, 0);
Key=0x00;
}
}
| 固定リンク
StrToIntは文字列を数字に変換するための関数ですが、引数に数字として不正な文字列(例えば「125a」とか)を渡すと例外が発生してしまいます。これをきちんと処理するのが面倒だったり、単純に不正な文字列が渡された場合は-1を返してほしいと思う場合があったりします。そういう時に便利なのがStrToIntDefという関数です。
i:=StrToIntDef(Edit1.Text,-1);
というようにデフォルト値を指定して変換ができます。変換に失敗した場合はデフォルト値が返される仕組みです。例外は発生しません。場合によっては非常に便利な関数です。
| 固定リンク
ファイルの「作成日時」「更新日時」「アクセス日時」を取得する方法です。手順は
1.ファイルをオープン (CreateFile)
2.ファイルタイムを取得 (GetFileTime)
3.取得したファイルタイム(UTC)をローカルタイムに変換 (FileTimeToLocalFileTime)
4.ローカルファイルタイムをシステムタイムに変換 (FileTimeToSystemTime)
5.システムタイムをTDateTime型に変換 (SystemTimeToDateTime)
6.ファイルをクローズ (CloseHandle)
となります。
HANDLE hFile;
FILETIME FtCreationTime,FtLastAccessTime,FtLastWriteTime;
FILETIME LftCreationTime,LftLastAccessTime,LftLastWriteTime;
SYSTEMTIME StCreationTime,StLastAccessTime,StLastWriteTime;
hFile = CreateFile(Filename.c_str() , GENERIC_READ , 0 , NULL ,
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL);
if (hFile != INVALID_HANDLE_VALUE) {
GetFileTime(hFile,&FtCreationTime,&FtLastAccessTime,&FtLastWriteTime);
FileTimeToLocalFileTime(&FtCreationTime,&LftCreationTime);
FileTimeToSystemTime(&LftCreationTime ,&StCreationTime);
Edit1->Text=FormatDateTime("yyyy/mm/dd hh:nn:ss",SystemTimeToDateTime(StCreationTime));
FileTimeToLocalFileTime(&FtLastAccessTime ,&LftLastAccessTime);
FileTimeToSystemTime(&LftLastAccessTime ,&StLastAccessTime);
Edit2->Text=FormatDateTime("yyyy/mm/dd hh:nn:ss",SystemTimeToDateTime(StLastAccessTime));
FileTimeToLocalFileTime(&FtLastWriteTime ,&LftLastWriteTime);
FileTimeToSystemTime(&LftLastWriteTime ,&StLastWriteTime);
Edit3->Text=FormatDateTime("yyyy/mm/dd hh:nn:ss",SystemTimeToDateTime(StLastWriteTime));
}
CloseHandle(hFile);
関連項目:
・世界協定時刻(UTC)をローカルタイムに変換
・TSystemTime(_SYSTEMTIME)とTDateTimeの変換
| 固定リンク
Windows 2000以降でFormを半透明にする方法です。SetLayeredWindowAttributes関数の3番目の引数で透明度を指定します。0が完全に透明で255が不透明です。
void __fastcall TForm1::FormCreate(TObject *Sender)
{
SetWindowLong(Handle, GWL_EXSTYLE,GetWindowLong(Handle, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle,0,200,LWA_ALPHA);
}
同じ関数を使って、ある色だけを透明にしたりもできます。以下の例は、Formの白色の部分を完全に透明にした上で、Formを半透明にしています。
void __fastcall TForm1::FormCreate(TObject *Sender)
{
SetWindowLong(Handle, GWL_EXSTYLE,GetWindowLong(Handle, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle,clWhite,200,LWA_COLORKEY | LWA_ALPHA);
}
| 固定リンク
manifestファイルの書き方はこちらを参照してください。
作成したmanifestファイルをexeファイルにリソースとして埋め込む方法です。
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define CONTROL_PANEL_RESOURCE_ID 123
#define RT_MANIFEST 24
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "○○.exe.manifest"
これをmanifest.rcというようなファイル名で保存します。なお上記の○○の部分には実行ファイルの名前を書きます。「プロジェクト」-「プロジェクトに追加」で作成したrcファイルをプロジェクトに追加します。
これでコンパイルすればOKです。
| 固定リンク
switch (GetSystemMetrics(SM_CLEANBOOT)) {
case 0:
//通常どおり起動された
break;
case 1:
//「Safeモード」で起動された
break;
case 2:
//「ネットワークを使ったSafeモード」で起動された
break;
}
| 固定リンク
int NumOfButton=GetSystemMetrics(SM_CMOUSEBUTTONS);
switch (NumOfButton) {
case 0:
//マウスがない
break;
case 1:
//ボタンが1個
break;
case 2:
:
}
| 固定リンク
if (GetSystemMetrics(SM_MOUSEPRESENT)) {
//接続されている
} else {
//接続されていない
}
| 固定リンク
BCB6.0では、ListViewなどにWindows XPで使用される32bitアイコン(アルファチャンネルを持つ半透明アイコン)を表示しようとすると、アルファがうまく反映されず、アイコンのふちが黒くなって表示されてしまいます。これを解決する方法です。
まず、ImageListを32bitに変更します。例えばFormCreateなどに次のようなコードを書いておきます。
void __fastcall TForm1::FormCreate(TObject *Sender)
{
UINT Flags=ILC_COLOR32;
if (ImageList1->Masked) Flags|=ILC_MASK;
ImageList1->Handle = (int)ImageList_Create(Width, Height, Flags, 0, ImageList1->AllocBy);
}
次に、manifestファイルを作成します。書き方はこちらを参照してください。
以上です。
BCB6.0、XP環境において、ImageListに32bitアイコンを追加していき、ListViewに表示したところ正常に表示されました。
| 固定リンク
「C:\Windows」のようなWindowsディレクトリを取得するには次のようにします。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char Buf[MAX_PATH];
GetWindowsDirectory(Buf,MAX_PATH);
Label1->Caption=Buf;
}
同じように「C:\Windows\System32」のようなシステムディレクトリはGetSystemDirectoryで取得することができます。
| 固定リンク
AnsiStringのsprintfメソッドを使います。
書式はDelphiのFormat関数と同じような感じです。
AnsiString Str=AnsiString().sprintf("%.5d",i);
| 固定リンク
printfのような書式付きのエラーダイアログ表示関数です。
使い方は
ShowError("Cannot open file %s",filename);
のような感じです。
#include <stdarg.h>
void __cdecl TForm1::ShowError(const char *format, ...)
{
va_list args;
va_start(args,format);
AnsiString Buf="";
Buf.vprintf(format,args);
va_end(args);
Application->MessageBoxA(Buf.c_str(),"ERROR",MB_OK | MB_ICONERROR);
}
| 固定リンク
・GetTickCount
コンピュータが起動してからの経過時間をミリ秒で返す。精度はいまいちで5~10ms程度。
・timeGetTime
コンピュータが起動してからの経過時間をミリ秒で返す。
・QueryPerformanceCounter(LARGE_INTEGER *)
高分解能パフォーマンスカウンタの値が取得できる。取得した値はQueryPerformanceFrequencyで得られるカウンタの周波数から、時間に変換できる。
LONGLONG t1,t2,fr;
QueryPerformanceFrequency((LARGE_INTEGER *)&fr);
QueryPerformanceCounter((LARGE_INTEGER *)&t1);
//計測したい処理
QueryPerformanceCounter((LARGE_INTEGER *)&t2);
Label1->Caption=AnsiString().sprintf("%.1f us", (double)(t2-t1) / fr * 1000000);
| 固定リンク
class TForm1 : public TForm
{
protected:
void __fastcall CMDialogKey(Messages::TWMKey &Message)
{
if (Message.CharCode != VK_LEFT) TForm::Dispatch(&Message);
}
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(CM_DIALOGKEY, Messages::TWMKey, CMDialogKey);
END_MESSAGE_MAP(TForm)
};
| 固定リンク
switch文のcaseでローカル変数を以下のように使おうとすると、「caseでローカル変数の初期化がとばされた」というようなエラーメッセージが表示されてしまいます。
switch (Value) {
case 0:
int i=0;
:
break;
default:
:
break;
}
このようなことをしたいときは時は次のようにcaseの中をブレースで括ります。
switch (Value) {
case 0:
{
int i=0;
:
break;
}
default:
:
break;
}
ウインドウの一覧を得るEnumWindowsというAPIがありますが、C++Builder6.0でこの関数を使用すると以下のようなエラーがでる場合があるようです。
----
E2034 'int (__stdcall *)(void *,long)'型は'int (__stdcall *)()'型に変換できない
E2342 パラメータ 'EnumWndProc' は int (__stdcall *)() 型として定義されているので int (__stdcall *)(void *,long) は渡せない
----
以下のように強制的にキャストをかけてしまえばコンパイルできるようになります。きちんと意図した動作もしているようです。
//関数の定義
BOOL CALLBACK EnumWndProc(HWND hWindow,LPARAM lData)
{
:
}
//呼び出し
EnumWindows((WNDENUMPROC)EnumWndProc,0);
Mutexを使用して、アプリケーションの2重起動を禁止する方法です。「プロジェクト」-「ソース表示」で表示されるファイルに以下のようなコードを追記します。
=====
#define MUTEX_ID "Unique_ID_String" //適当な文字列を設定
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
HANDLE hMutex=NULL;
//2重起動のチェック
//Mutexを作成してみる
hMutex = CreateMutex(NULL, true, MUTEX_ID);
if (hMutex!=NULL) {
if (GetLastError()==ERROR_ALREADY_EXISTS) { //すでに起動されている
CloseHandle(hMutex); // 閉じる
ReleaseMutex(hMutex);// 破棄する
//すでに起動済みの画面を探して前面に持ってくる処理などを書く
return 0; //終了
}
} else {
//Mutexの作成に失敗したときの処理
}
//この辺はもともと書かれている部分
Application->Initialize();
:
Application->Run();
//最後に後始末
CloseHandle(hMutex); // 閉じる
ReleaseMutex(hMutex); //ミューテクス解除
}
catch (Exception &exception)
{
Application->ShowException(&exception);
:
return 0;
}
BCBでWindowsのメッセージを捕まえて処理をする場合の書き方です。
class TForm1 : public TForm
{
:
private:
//実際にメッセージを処理する関数の宣言
//関数の中身はソースに自分で書く
void __fastcall WMDropFile(TWMDropFiles &Msg);
BEGIN_MESSAGE_MAP
//捕まえたいメッセージと、それを処理する関数を登録
VCL_MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFile)
END_MESSAGE_MAP(TComponent)
};
引数に指定されたディレクトリが存在するかを調べる関数です。ユニコードファイル名に対応しています。
bool __fastcall DirectoryExistsW(WideString WFilename)
{
WIN32_FIND_DATAW FindFileData;
HANDLE hFind;
hFind = FindFirstFileW(WFilename.c_bstr(), &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
// 検索ハンドルをクローズ
FindClose(hFind);
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) return true;
}
return false;
}
引数に指定されたファイル名(ディレクトリも含む)が存在するかを調べる関数です。ユニコードファイル名に対応しています。
bool __fastcall FileExistsW(WideString WFilename)
{
WIN32_FIND_DATAW FindFileData;
HANDLE hFind;
hFind = FindFirstFileW(WFilename.c_bstr(), &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
// 検索ハンドルをクローズ
FindClose(hFind);
return true;
}
return false;
}
システムメニューやボタンなどで使用されるフォントを取得する方法です。以下は、システムのGUIで使用されるフォントを取得する例です。
void __fastcall TForm1::FormCreate(TObject *Sender)
{
HFONT hFont;
TLogFont LogFont;
hFont=GetStockObject(DEFAULT_GUI_FONT);
GetObject(hFont,sizeof(LogFont),&LogFont);
}
DEFAULT_GUI_FONTの部分には、以下の値を指定することもできます。
OEM_FIXED_FONT = 10;
ANSI_FIXED_FONT = 11;
ANSI_VAR_FONT = 12;
SYSTEM_FONT = 13;
DEVICE_DEFAULT_FONT = 14;
DEFAULT_PALETTE = 15;
SYSTEM_FIXED_FONT = 16;
DEFAULT_GUI_FONT = 17;
Form上のコンポーネントのうち、ある特定のクラスから派生しているものだけに対して処理をしたい場合に使えるテクニックです。以下は、TControlから派生したクラスに対してのみ処理をする場合の例です。
for (int i=0;i<ComponentCount;i++) {
if (Components[i]->InheritsFrom(__classid(TControl))) {
TControl *Ctrl=(TControl *)Components[i];
//何か処理をする
}
}
TRect WorkAreaRect;
SystemParametersInfo( SPI_GETWORKAREA, 0, &WorkAreaRect, 0 );
manifestファイルを使うと、アプリケーションの外観を簡単にWindowsXPのスタイルにすることができます。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="CompanyName.ProductName.YourApp"
type="win32" />
<description>Description</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*" />
</dependentAssembly>
</dependency>
</assembly>
これを、○○.exe.manifestという名前のファイルに保存します。このとき文字コードはUTF-8にします。○○の部分は実行ファイルの名前を入れます。このファイルを実行ファイルと同じ場所においておけばOKです。
Delphi5の場合は、PageControlなど一部のコンポーネントは、うまくスタイルが変更されません。これらに対応したコンポーネントを作られている方もいるようです。
[ヘッダ]
class TMyTrackBar: public TTrackBar
{
public:
__fastcall TMyTrackBar(TComponent* Owner);
void __fastcall CreateParams(TCreateParams &Params);
};
[ソース]
//
マイクロソフトのホームページからダウンロードできるHTML Help WorkshopにはプログラムからHTML Helpを扱うためのライブラリファイル(htmlhelp.lib)が付属していますが、BCBではそのまま使うことはできません。次のようにしてhhctrl.ocxからBCB用のライブラリファイルを作成します。
implib htmlhelp.lib hhctrl.ocx
BCBのプロジェクトに、作成したhtmlhelp.libと、Workshopに付属しているヘッダファイルhtmlhelp.hを追加します。
FormのOnCreateとOnCloseに下記のようなコードを書きます。
//
ListViewのコラムをクリックした時に、その列をキーに内容をソートする方法です。ListViewのViewStyleはvsReport、ShowColumnHeaderはtrueに設定されているとします。
クリックされた列の番号を保持しておく変数を用意しておきます。
:
private
int FColumnToSort;
:
};
ListViewのOnColumnClickとOnCompareを使います。またTagプロパティは、コラムをクリックするたびに、ソートの方向(昇順か降順か)を反転するために使っています。
void __fastcall TForm1::ListView1ColumnClick(TObject *Sender,
TListColumn *Column)
{
FColumnToSort = Column->Index;
((TCustomListView *)Sender)->AlphaSort();
//ソートの方向を切り替える 昇順、降順
if (FColumnToSort==0)
ListView1->Tag=(ListView1->Tag==1)?0:1;
else
ListView1->Columns->Items[FColumnToSort-1]->Tag=
(ListView1->Columns->Items[FColumnToSort-1]->Tag==1)?0:1;
}
//
相対パスから絶対パスへの変換はExpandFileName。
絶対パスから相対パスへの変換はExtractRelativePath。
これらの関数を使用する前には、SetCurrentDirでベースとなるディレクトリを設定する必要がある。
AnsiString AppDir=ExtractFilePath(Application->ExeName);
if (SetCurrentDir(AppDir)) {
Label1->Caption=ExpandFileName("../../test.txt");
}
TSplitterにおいてAutoSnapをTrueにすると、コンポーネントのサイズがMinSize以下となったときにサイズを0にしてくれます。このSnapされた状態で起動する方法です。
Panel1を見えない状態で起動する例です。
Panel1->Height=1;
Splitter1->Perform(WM_LBUTTONDOWN,0,0);
Splitter1->Perform(WM_MOUSEMOVE,MK_LBUTTON|MK_MBUTTON,0);
Splitter1->Perform(WM_LBUTTONUP,0,0);
BCB6.0には最初からIndyがインストールされていますが、それをIndy9にバージョンアップする方法です。
最初にインストールを試みたときは、「プロシージャエントリポイント Idresourcestrings@_RSBindingAnyがダイナミックリンクライブラリIndy60.bplから見つかりませんでした。」というエラーがでてパッケージがインストールできず苦労しましたが、下記のとおりの順番でやり直したところうまくいきました。
前準備(BCBのアップデート)
(1) ボーランドのページからBorland C++Builder 6 アップデートパック #4をダウンロード。すでにインストール済みの場合はスキップ。
(2) アップデートパックをインストールする。
古いIndyのアンインストール
(3) コントロールパネルから「プログラムの追加と削除」を起動。
(4) その中から「Borland C++Builder 6」を選択して「変更」をクリック。インストールCDROMを求められた場合はCDROMを挿入。
(5) 表示された機能一覧の中から「Indy」を探して、「インストールしない」にして「次へ、次へ」。
(6) 残っているゴミの削除。以下はIndyのサイトに書いてあった情報。
(6-1) $(BCB)フォルダ以下から「IDPAS32.obj」というファイルを検索していったん、デスクトップなどに移動する。BCB6.0なら $(BCB)\Source\vcl内に見つかると思います。
(6-2) $(BCB)フォルダ以下から「dclindy*.bpl, dclindy.*, dclindy*.bpl, indy*.lib, id*.pas, id*.hpp, id*.obj, id*.dcu」を検索して削除。Indy関連ではないファイルを間違えて削除しないように注意。検索するときは「」内の文字列をそのままWindowsの検索画面の「ファイル名のすべてまたは一部」の欄に入力して検索すればOK。
(6-2) C:\Windows\System32以下の「indy*.bpl」を検索して削除。
(6-3) $(BCB)\Help以下から「indy.*」を検索して削除。
(6-4) 6-1で移動しておいたIDPAS32.objを元の場所に戻す。
新しいIndyのダウンロードとインストール
(7) Indyのページからソースをダウンロード。WindowsはZipで配布されている。
(8) ダウンロードしてきたファイルを展開。展開して出てきたフォルダを、適当なフォルダを新規に作ってその中に移動する。
(9) 展開したフォルダの中にある「Fullc6.bat」を実行。DOSの画面が消えるまで待つ。実行が終わるとひとつ上のフォルダに「C6」というフォルダができている。
(10) 「C6」フォルダの中身を「$(BCB)\Source\Indy」にまるごとコピー。
(11) 「C6」フォルダの「dclIndy60.bpl」を「$(BCB)\bin」にコピー。
(12) 「C6」フォルダの「hpp」という拡張子のファイルを全部「$(BCB)\Include」にコピー。
(13) BCBを起動する。
(14) 「ツール」-「環境オプション」で表示されるダイアログで、「ライブラリ」タブを選択。「ライブラリパス」に「$(BCB)\Source\Indy」を追加して「OK」でダイアログを閉じる。
(15) 「コンポーネント」-「パッケージのインストール」。「追加」ボタンを押して「$(BCB)\bin\dclIndy60.bpl」を選択。チェックがついていることを確認して「OK」を押すとパレットに新しいIndyコンポーネントが追加される。
Indyヘルプファイルの更新
(16) Indyのページから新しいヘルプファイルをダウンロード。何種類が形式が用意されているが、元のと同じWinHelp形式を選択。
(17) ダウンロードしたファイルを展開。
(18) 展開したフォルダの中にあるファイルを丸ごと「$(BCB)\Help」にコピー。
インストールはこれで完了。
もともと古いバージョンのIndyを使っていたプロジェクトをコンパイルする場合は、そのままだとエラーが出る。プロジェクトファイル(例:Project1.bpr)をメモ帳などで開き、「Indy.lib」と「Indy.bpi」という文字列を検索して削除してから改めてコンパイルしなおすとうまくいく。
電光掲示板の文字のようにスクロールするラベルです。 Form上にLabelとTimerをひとつずつ置きます。
スクロールさせたい文字列はCaptionStringという内部変数に入れておきます。TimerのIntervalは200くらいにしておきます。
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static int x=Label1->Width;
RECT r;
int w;
r.left=0;
r.top =0;
r.right=Label1->Width;
r.bottom=Label1->Height;
w=Label1->Canvas->TextWidth(CaptionString);
if (w+x<0) X=Label1->Width;
Label1->Canvas->Brush->Color=Label1->Color;
Label1->Canvas->Brush->Style=bsSolid;
Label1->Canvas->FillRect(r);
Label1->Canvas->TextRect(r,X,1,CaptionString);
Label1->Update();
x=x-10;//移動量
}
プロジェクトのソースファイルを以下のように書き換えます。ソースファイルは「プロジェクト」-「ソース表示」で表示できます。
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
//タスクバーからアイコンを消す
ShowWindow(Application->Handle, SW_HIDE);
SetWindowLong(Application->Handle, GWL_EXSTYLE,
GetWindowLong(Application->Handle, GWL_EXSTYLE) | WS_EX_TOOLWINDOW);
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
:
以下はStringGridで列を指定してソートする手続きです。1つ目の引数にはソートするStringGridを、2つ目の引数には何列目でソートするかを指定します。なお、以下の例ではデータを文字列としてソートしていますが、データを比較するif文を書き換えれば数値としてソートすることも可能です。その場合は、比較する2つデータをStrToIntなどで整数に直してから比較することになります。
void __fastcall TForm1::StringGridSort(TStringGrid *Grid, int SortCol)
{
for (int i=Grid->FixedRows;i
for (int j=Grid->RowCount-1;j>i;j--) {
if (Grid->Cells[SortCol][j-1]>Grid->Cells[SortCol][j]) {//データを比較
//2つの行を入れ替える
AnsiString TmpStr=Grid->Rows[j-1]->CommaText;
Grid->Rows[j-1]->CommaText=Grid->Rows[j]->CommaText;
Grid->Rows[j]->CommaText=TmpStr;
}
}
}
}
この手続きはバブルソートという方法を使っています。時間のかかるソート法ですので行数が多くなると固まったようになるかもしれません。
StringGridで、一番上の行につくったFixedRowがクリックされたときに、クリックされた列をキーにしてデータをソートしたいということがあります。マウスクリックされた場所が、何行、何列のセルなのかは以下のようにして取得することができます。
void __fastcall TSentenceSimForm::StringGrid1MouseUp(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
int ARow,ACol;
StringGrid1->MouseToCell(X,Y,ACol,ARow);
//AColに列、ARowに行番号が格納される
if (ARow!=0) return; //クリックされたのが一番上の行じゃなかったらreturn
else StringGridSort(ACol); //ACol列でソート
}
上の例のStringGridSortは自分で定義する必要があります。
入力されたバイナリデータをBase64エンコードする関数です。引数Bufには入力データ列を、Lengthにはその長さを指定します。エンコードの結果はAnsiString型の文字列で返されます。
AnsiString __fastcall Encode64(Byte *Buf,int Length)
{
char *Codes64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int Byte3=0;
AnsiString Result="";
for (int i=0;i<Length;i++) {
Byte3=(Byte3<<8)+(int)Buf[i];
if ((i+1)%3==0) {
Result=Result+Codes64[(Byte3>>18)&0x3F];
Result=Result+Codes64[(Byte3>>12)&0x3F];
Result=Result+Codes64[(Byte3>>6 )&0x3F];
Result=Result+Codes64[(Byte3 )&0x3F];
Byte3=0;
}
}
int Rest=Length%3;
switch (Rest) {
case 1:
Byte3=Byte3<<4;
Result=Result+Codes64[(Byte3>>6 )&0x3F];
Result=Result+Codes64[(Byte3 )&0x3F];
Result=Result+"==";
break;
case 2:
Byte3=Byte3<<2;
Result=Result+Codes64[(Byte3>>12)&0x3F];
Result=Result+Codes64[(Byte3>>6 )&0x3F];
Result=Result+Codes64[(Byte3 )&0x3F];
Result=Result+"=";
break;
}
return Result;
}
フォームの状態を調べるにはWindowStateプロパティを使用します。
{
switch (Form1->WindowState) {
case wsMaximized:
//最大化されている
break;
case wsMinimized:
//最小化されている
break;
case wsNormal:
//どちらでもない
break;
}
}
ヘッダ
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Windows.hpp>
class TSysOSVersionInfo
{
private:
AnsiString FProductID;
AnsiString FProductName;
DWORD FServicePackVersion;
DWORD FVersionMajor;
DWORD FVersionMinor;
DWORD FVersionBuild;
AnsiString FCSDVersion;
bool FIsWinNT;
public:
__fastcall TSysOSVersionInfo(void);
__fastcall ~TSysOSVersionInfo(void);
__property AnsiString ProductID={read=FProductID};
__property AnsiString ProductName={read=FProductName};
__property AnsiString ProductType={read=FProductType};
__property DWORD ServicePackVersion={read=FServicePackVersion};
__property DWORD VersionMajor={read=FVersionMajor};
__property DWORD VersionMinor={read=FVersionMinor};
__property DWORD VersionBuild={read=FVersionBuild};
__property AnsiString CSDVersion={read=FCSDVersion};
};
#endif
ソース
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#include <windows.h>
#include <Registry.hpp>
//---------------------------------------------------------------------------
__fastcall TSysOSVersionInfo::TSysOSVersionInfo(void)
{
TSystemInfo SystemInfo;
memset(&SystemInfo, 0x00, sizeof(SystemInfo));
GetSystemInfo(&SystemInfo);
FIsWinNT = (Win32Platform == VER_PLATFORM_WIN32_NT);
//ProductID,ProductName
TRegistry *Reg=new TRegistry(KEY_READ);
try {
bool Res;
Reg->RootKey=HKEY_LOCAL_MACHINE;
if (FIsWinNT) Res=Reg->OpenKeyReadOnly("Software\\Microsoft\\Windows NT\\CurrentVersion");
else Res=Reg->OpenKeyReadOnly("Software\\Microsoft\\Windows\\CurrentVersion");
if (Res) {
FProductID=Reg->ReadString("ProductID");
FProductName=Reg->ReadString("ProductName");
}
Reg->CloseKey();
} __finally {
delete Reg;
}
FVersionMajor=Win32MajorVersion;
FVersionMinor=Win32MinorVersion;
FVersionBuild=Win32BuildNumber;
FCSDVersion=Win32CSDVersion;
}
//---------------------------------------------------------------------------
__fastcall TSysOSVersionInfo::~TSysOSVersionInfo(void)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TSystemTime STime,LTime;
TIME_ZONE_INFORMATION TzInfo;
//タイムゾーン情報を取得
GetTimeZoneInformation( &TzInfo );
//現在のシステム時刻(UTC)を取得
GetSystemTime(&STime);
//タイムゾーン情報を使ってローカルタイムに変換
SystemTimeToTzSpecificLocalTime(&TzInfo,&STime,<ime);
//結果を表示
AnsiString Str;
Str.printf("%02d:%02d:%02d",LTime.wHour,LTime.wMinute,LTime.wSecond);
Label1->Caption=Str;
}
TSystemTimeをTDateTime型に変換
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime DateTime;
TSystemTime SystemTime;
GetLocalTime(&SystemTime);
//変換
DateTime=SystemTimeToDateTime(SystemTime);
}
TDateTimeをTSystemTimeに変換
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TDateTime DateTime;
TSystemTime SystemTime;
DateTime=Now();
//変換
DateTimeToSystemTime(DateTime,&SystemTime);
}
GetSystemTimeを使用します。引数にはTSystemTime構造体へのポインタを指定します。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TSystemTime Stime;
GetSystemTime(&Stime);
AnsiString Str;
Str.printf("%d/%d/%d",Stime.wYear,Stime.wMonth,Stime.wDay);
Lable1->Caption=Str;
}
TSystemTime構造体には次の値が格納されます。
| wYear | 年 |
| wMonth | 月 |
| wDayOfWeek | 曜日(日:0、月:1、..、土:6) |
| wDay | 日 |
| wHour | 時 |
| wMinute | 分 |
| wSecond | 秒 |
| wMilliseconds | ミリ秒 |
なお、ローカル時間はGetLocalTimeで取得することができます。
TColorをR,G,Bの値に分解する関数です。
void TColor2RGB(TColor Color, Byte &R, Byte &G, Byte &B)
{
int RGB=ColorToRGB(Color);
R=RGB&0xFF;
G=(RGB>>8)&0xFF;
B=(RGB>>16)&0xFF;
}
MessageBeepを使うと、コントロールパネルの[サウンド]で設定された音を鳴らすことができます。引数には音の種類を指定します。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MessageBeep(MB_ICONASTERISK);
}
指定できる音の種類
| 0xFFFFFFFF | 標準のビープ音 |
| MB_ICONASTERISK | システム 情報 |
| MB_ICONEXCLAMATION | システム 警告 |
| MB_ICONHAND | システム エラー |
| MB_ICONQUESTION | システム 問い合わせ |
| MB_OK | デフォルトの警告音 |
LoadIconを使用すると、システムで使用されるアイコン(MessageDialogなどに表示されるエラーや警告のアイコンなど)を取得できます。
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//Image1にエラーのアイコンを表示
Image1->Picture->Icon->Handle = LoadIcon(0, IDI_HAND);
}
他にも以下のような値を指定できます。
| IDI_APPLICATION |
| IDI_HAND |
| IDI_QUESTION |
| IDI_EXCLAMATION |
| IDI_ASTERISK |
| IDI_WINLOGO |
ファイル名の拡張子を変更するにはChangeFileExt関数を使います。
#include <SysUtils.hpp>
//拡張子を取得
Filename="C:\\tmp\\test.ini";
Result=ChangeFileExt(Filename,".htm");
引数には元のファイル名と拡張子を「.」を含めた形で指定します。上の例の場合、Resultは「C:\tmp\test.htm」となります。
ChangeFileExt(Filename,"");
のようにすると拡張子を取り除くこともできます。
| 固定リンク
ファイルの拡張子を取得するにはExtractFileExt関数を使います。
#include <SysUtils.hpp>
//拡張子を取得
Filename="C:\\tmp\\test.ini";
FileExt=ExtractFileExt(Filename);
関数を実行すると変数FileExtには、拡張子が「.」を含めた形で格納されます。上の例の場合はFileExtの内容は「.ini」となります。
拡張子がない場合は空の文字列が返されます。
| 固定リンク
ダイアログを動的に作成する方法です。以下はTSaveDialogの例です。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TSaveDialog *Dlg;
Dlg=new TSaveDialog(this);
//フィルタを設定
Dlg->Filter="テキストファイル(*.txt)|*.txt|HTMLファイル(*.htm)|*.htm|すべてのファイル|*.*";
//オプションを設定
Dlg->Options=Dlg->Options<<ofOverwritePrompt<<ofPathMustExist;
Dlg->FileName="list.txt";
if (Dlg->Execute()) {
//処理をする
}
delete Dlg;
}
| 固定リンク
Delphiにはwith文を使って、長いコードを省略することができます。例えば以下のようです。
with Form1.Image1.Picture.Bitmap.Canvas do begin
MoveTo(0,0);
LineTo(1,1);
end;
BCBでも使いたいところですが残念ながらBCBにはwith文はありません。その代わりに次のようにして書くことができます。
TCanvas *Canvas=Form1->Image1->Picture->Bitmap->Canvas;
Canvas->MoveTo(0,0);
Canvas->LineTo(1,1);
TScreenのFormCountおよびFormsを使用します。
//ListBoxにFormの名前を一覧表示
for (int i=0;i<Screen->FormCount;i++) {
TForm* Form=Screen->Forms[i];
ListBox1->Items->Add(Form->Name);
}
| 固定リンク
CheckBox1->Checked=Memo1->Font->Style.Contains(fsBold);
CheckBox2->Checked=Memo1->Font->Style.Contains(fsItalic);
CheckBox3->Checked=Memo1->Font->Style.Contains(fsUnderline);
GraphicFilter、GraphicExtensionを使うと画像ファイルに対応したフィルタ文字列、拡張子が取得できます。
OpenDialog1->DefaultExt = GraphicExtension(__classid(Graphics::TBitmap));
OpenDialog1->Filter = GraphicFilter(__classid(Graphics::TBitmap));
TBitmap以外に、Ticon、TMetafile、TGraphicが指定できます。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TOpenDialog *Dlg=new TOpenDialog(this);
//オプションを設定
Dlg->Options.Clear();
Dlg->Options<<ofFileMustExist<<ofPathMustExist;
if (Dlg->Execute()) {
//なにかの処理
}
delete Dlg;
}
CreateDirでディレクトリ(フォルダ)が作成できます。深い階層のディレクトリを作成する場合は、親ディレクトリを順番に作っていく必要があります。この場合は、後述のForceDirectoriesを使うと便利です。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString DirName = "C:\tmp\\test\\aaal";
if (CreateDir(DirName)) {
//作成に成功
}
}
ForceDirectoriesを使うと深い階層のディレクトリをまとめて作成できます。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString DirName = "C:\tmp\\test\\aaal";
if (ForceDirectories(DirName)) {
//作成に成功
}
}
UINT GetTempFileName(
LPCTSTR lpPathName, // ディレクトリ名
LPCTSTR lpPrefixString, // 一時ファイル名の接頭辞
UINT uUnique, // 整数
LPTSTR lpTempFileName // 一時ファイル名を格納するバッファ
);
lpPrefixStringとuUniqueに基づいて一時ファイル名が作成される。
uUniqueに0を指定した場合は、システム時刻が使用され、実際にファイルが作成される。
uUniqueに0以外を指定すると、ファイル名だけが作られる。ファイル名が一意かどうかも保証されない。
| 固定リンク
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TSearchRec Sr;
int Attributes = faAnyFile; //検索対象とするファイルの属性
if (FindFirst("C:\\tmp\\*.*", Attributes, Sr) == 0) {
do {
if ((sr.Attr & Attributes) == Sr.Attr) {
ListBox1->Items->Add(Sr.Name);
//Sr.Sizeでファイルのサイズを取得できる
}
} while (FindNext(Sr) == 0);
FindClose(Sr);
}
}
ファイルの属性に設定できる値。ORでつないで指定する。
| faReadOnly | 書き込み禁止ファイル |
| faHidden | 隠しファイル |
| faSysFile | システムファイル |
| faVolumeID | ボリュームファイル |
| faDirectory | ディレクトリ |
| faArchive | アーカイブ |
| faAnyFile | すべてのファイル |
関連付けられたアプリで開く
ShellExecute(NULL, "open", Filename.c_str(), NULL, NULL, SW_SHOWNORMAL);
*openのほかにもprintとかも使える
アプリを指定して開く
ShellExecute(NULL, NULL, "notepad.exe", Filename.c_str(), NULL, SW_SHOWNORMAL);
//---------------------------------------------------------------------------
void __fastcall TForm1::LinkLabelMouseEnter(TObject *Sender)
{
((TLabel *)Sender)->Font->Color=clRed;
((TLabel *)Sender)->Font->Style=TFontStyles() << fsUnderline;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::LinkLabelMouseLeave(TObject *Sender)
{
((TLabel *)Sender)->Font->Color=clNavy;
((TLabel *)Sender)->Font->Style=TFontStyles();
}
//---------------------------------------------------------------------------
#include <System.hpp>
#include <IdWinsock.hpp>
//-----------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
WORD wVersionRequested;
TWSAData wsaData;
wVersionRequested = MAKEWORD(1,1);
WSAStartup(wVersionRequested,&wsaData);
}
//-----------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
WSACleanup;
}
//-----------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char Buf[256];
PHostEnt p;
p=gethostbyname(Buf);
//IPアドレス
Label1->Caption=(inet_ntoa)(*((PInAddr)p->h_addr_list[0]));
//ローカルホスト名
Label2->Caption=p->h_name;
}
//-----------------------------------------------------------------
y年m月d日の曜日(日曜が0、...、土曜が6)を求める方法です。
1月、2月は前年の13月、14月として計算します。
begin
if (m = 1) or (m = 2) then begin
y:=y-1;
m:=m+12;
end;
Result:=(y + (y div 4) - (y div 100) + (y div 400) +((13*m+8) div 5) + d) mod 7;
end;
この式はZellerの公式というものです。
1582年10月15日(グレゴリオ暦施行日)以前については有効ではありませんのでご注意ください。
タスクバーを閉じるとシャットダウンのダイアログが表示されます。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HWND hWnd;
hWnd=FindWindow("Shell_TrayWnd", NULL); //タスクバーのハンドルを取得
SendMessage(hWnd, WM_CLOSE, 0, 0);
}
以下のようにするとProgressBarのバーの部分の色が変えられます。
#include <CommCtrl.h>
void __fastcall TForm1::FormCreate(TObject *Sender)
{
SendMessage(ProgressBar1->Handle, PBM_SETBARCOLOR, 0, clTeal);
//SendMessage(ProgressBar1->Handle, PBM_SETBARCOLOR, 0, RGB(255,0,0));
}
C++Builder 6.0 の場合は、以下の場所にあります。
$(BCB)/Help/index.html
*$(BCB)はC++Builderをインストールしたフォルダの意味です。
通常は子画面の×ボタンを押しても最小化されるだけで消えません。
本当に閉じたい場合は、OnCloseの中に次の一行を書きます。
Action = caFree;
BCBで使用できる32ビットのデータ型とサイズ
| 型 | バイト | 範囲 |
| unsigned char | 1 | 0 ≦ X ≦ 255 |
| char | 1 | -128 ≦ X ≦ 127 |
| short int | 2 | -32,768 ≦ X ≦ 32,767 |
| unsigned int | 4 | 0 ≦ X ≦ 4,294,967,295 |
| int | 4 | -2,147,483,648 ≦ X ≦ 2,147,483,647 |
| enum | 4 | -2,147,483,648 ≦ X ≦ 2,147,483,647 |
| unsigned long | 4 | 0 ≦ X ≦ 4,294,967,295 |
| long | 4 | -2,147,483,648 ≦ X ≦ 2,147,483,647 |
| float | 4 | 1.18 * 10^-38 < |X| < 3.40 * 10^38 |
| double | 8 | 2.23 * 10^-308 < |X| < 1.79 * 10^308 |
| long double | 10 | 3.37 * 10^-4932 < |X| < 1.18 * 10^4932 |
SHFILEINFO shfi;
SHGetFileInfo(Filename.c_str(), FILE_ATTRIBUTE_ARCHIVE, &shfi,
sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_LARGEICON | SHGFI_TYPENAME);
Image1->Picture->Icon->Handle=shfi.hIcon;
Delphi で作成した関数を C++Builder で使用するには pas ファイルから objファイルと hppファイル を生成する必要があります。一度、pasファイルをプロジェクトに加え、「コンパイル」するとこれらのファイルが作成されますので、必要な箇所でhppファイルをインクルードします。
TIcon *Icon;
Icon=new TIcon;
Icon->LoadFromFile(LoadFilename);
Bmp->Width=Icon->Width;
Bmp->Height=Icon->Height;
Bmp->Canvas->Draw(0,0,Icon);
delete Icon;
関数型を __closure という指定をつけてtypedefします。
typedef void __fastcall (__closure *TMyEvent)(int State);
class TMyClass
{
private:
TMyEvent *FOnMyEvent;
:
public:
__property TMyEvent *OnMyEvent={read=FOnMyEvent, write=FOnMyEvent};
:
};
AnsiStringをchar *に代入したいときは、c_str() を使用します。
char *dest;
AnsiString src="test";
//dest=src; これはエラーになる
dest=src.c_str();
c_str() を使う際の注意点。
AnsiString::c_str() は一時的な領域をを指すポインタを返します。このポインタは,それが使われている文の実行が終了すると不定になってします。 そのため、 c_str() が指す領域を変更するような処理をしてはいけません。
char *buf=NULL;
buf=new char[1024];
/* bufを使った処理 */
delete [] buf;
確保した配列を解放するときに[ ]を付け忘れると、配列の最初の要素だけが解放されることになります。書き忘れないように注意しましょう。
| 定数名 | 説明 |
| CHAR_MIN | char型の最小値 |
| CHAR_MAX | char型の最大値 |
| UCHAR_MAX | unsigned char型の最大値 |
| SHRT_MIN | short型の最小値 |
| SHRT_MAX | short型の最大値 |
| USHRT_MAX | unsigned short型の最大値 |
| LONG_MIN | long型の最小値 |
| LONG_MAX | long型の最大値 |
| ULONG_MAX | unsigned long型の最大値 |
| INT_MIN | int型の最小値 |
| INT_MAX | int型の最大値 |
| UINT_MAX | unsigned int型の最大値 |
デフォルトの設定でプロジェクトをコンパイルすると、別のパソコンにexeファイルだけをコピーしてもファイルが足りないと言われて実行できないことがある。exeだけで実行できるようにコンパイルするには、
「プロジェクト」-「オプション」で
「パッケージ」タブの「実行時パッケージを使って構築」のチェックを外す
「リンカ」タブの「共有RTL DLLを使う」のチェックを外す
void GetFileVersionInformation(char *Result,int Size)
{
LPVOID lpStr1 = NULL;
LPVOID lpStr2 = NULL;
WORD* wTmp;
DWORD dwHandle_dammy = NULL;
UINT nRet;
UINT dwLength;
char sFileName[1024];
char sTmp[1024];
char *sInfo;
if ((Result==NULL) || (Size==0)) return;
memset(sFileName,0x00,1024);
GetModuleFileName(NULL,sFileName,1024);
//バージョン情報のサイズを取得する
DWORD dwInfoSize = GetFileVersionInfoSize((char*)(LPCTSTR)sFileName, &dwHandle_dammy);
LPVOID* pVersionInfo = new LPVOID[dwInfoSize];
nRet = GetFileVersionInfo((char*)(LPCTSTR)sFileName, dwHandle_dammy, dwInfoSize, pVersionInfo);
if(nRet){
//言語IDとキャラクタIDを取得する
nRet = VerQueryValue(pVersionInfo, "\\VarFileInfo\\Translation", &lpStr1, &dwLength);
if(nRet){
wTmp = (WORD*)lpStr1;
//バージョン情報を取得する
StringCbPrintfA(sTmp,1024,"\\StringFileInfo\\%04x%04x\\FileVersion", *wTmp, *(wTmp + 1));
nRet = VerQueryValue(pVersionInfo, sTmp, &lpStr2, &dwLength);
if(nRet) sInfo = (char*)lpStr2;
else sInfo = "";
strncpy(Result,sInfo,Size-1);
} else {
strncpy(Result,"",Size-1);
}
} else {
strncpy(Result,"",Size-1);
}
delete[] pVersionInfo;
}
=====
AnsiString 版
AnsiString GetFileVersionInformation(void)
{
LPVOID lpStr1 = NULL;
LPVOID lpStr2 = NULL;
WORD* wTmp;
DWORD dwHandle_dammy = NULL;
UINT nRet;
UINT dwLength;
AnsiString sTmp;
AnsiString sInfo;
AnsiString Result="";
//バージョン情報のサイズを取得する
DWORD dwInfoSize = GetFileVersionInfoSize(Application->ExeName.c_str(), &dwHandle_dammy);
LPVOID* pVersionInfo = new LPVOID[dwInfoSize];
nRet = GetFileVersionInfo(Application->ExeName.c_str(), dwHandle_dammy, dwInfoSize, pVersionInfo);
if(nRet){
//言語IDとキャラクタIDを取得する
nRet = VerQueryValue(pVersionInfo, "\\VarFileInfo\\Translation", &lpStr1, &dwLength);
if(nRet){
wTmp = (WORD*)lpStr1;
//バージョン情報を取得する
sTmp.sprintf("\\StringFileInfo\\%04x%04x\\FileVersion", *wTmp, *(wTmp + 1));
nRet = VerQueryValue(pVersionInfo, sTmp.c_str(), &lpStr2, &dwLength);
if(nRet) Result = (char*)lpStr2;
else Result = "-";
} else {
Result="-";
}
} else {
Result="-";
}
delete[] pVersionInfo;
return Result;
}
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
FClientWndProc = MakeObjectInstance(ClientWndProc);
if (FClientWndProc != NULL)
FOrgWndProc = (void *)SetWindowLong(ClientHandle, GWL_WNDPROC,Longint(FClientWndProc));
}
//---------------------------------------------------------------------------
__fastcall TMainForm::~TMainForm(void)
{
if (FOrgWndProc != NULL)
SetWindowLong(ClientHandle, GWL_WNDPROC, Longint(FOrgWndProc));
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ClientWndProc(TMessage &Msg)
{
switch (Msg.Msg) {
case WM_NCCALCSIZE:
// スクロールバーを消す
ShowScrollBar(ClientHandle, SB_BOTH, false);
Msg.Result = CallWindowProc((FARPROC)FOrgWndProc, ClientHandle,Msg.Msg, Msg.WParam, Msg.LParam);
break;
default:
Msg.Result = CallWindowProc((FARPROC)FOrgWndProc, ClientHandle,Msg.Msg, Msg.WParam, Msg.LParam);
break;
}
}
ヘッダ
class TMainForm : public TForm
{
:
private:
TRect FMaximizedRect;
// メッセージハンドラ
void _fastcall WMGetMinMaxInfo(TWMGetMinMaxInfo &Msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_GETMINMAXINFO, TWMGetMinMaxInfo, WMGetMinMaxInfo)
END_MESSAGE_MAP(TForm)
:
};
ソース
void _fastcall TMainForm::WMGetMinMaxInfo(TWMGetMinMaxInfo &Msg)
{
//最大化したときのFormのサイズを取得
FMaximizedRect.Top=0;
FMaximizedRect.Left=0;
FMaximizedRect.Right=Msg.MinMaxInfo->ptMaxSize.x;
FMaximizedRect.Bottom=Msg.MinMaxInfo->ptMaxSize.y;
/* その他、取得できる値
//最大化の時のポジション
Msg.MinMaxInfo.ptMaxPosition.x , Msg.MinMaxInfo.ptMaxPosition.y
//最小サイズ
Msg.MinMaxInfo.ptMinTrackSize.x , Msg.MinMaxInfo.ptMinTrackSize.y
//最大サイズ
Msg.MinMaxInfo.ptMaxTrackSize.x , Msg.MinMaxInfo.ptMaxTrackSize.y
*/
}
設定値を取得するだけでなく、逆に値を設定することもできるので最大化したときのサイズを変えたりもできる。
C++Builder | C++言語・Pascal言語 | Delphi | TActionList | TColor | TEdit | TeX | TForm | TIniFile | TLabel | TListBox | TListView | TMemo | TProgressBar | TSplitter | TStatusBar | TStringGrid | TTrackBar | TWebBrowser | Windows | その他 | アルゴリズム | システム関連 | ネットワーク関連 | ファイル、フォルダの処理 | フォント関連 | フォーム・ダイアログ関連 | フリーソフト | プログラミング全般 | マウス、キーボードの処理 | 文字列の処理 | 日付時刻の処理 | 画像関連 | 開発環境(IDE)関連