BorlandC++Builder

BorlandC++Builderを趣味で使ってます。役に立ったテクニックなどをメモしていきます。


小技

二重起動の防止

要はセマフォを実現できれば良いわけです。ですので固定ファイルの存在の有無でチェックしたりしても良いです。OSの提供するAPIを使う方が手軽です。

CreateMutexを用いてハンドルを取得します。"UniqueString"はユニークな文字列を指定します。既にハンドルが取得されている場合は二重起動としてそのまま終了するようになっています。

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    HANDLE mx = CreateMutex(NULL, true, "UniqueString");
    if (GetLastError()) {
        return -1;
    }

    try
    {
        Application->Initialize();
        Application->CreateForm(__classid(TForm1), &Form1);
        Application->Run();
    }
    catch (Exception &exception)
    {
         Application->ShowException(&exception);
    }
    catch (...)
    {
         try
         {
             throw Exception("");
         }
         catch (Exception &exception)
         {
             Application->ShowException(&exception);
         }
    }
    ReleaseMutex(mx);
    return 0;
}

終了時にハンドルを解放します。

2007/04/07 komina

二重起動の防止(2)

もっと簡単に下記のようなクラス作ると便利かもしれません。

class OnlyOne {
    HANDLE mx;
    bool enable;

  public:
    OnlyOne(const char *id) {
        mx = CreateMutex(NULL, true, id);
        enable = !GetLastError();
    }
    ~OnlyOne(void) {
        if (isEnable()) {
            ReleaseMutex(mx);
        }
    }
    bool isEnable(void) {
        return(enable);
    }
};
OnlyOne app("app id");
if (!app.isEnable()) return(-1); // 起動済みなので強制終了

適当な変数とIDでインスタンスを作成し、二重起動をチェックするだけです。後始末はスコープを外れる時に自動的に行われるので解放の手間もありません。

2007/05/12 komina

実行ファイルの絶対パスを取得

ApplicationにExeNameというプロパティがあります。AnsiStringで実行ファイルの絶対パスを返します。

AnsiString exeName = Application->ExeName;

実行ファイルのフォルダまでが必要ならExtractFilePathを使って、

AnsiString exePath = ExtractFilePath(Application->ExeName);

とします。

2007/04/08 komina

TLabelのキャプション中で改行

オブジェクトインスペクタからはダメ。

Label1->Caption = "ABC\ndef";

のようにプログラム中で直接代入すると複数行にわたるキャプションが設定できる。

2007/04/07 komina