HOME > BCB
このページではBCBプログラミングで役立つ(と思われる)テクニックをメモの感覚でまとめていきます。 間違い等のご指摘をいただけると助かります。
以下のようにMutexを設定します。ApplicationTitleはUniqueな名称を適当に設定。
HANDLE mx;
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
//2回起動防止
mx = CreateMutex( NULL, true, "ApplicationTitle" );
if( GetLastError() ){
return 1;
}
try
{
//省略
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
ReleaseMutex( mx );
return 0;
}
//---------------------------------------------------------------------------
ウインドウ名がApplicationTitleのようにわかっている場合はFindWindowを使ってそちらにデータを送ります。
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HWND hWnd=FindWindow(NULL,"ApplicationTitle");
//引数が付いてきたとき、引数を見つけたウインドウへ送る
if(hWnd && ParamCount()>0){
for(int i=1;i<=ParamCount();i++){
char msgbuf[256];
strcpy(msgbuf,ParamStr(i).c_str());
COPYDATASTRUCT cds;
cds.dwData = i;
cds.cbData = strlen(msgbuf);
cds.lpData = (LPVOID)msgbuf;
::SendMessage(hWnd,WM_COPYDATA, NULL ,(LPARAM)&cds);
}
return 1;
}
try
{
//通常の処理
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
//---------------------------------------------------------------------------
//MainUnit.h
Private:
void __fastcall WMCopyData( TMessage &Message );
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, WMCopyData)
END_MESSAGE_MAP(TComponent)
//---------------------------------------------------------------------------
//MainUnit.cpp
void __fastcall TMainForm::WMCopyData( TMessage &Message ){
COPYDATASTRUCT *cds=(PCOPYDATASTRUCT)Message.LParam;
//送られてきた(char*)cds->lpDataを処理
//アプリケーションのウインド状態変更
Application->Restore();
Message.Result=true;
}
//---------------------------------------------------------------------------
以下のようにApplication->ShowMainForm=false;を追加します。
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->Title = "ApplicationTitle";
Application->ShowMainForm=false; //初期に非表示
Application->CreateForm(__classid(TMainForm), &MainForm);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
//---------------------------------------------------------------------------
たとえば以下のように記述します。
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
if (ParamCount() > 0) {
for(int iFile=1;iFile<=ParamCount();iFile++){
String OpenFileName=ExtractLongPathName(ParamStr(iFile));
//ファイルを開く処理
if(FileExists(OpenFileName))OpenDocument(OpenFileName);
}
}
}
//----------------------------------------------------------------------------
String __fastcall TMainForm::ExtractLongPathName(const String &ShortPath)
{
String asTemp=ShortPath;
String asReturn=ExtractLongName(asTemp);
int iDelimiter=asTemp.LastDelimiter("\\");
asTemp=ShortPath.SubString(1,iDelimiter-1);
while((iDelimiter=asTemp.LastDelimiter("\\"))>0){
asReturn=ExtractLongName(asTemp)+"\\"+asReturn;
asTemp=ShortPath.SubString(1,iDelimiter-1);
}
asReturn=asTemp+"\\"+asReturn;
return asReturn;
}
//----------------------------------------------------------------------------
String __fastcall TMainForm::ExtractLongName(const String &ShortPath)
{
WIN32_FIND_DATA FindData;
HANDLE hFindFile = FindFirstFile(ShortPath.c_str(), &FindData);
String LongName = FindData.cFileName ;
CloseHandle(hFindFile);
return LongName;
}
//---------------------------------------------------------------------------
たとえば以下のように設定します。
//---------------------------------------------------------------------
void __fastcall TMainForm::ShowHint(TObject *Sender)
{
StatusBar1->Panels->Items[1]->Text = Application->Hint;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
Application->OnHint = ShowHint;
}
//---------------------------------------------------------------------------
たとえば以下のように記述
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
String DefaultDir=ExtractFilePath(ParamStr(0));
}
たとえば以下のように記述します。
RECT WinRect;
SystemParametersInfo(SPI_GETWORKAREA,0,&WinRect,0);
int iScreenTop=WinRect.top;
int iScreenLeft=WinRect.left;
int iScreenBottom=WinRect.bottom;
int iScreenRight=WinRect.right;
int iScreenHeight=GetSystemMetrics(SM_CYFULLSCREEN);
int iScreenWidth=GetSystemMetrics(SM_CXFULLSCREEN);
MainUnit.hに以下のように記述。
void __fastcall WMEndSession(TMessage &Msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_ENDSESSION,TMessage,WMEndSession)
END_MESSAGE_MAP(TComponent)
MainUnit.cppに処理を記述
//---------------------------------------------------------------------------
void __fastcall TMainForm::WMEndSession(TMessage &Msg)
{
//処理内容
}
//---------------------------------------------------------------------------
たとえば以下のように設定します。
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
COMPCOLOR imecolor[4];
imecolor[0].crText=0x00ff0000;
imecolor[0].crBackground=0x00ffffff;
imecolor[0].dwEffects=CFE_AUTOCOLOR;
imecolor[1].crText=0x00000000;
imecolor[1].crBackground=0x00ffff00;
imecolor[1].dwEffects=CFE_AUTOCOLOR;
imecolor[2].crText=0x00ff0000;
imecolor[2].crBackground=0x00ffffff;
imecolor[2].dwEffects=CFE_AUTOCOLOR;
imecolor[3].crText=0x00ffffff;
imecolor[3].crBackground=0x00ff0000;
imecolor[3].dwEffects=CFE_AUTOCOLOR;
RichEdit1->Perform(EM_SETIMECOLOR,0,(LPARAM)&imecolor);
}
//---------------------------------------------------------------------------
詳しくはEM_SETIMECOLOR参照。
たとえば以下のように記述します。
int iRow=SendMessage(RichEdit1->Handle,EM_LINEFROMCHAR,-1,0)+1;
int iCol=RichEdit1->SelStart
-SendMessage(RichEdit1->Handle,EM_LINEINDEX,-1,0)+1;
たとえば以下のように記述します。
int iFirstVisibleLine=RichEdit1->Perform(EM_GETFIRSTVISIBLELINE,0,0);
int iCurLine=RichEdit1->Perform(EM_LINEFROMCHAR, RichEdit1->SelStart, 0);
int iVisibleLine=RichEdit1->ClientHeight/(RichEdit1->DefAttributes->Height);
int iMoveLine=iCurLine-iVisibleLine/2-iFirstVisibleLine+1;
if(iCurLine>0 || iMoveLine>0)
RichEdit1->Perform(EM_LINESCROLL,0,MoveLine);
たとえば以下のように記述します。これはTListView等でも同様です。
RichEdit1->Lines->BeginUpdate();
//時間のかかる処理
RichEdit1->Lines->EndUpdate();
あるいは、
long mask = SendMessage(RichEdit1->Handle, EM_SETEVENTMASK, 0, 0);
//時間のかかる処理
SendMessage(RichEdit1->Handle, EM_SETEVENTMASK, 0, mask);
AnsiStringの関数を使えば
String asSource;
String asDest=AnsiLowerCase(asSource);
で簡単ですが、地道にやると次のようになります。
String __fastcall TMainForm::ToUpperLowerCase(const String &Str, bool bUpperCase)
{
char* source=Str.c_str();
char* dest=new char[s.Length()+1];
//sourceのポインタ
char* Psource=source;
//destのポインタ
char* Pdest=dest;
while (*P!='\0'){
//一応ダブルバイト文字をチェック
if((*P>=char(0x81) && *P<=char(0x9f))
|| (*P>=char(0xe0) && *P<=char(0xfc))){
*Pdest++=*Psource++;
*Pdest++=*Psource++;
}else if(bUpperCase && *P>='a' && *P<='z'){
*Pdest++=*Psource++ -32;
}else if(!bUpperCase && *P>='A' && *P<='Z'){
*Pdest++=*Psource++ +32;
}else{
*Pdest++=*Psource++;
}
}
*Pdest='\0';
String Str1=String(dest);
delete[] dest;
return Str1;
}
PostMessage(GetDesktopWindow(),WM_SYSCOMMAND,SC_SCREENSAVE,0L);
//オン
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,TRUE,0,SPIF_SENDWININICHANGE);
//オフ
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,FALSE,0,SPIF_SENDWININICHANGE);
#include <comobj.hpp>
void __fastcall TMainForm::OpenIE(String asURL)
{
const String asOLEObjName = "InternetExplorer.Application";
static Variant IE;
HWND hWnd;
if( VarIsEmpty( IE ) ){
IE = CreateOleObject( asOLEObjName );
}
if(!(hWnd = FindWindow( "IEFrame", NULL ))){
IE = CreateOleObject( asOLEObjName );
hWnd = FindWindow( "IEFrame", NULL );
}
if(hWnd){
IE.OlePropertySet("Visible",true);
::SetForegroundWindow( hWnd );
IE.OleProcedure("Navigate",asURL);
}
}
BCB4だと問題なく動きますが、BCB3はDdeMan.pasのバグのため、DdeMan.pasのRequestData関数の
Move(pData, Result, len); を Move(pData^, Result^, len);
に書き換えて再コンパイルする必要があります。(あるかりさん、ありがとうございました。)
//#include "Ddeman.hpp" //BCB3のとき
#include <Ddeman.hpp>
void __fastcall TMainForm::OpenNN(String asURL)
{
char* dummy;
bool bSuccess=false;
TDdeClientConv *dde = new TDdeClientConv(this);
dde->ServiceApplication =NNFullPath; //netscapeのパス
dde->SetLink("netscape", "WWW_Activate");
dummy=dde->RequestData("0xFFFFFFFF");
StrDispose(dummy);
bSuccess=dde->SetLink("netscape", "WWW_OpenURL");
dummy=dde->RequestData(asURL+",,0xFFFFFFFF,0x3,,,");
StrDispose(dummy);
dde->CloseLink();
delete dde;
if(!bSuccess)WinExec(NNFullPath.c_str(),SW_SHOW);
}
HOME > BCB