旧C++Builder FAQ - プログラミング・Windows

Abstract: この FAQは、旧 www.borland.co.jpに掲載されていた記事を転載したものです。記事は掲載時点の情報をあるがままに掲載しており、新バージョンでのご利用においては、コンポーネントや APIの仕様変更等によりご利用いただけない場合がありますのでご留意ください。

    「バージョン情報」の設定方法

該当するバージョン:C++Builder 1

Q:

EXEファイルのショートカットアイコンをクリックした際に出る「バージョン情報」を、自分の作ったプログラムでも出せるようにしたい。

A:

この部分につきましては、現在プロジェクトオプション等では設定出来ません。下記のような、リソースファイルを作成して?????と書いてある部分に必要事項をうめた後、プロジェクトマネージャでこのリソースファイルを追加してください。

--------------------verinfo.rc start---------------------
VERSIONINFO_1 VERSIONINFO
FILEVERSION 1, 0, 0, 0
PRODUCTVERSION 1, 0, 0, 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
{
 BLOCK "StringFileInfo"
 {
  BLOCK "041103A4"
  {
   VALUE "CompanyName", "?????\000\000"
   VALUE "FileDescription", "?????\000"
   VALUE "FileVersion", "?.??\000\000"
   VALUE "InternalName", "?????\000"
   VALUE "LegalCopyright", "Copyright (c) ?????? 199?\000\000"
   VALUE "OriginalFilename", "?????.exe\000"
  }

 }
 BLOCK "VarFileInfo"
 {
  VALUE "Translation", 0x0411,932
 }
}
--------------------verinfo.rc end-----------------------

    Visual Basicで作成されたコントロールを使用すると Access Violationが発生します。(99/6/4)

該当するバージョン:C++Builder 3,C++Builder 4

Q:

Visual Basicで作成されたコントロールを使用すると Access Violationが発生します。

A:

COMに関して出版された書籍は、一般的に Visual Basicが作り出す VTableは C++の VTableと同じであるかのように説明されています。

しかし、Visual Basicの作り出す VTableは、C++の VTableと完全に互換がありません。(関数が VTable に連続して配置されない)

C++Builderで Visual Basicで作成された、ActiveX コントロールを Ole Automationで使用する場合は、ディスパッチインターフェースを使用して下さい。

    タスクバーを除いたデスクトップの領域の取得(98/08/03)

Q:

タスクバーを除いたデスクトップの領域を取得する方法はありますか。

A:

Windows API SystemParametersInfo()を使用します。

Example:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    TRect r ;

    SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
    Form1->Top = r.Top;
    Form1->Left = r.Left;
    Form1->Width = r.Right - r.Left;
    Form1->Height = r.Bottom - r.Top;
  }

    フォルダの選択ダイアログを表示する方法(98/08/03)

Q:

フォルダの選択ダイアログを表示したい。

A:

Windows API SHBrowseForFolder()を使用します。

Example:

  #include <windowsx.h>
  #include <shlobj.h>

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    BROWSEINFO BrowsingInfo;
    char DirPath[MAX_PATH];
    char FolderName[MAX_PATH];
    LPITEMIDLIST ItemID;

    memset( &BrowsingInfo, 0, sizeof(BROWSEINFO) );
    memset( DirPath, 0, MAX_PATH );
    memset( FolderName, 0, MAX_PATH );
    BrowsingInfo.hwndOwner      = Handle;
    BrowsingInfo.pszDisplayName = FolderName;
    BrowsingInfo.lpszTitle      = "フォルダを選択してください";
    BrowsingInfo.ulFlags        = BIF_RETURNONLYFSDIRS;
    ItemID = SHBrowseForFolder( &BrowsingInfo );
    SHGetPathFromIDList(ItemID, DirPath );
    ShowMessage( DirPath );
    GlobalFreePtr( ItemID );
  }

最新の C++Builderでこのサンプルを試すためには、プロジェクトの定義に、NO_WIN32_LEAN_AND_MEANを追加してください。

    タスクバーを非表示にする(98/07/01)

Q:

タスクバーを非表示にする方法はありますか。

A:

Windows API FindWindow()を使用してタスクバーのハンドルを取得し、Windows API ShowWindow()で非表示にします。

Example:

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    // 非表示
    HWND hTaskbar;
    hTaskbar = FindWindow("Shell_TrayWnd", NULL);
    ShowWindow(hTaskbar, SW_HIDE);
  }

  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
    // 表示
    HWND hTaskbar;
    hTaskbar = FindWindow("Shell_TrayWnd", NULL);
    ShowWindow(hTaskbar, SW_SHOWNORMAL);
  }

    C++Builderから Windowsの壁紙の設定を行いたい。

Q:

C++Builderから Windowsの壁紙の設定を行いたい。

A:

Windows API関数に SystemParametersInfo()があります。

この関数のパラメータに SPI_SETDESKWALLPAPERを指定する事で、壁紙の設定を行う事が出来ます。

以下はボタンを押したときに壁紙を設定するサンプルです。

注:

このサンプルは Windowsの環境ファイルに保存されません。

環境ファイルに保存するためには、最後の引数を SPIF_UPDATEINIFILE + SPIF_SENDWININICHANGEにする必要があります。

  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    char *BmpName = "c:\\win95\\花見.bmp";
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, BmpName, 0);
  }

    ユーザー定義のメッセージを受け取る方法

Q:

ユーザー定義のメッセージを受け取るにはどのようにすれば良いのでしょうか。

A:

フォームの定義に次のようなメッセージハンドラのマクロ定義を追加します。

  BEGIN_MESSAGE_MAP
  MESSAGE_HANDLER(MESSAGE_NAME, MESSAGE_TYPE, METHOD)
  END_MESSAGE_MAP(BASE)

そしてフォームのパブリックメンバーとしてメソッドを宣言し,普通に行いたい処理を実装します。

注意:

RegisterWindowMessageを介して登録されたメッセージではうまく動作しません。この方法は #defineされたメッセージに対してのみ有効です。

   //*** Unit1.h の抜粋 ***//
   const wm_MyMessage = WM_USER + 10;    // ユーザー定義のメッセージ

   class TForm1 : public TForm
   {
   __published: // IDE 管理のコンポーネント
       TButton *Button1;
       TLabel *Label1;
       void __fastcall Button1Click(TObject *Sender);
   private:     // ユーザー宣言
   public:      // ユーザー宣言
       __fastcall TForm1(TComponent* Owner);
       void MyMessage(Messages::TMessage &mes);  // メッセージハンドラ

     BEGIN_MESSAGE_MAP
     MESSAGE_HANDLER(wm_MyMessage, TMessage, MyMessage)
     END_MESSAGE_MAP(TForm)
   };
   //*** Unit1.cpp の抜粋***//
   // ユーザー定義用メッセージハンドラ
   void TForm1::MyMessage(Messages::TMessage &mes)
   {
       Label1->Caption = "メッセージ感知";
   }

   // ユーザー定義メッセージを送るイベント
   void __fastcall TForm1::Button1Click(TObject *Sender)
   {
       SendMessage( Form1->Handle, wm_MyMessage, 0, 0 );
   }

    Borland C++Builderでの DLLの構築方法

Q:

自分で Borland C++ Builderの DLLを構築するにはどのように行なったら良いのですか。

自分で DLLの following functionを試みました。

  extern "C" int WINAPI fParse(char* AString)
  {
    AString[0] = 'Z';
    return 1;
  }

A:

メニューバーで[ファイル|新規作成]でダイナミックリンクライブラリを選び閉じます。

export関数 __declspec(dllexport)を使用します。

function headerを次のように記載します。

  extern "C" int WINAPI __declspec(dllexport) fParse(char* AString) {...}

    アプリケーションの二重起動防止

Q:

アプリケーションの二重起動を防止したい。

A:

WindowsAPI CreateMutex()で自分を登録します。

CreateMutex()の第三引数には、このアプリケーション特有のキーワードを記述してください。

  // projectソースの宣言部に追加
  HANDLE mx;
  // WinMainの行の直後に下記の内容を追加
  mx = CreateMutex( NULL, true, "UniqueName" );
  if( GetLastError() ){
    return 1;
  }
  // 最後の return 0の前に追加
  ReleaseMutex( mx );