2016年11月26日

WIN64ビルドでcabinet sdkを使う

C++BuilderXE7で問題があったのでメモ
それ以降はもしかしたら直ってるかもしれない(直ってないかもしれない)

cabinet sdkをWIN64でビルドするとリンクエラーになる
[ilink64 エラー] Error: Unresolved external 'FDICreate' referenced from xxxx\WIN64\DEBUG\CABINET.O
[ilink64 エラー] Error: Unresolved external 'FDIDestroy' referenced from xxxx\WIN64\DEBUG\CABINET.O
[ilink64 エラー] Error: Unresolved external 'FDIIsCabinet' referenced from xxxx\WIN64\DEBUG\CABINET.O
[ilink64 エラー] Error: Unresolved external 'FDICopy' referenced from xxxx\WIN64\DEBUG\CABINET.O
libファイルのリンク方法は以下の通り
#if _WIN64
#pragma link "Cabinet.a" // リンクエラー
#else
#pragma link "Cabinet.lib" // OK
#endif
WIN32でビルドすると問題なく通る

幸いなことに最近の?RadStudioはPlatformSDKが入っているので、
FDI.HやCabinet.lib等のファイルを別途持ってくる必要なくビルドできる

で、問題はWIN64ですが、
clangに追従していないのか、付属のCabinet.aではダメっぽい
ちなみに、libファイルは以下の場所にある。
C:\Program Files (x86)\Embarcadero\Studio\15.0\lib\win32\release\psdk\Cabinet.lib
C:\Program Files (x86)\Embarcadero\Studio\15.0\lib\win64\release\psdk\Cabinet.a
以下のようにしてdllからCabinet.aファイルを作り直してそれを使えばいけた
mkexp Cabinet.a C:\Windows\System32\cabinet.dll
ただしこの方法は、なるべく古いOSのcabinet.dll(x64)で作成しないと、
古いOSで使えない場合がある
手元のcaibnet.dll(x64)は。。。
cabinet.dll 121.562KB 2016/07/16 20:42
Win10なのでとても新しい。。。。
XP(もしくはVista)の64bitあたりのcabinet.dllがほしいな。。。
posted by sanahi at 20:45| 滋賀 ☁| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2016年11月03日

WM_INPUTテスト

WM_INPUTを使うアレ
キーフックDLLを作らないで、グローバルフックみたいな どこでもキーを受けられるかテスト
XP以降
つかえるかなぁ〜

Unit1.h

//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
private:	// ユーザー宣言
	void __fastcall OnWmInput(TMessage &msg);
	BEGIN_MESSAGE_MAP
		VCL_MESSAGE_HANDLER(WM_INPUT, TMessage, OnWmInput)
	END_MESSAGE_MAP(TForm)
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit1.cpp

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	RAWINPUTDEVICE rid;
	::ZeroMemory( &rid, sizeof(rid) );
	rid.usUsagePage = 0x01; // <--このへんでキーボードかマウスか指定
	rid.usUsage = 0x06; // <--このへんでキーボードかマウスか指定
	//rid.dwFlags = RIDEV_NOLEGACY | RIDEV_EXINPUTSINK; // <-- RIDEV_NOLEGACYつけるかはお好みで
	rid.dwFlags = RIDEV_EXINPUTSINK;
	rid.hwndTarget = Handle;
	::RegisterRawInputDevices(&rid, 1, sizeof(rid));
}
//---------------------------------------------------------------------------
//! WM_INPUT イベントハンドラ
void __fastcall TForm1::OnWmInput(TMessage &msg)
{
	RAWINPUT raw;
	UINT sz = sizeof(raw);

	::GetRawInputData( (HRAWINPUT)msg.LParam, RID_INPUT, &raw, &sz, sizeof(raw.header) );
	// この辺の条件判定はお好みで...
	if( (raw.header.dwType == RIM_TYPEKEYBOARD) && (raw.data.keyboard.Flags & RI_KEY_BREAK) ) {
	  if( raw.data.keyboard.VKey == VK_SNAPSHOT ) { // PrintScreenキー
		::OutputDebugString(L"VK_SNAPSHOT\n");  // <-- ここ
	  }
	}
}
//---------------------------------------------------------------------------

posted by sanahi at 11:34| 滋賀 ☁| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2016年03月02日

プロパティ xFFF4F が存在しません

とても悩んでしまったのでメモ

XE7で TAlphaColorをプロパティにすると Win32はOKですが、
Androidで起動エラーになっています
機種はNexus4,KitKat4.4.4
$75744E6F で初回の例外が発生しました。
例外クラスは EReadError メッセージは 'プロパティ xFFF4F が存在しません'。 
プロセス Project1.apk (20370)
Error_xFFF4F.png
プロパティを使ったわけでもなく プロパティを含むソースをリンクしただけで
起動時にエラーとなって起動できません

新規プロジェクトを以下にするだけで起動できない
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
private:	// ユーザー宣言
  TAlphaColor FTestColor;
  TAlphaColor __fastcall GetTestColor() {
    return FTestColor;
  }
  void __fastcall SetTestColor( TAlphaColor value ) {
    FTestColor = value;
  }
public:		// ユーザー宣言
  __fastcall TForm1(TComponent* Owner);
__published:
  __property TAlphaColor TestColor = { read=GetTestColor, write=SetTestColor }; // <-- この行があると起動不可
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

原因は調べてないのでとりあえずメモ

ラベル:XE7 android FMX
posted by sanahi at 01:33| 滋賀 ☔| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2015年01月14日

Android対応MessageDlgメモ2

MessageDlgを非ブロッキング版で実装する面倒な処理メモ2(C++BuilderXE7)

今回は、MessageDlgを連続で出す方法を考察

前回の方法からさらに汎用化を進めて無名メソッドを外に出してみます。
外に出すことにより、前回の様なIDEのイベントハンドラに関するエラーの回避できます。
今回はコンストラクタで 「複数のインスタンス判別用にStatus」を、「イベント発生用にTNotifyEvent」をもらうようにしました。
//---------------------------------------------------------------------------
// 無名メソッド(MessageDlg用)
class TMessageDlgProc: public TCppInterfacedObject<TInputCloseDialogProc> {
  private:
    TNotifyEvent FEvent;
    UnicodeString FStatus;
    TModalResult FResult;
  protected:
  public:
    __fastcall TMessageDlgProc( UnicodeString AStatus, TNotifyEvent AEvent ) {
      FStatus = AStatus;
      FEvent = AEvent;
    }
    void __fastcall Invoke(const System::Uitypes::TModalResult AResult) {
      FResult = AResult;
      if( FEvent != NULL ) {
        FEvent(this);
      }
    }
    __property TModalResult Result = { read=FResult, write=FResult };
    __property UnicodeString Status = { read=FStatus, write=FStatus };
};

そして今回も、同じイベントを何度もコールさせて状況により処理分けしています。
以下は最大で3回のMessageDlgを出しています。
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
  // 非ブロッキング入力BOX
  // Senderをダウンキャストで無名メソッドかを判断する
  TMessageDlgProc *proc = dynamic_cast<TMessageDlgProc *>(Sender);
  if( proc == NULL ) {
    // [1]
    MessageDlg( L"よろしいですか1?", TMsgDlgType::mtConfirmation, TMsgDlgButtons() << TMsgDlgBtn::mbYes << TMsgDlgBtn::mbNo, 0, new TMessageDlgProc(L"Status1", Button3Click) );
    return;
  }

  if( proc->Status == L"Status1" ) {
    if( proc->Result == mrYes ) {
      // [2]
      MessageDlg( L"よろしいですか2?", TMsgDlgType::mtConfirmation, TMsgDlgButtons() << TMsgDlgBtn::mbYes << TMsgDlgBtn::mbNo, 0, new TMessageDlgProc(L"Status2", Button3Click) );
    }
    else {
      ShowMessage(L"YESx0");
    }
  }
  else if( proc->Status == L"Status2" ) {
    if( proc->Result == mrYes ) {
      // [3]
      MessageDlg( L"よろしいですか3?", TMsgDlgType::mtConfirmation, TMsgDlgButtons() << TMsgDlgBtn::mbYes << TMsgDlgBtn::mbNo, 0, new TMessageDlgProc(L"Status3", Button3Click) );
    }
    else {
      ShowMessage(L"YESx1");
    }
  }
  else if( proc->Status == L"Status3" ) {
    if( proc->Result == mrYes ) {
      ShowMessage(L"YESx3");
    }
    else {
      ShowMessage(L"YESx2");
    }
  }
  else {
  }
}
posted by sanahi at 04:18| 滋賀 ☀| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2015年01月06日

Android対応MessageDlgメモ

MessageDlgを非ブロッキング版で実装する面倒な処理メモ(C++BuilderXE7)

通常はこんな感じだろうか?
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  // 無名メソッド(anonymous method)
  class TLocalProc: public TCppInterfacedObject<TInputCloseDialogProc> {
    private:
    public:
      void __fastcall Invoke(const System::Uitypes::TModalResult AResult) {
        if( AResult == mrYes ) {
          ShowMessage(L"YES!!");
        }
        else {
          ShowMessage(L"NO!!");
        }
      }
  };
  // 非ブロッキングMessageDlg
  MessageDlg( L"よろしいですか?", TMsgDlgType::mtConfirmation, TMsgDlgButtons() << TMsgDlgBtn::mbYes << TMsgDlgBtn::mbNo, 0, new TLocalProc() );
}

さらに一歩進めて無名メソッド内の処理を外に出した(風に)してみた
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  // 無名メソッド(anonymous method)
  class TLocalProc: public TCppInterfacedObject<TInputCloseDialogProc> {
    private:
    public:
      TForm1 *FOwner;
      TModalResult FResult;
      __fastcall TLocalProc( TForm1 *AOwner ) {
        FOwner = AOwner;
      }
      void __fastcall Invoke(const System::Uitypes::TModalResult AResult) {
        // 結果を保持して自分を渡した同じイベントを呼ぶ
        FResult = AResult;
        FOwner->Button2Click(this); // --> [2]が実行される
      }
  };
  // 非ブロッキングMessageDlg
  // Senderをダウンキャストで無名メソッドかを判断する
  TLocalProc *proc = dynamic_cast<TLocalProc *>(Sender);
  if( proc == NULL ) {
    // [1]
    MessageDlg( L"よろしいですか?", TMsgDlgType::mtConfirmation, TMsgDlgButtons() << TMsgDlgBtn::mbYes << TMsgDlgBtn::mbNo, 0, new TLocalProc(this) );
  }
  else {
    // [2]
    if( proc->FResult == mrYes ) {
      ShowMessage(L"YES!!");
    }
    else {
      ShowMessage(L"NO!!");
    }
  }
}

そして無名メソッド使うとこんなエラーがでて、イベントハンドラに飛べなくなります。。。
xe7_無名メソッドバグ.jpg
__fastcall行でIDEの挙動が怪しくなるようです
IDEのバグだとおもうのですが。。。
QC調べようにもどんなspellで検索すればいいのか分からない

いろいろ面倒過ぎるwww
posted by sanahi at 01:50| 滋賀 ☁| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2014年05月24日

権限昇格用アイコンあれこれ

とりあえずメモ
TestShieldIcon.png
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <ComObj.hpp>

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    ::CoInitialize(NULL);
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
    ::CoUninitialize();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonLargeClick(TObject *Sender)
{
    HICON phico = NULL;
    HRESULT hr = ::LoadIconMetric( NULL, MAKEINTRESOURCE(IDI_SHIELD), LIM_LARGE, &phico );
    OleCheck(hr);
    Image1->Picture->Icon->Handle = phico;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonSmallClick(TObject *Sender)
{
    HICON phico = NULL;
    HRESULT hr = ::LoadIconMetric( NULL, MAKEINTRESOURCE(IDI_SHIELD), LIM_SMALL, &phico );
    OleCheck(hr);
    Image2->Picture->Icon->Handle = phico;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ShieldIcon1Click(TObject *Sender)
{
    ShowMessage(L"test");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonAddMenuItemClick(TObject *Sender)
{
    HICON phico = NULL;
    TIcon *icon = NULL;
    try {
        HRESULT hr = ::LoadIconMetric( NULL, MAKEINTRESOURCE(IDI_SHIELD), LIM_SMALL, &phico );
        OleCheck(hr);

        icon = new TIcon();
        icon->Handle = phico;
        ImageList1->AddIcon(icon);
        ShieldIcon1->ImageIndex = ImageList1->Count-1;
    }
    __finally {
        delete icon;
    }
}
//---------------------------------------------------------------------------
ちなみに、LoadIconMetric()APIはXPで使用不可
使用すると起動エラー
XPでエラーにしないようにLoadLibrary()にし、バージョンチェックは必要かもしれない
posted by sanahi at 00:41| 滋賀 ☀| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2008年11月28日

XP+IE7環境でWinINetのAPIがエラーになる

どこかどう変わったのかはわかりませんが、
Win98〜WinXP SP2 + IE6 までは問題なかったのですが、
WinXP SP3 + IE7 環境でWININETが使えなくなってしまった

具体的には、HttpQueryInfo()をコールするとアクセス違反
通常のエラーなら戻り値がFALSE
しかしコレは例外が発生している

いろいろ迷走しているうちに、wininet.libが怪しそうと気づく

ためしに、implibを使って、IE7のwininet.dllからwininet.libを作成して、リンクしてみたら、、、動いてしまった

だからといって、このwininet.libを採用すると、他環境で動かなくなる可能性が高い

wiroのwininet.libはおそらくwin2kのwininet.dllから作成したもの

ここでとった方法が、BCBにあるwininet.libをリンクする

これはかなり古いが互換性は一番あるのではないかと
$(BCB)\Lib\wininet.lib

ひとまずコレで様子見です

posted by sanahi at 02:00| 滋賀 ☁| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2008年10月20日

QuickReport、Previewのボタン非表示

QuickReportネタ

プレビューのファイル読み込み、保存という謎なツールボタンを消す
こうか?な?

//--------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    QuickRep1->Preview();
}
//--------------------------------------------------------
void __fastcall TForm1::QuickRep1Preview(TObject *Sender)
{
    TQRStandardPreview *pv = new TQRStandardPreview(
                                    Application, 
                                    dynamic_cast<TQRPrinter *>(Sender)
                                 );
//    pv->PrintSetup->Visible = false;
//    pv->Print->Visible = false;
//    pv->Separator3->Visible = false;
    pv->SaveReport->Visible = false;
    pv->LoadReport->Visible = false;
    pv->Separator4->Visible = false;
    pv->Show();
}
//--------------------------------------------------------
使いやすいような、不便なようなコンポーネント。。。
これで、謎なボタンは消せた!

しかしぃ〜
「プリンタの設定」のプロパティ設定が全く反映されないのはマズ〜
プリンタ選択までは出来ないと使えないからなぁ〜

なんとかプロパティ(P)ボタンを無効にしたいががが、しばらく悩もう
ユーザーに突っ込まれちゃうぜ!

仕様ですと言い切れるか!?
posted by sanahi at 22:31| 滋賀 ☀| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2008年09月26日

Indy9インストール

・2008/09/26 リンク周り等を最新に更新

BCB6標準のIndy8(8.0.25)をIndy9にアップグレードにしてみた
9.0.17で確認済
いやぁ、結構面倒な作業で・・・(^^;
  1. BCB6を最新の状態にしておく
    これ、鉄則
    最新にしておかないと動かない事が確認されてるそうです
    最新パッチは
    http://www.codegear.com/downloads/regusers/cppbuilder
    からC++Builder6のUpdatePack4をダウンロードして適用しておく

  2. Indy9関連ファイルをダウンロード
    Automated Installer があるが、Delphi5〜7用らしいので断念
    http://www.indyproject.org/Sockets/Download/Files/Indy9.EN.aspx
    から ソース(Indy_9_00_17_src.zip)、 ヘルプ(Indy-9-0-Help-WinHelp.zip)をダウンロード

  3. BCB6が起動中なら終了させる

  4. $(BCB)\Source\vcl\IDPAS32.obj を保存しておく
    あとで検索して一括削除したあとにこのファイルだけ戻す必要がある為です
    # 一括削除時、ゴミ箱経由で削除しておけば、このファイルだけ元に戻せば同じ事

  5. しなくても問題ないが、「アプリケーションの追加と削除」のBCB6から「変更」でIndyを削除
  6. Indy8関連ファイルの削除
    $(BCB) 以下で、
    dclindy*.bpl,dclindy.*,dclindy*.bpl,indy*.lib,id*.pas,id*.hpp,id*.obj,id*.dcu
    を検索し、削除する(念のためゴミ箱移動)

    $(WinDir)\System32\indy*.bpl を削除
    と、 Indy Knowledge Baseに書いていあったが、これは見つからなかった
    (コレはIndy9のFULLC6.batを実行した時にもコピーされるようです
    もし先にC6.batを実行した場合は日付を確認して新しければ消さない方が良いかも)

  7. IDPAS32.objを戻す
    $(BCB)\Source\vcl\IDPAS32.objが消えてるはずなので元に戻す

  8. ヘルプファイル類を新しいものに置き換える
    $(BCB)\Help\indy.* 削除
    Indy-9-0-Help-WinHelp.zip を $(BCB)\Help\ へ展開

  9. ソースを適当なディレクトリに展開してインストール準備する
    Indy_9_00_17_src.zip を 適当なディレクトリ($(HOGE)とする) へ展開
    $(HOGE)\Indy_9_00_17_src\FULLC6.BAT 実行
    $(HOGE)\C6 が出来上がる

  10. ソースをBCB本体側へコピー
    以下の構成でコピー
    $(HOGE)\Indy_9_00_17_src の内容を $(BCB)\Source\Indy9 へ新規コピー
    $(HOGE)\C6 の内容を $(BCB)\Lib\Indy9 へ新規コピー
    ついでといっちゃアレだが、$(BCB)\Source\Indy は要らないだろうから削除

  11. BCB6起動
    エラーダイアログ出ます
    e45acf51eb2daba6ecde304640cebf2f.png
    そりゃそうだ。勝手に消したんだから(^^;
    「いいえ」を選んで続行

  12. Indy8パッケージの削除
    念のため削除
    コンポーネント(C)>パッケージのインストール(P)
    f42ef57cf58b5a3832654e083622adf2.png
    から、チェックのはずれたIndyコンポーネントがあるので「削除」

  13. Indy9パッケージの追加
    同じダイアログから「追加」する
    $(BCB)\Lib\Indy9\ のファイルを追加する
    ここで、エラーがでる場合がある(エラーなければ次へ)
    dde700915ed4783ac6ab49c4c1732a7d.png
    4d9ef9f2e4b677711a60430fe7b978ca.png
    とりあえず、こんな感じのエラーが出た
    Indy8関連ファイル削除段階で$(WinDir)\System32\indy*.bpl が見つからず削除できなかったが、
    実は代わりに、$(BCB)\bin\Indy60.bpl というファイルが見つかっていた
    エラー内容から察するにどうやら、コレは消さないといけないようです
    ということで削除
    そしてエラー無く「追加」成功

  14. パス設定
    以下のパスをそれぞれ追加
    インクルードパス $(BCB)\Lib\Indy9
    ライブラリパス $(BCB)\Lib\Indy9

  15. デバッガオプション設定
    「ツール|デバッガオプション|言語固有の例外」にEIdSilentExceptionを追加

ひとまず、成功?

参考サイト
The Indy Project
  Download Indy 9.0
  Indy Docs
  Indy Knowledge Base

CodeGear
  C++Builder ダウンロード

posted by sanahi at 00:00| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

2007年12月04日

LIBBOOST_REGEX-BCB-MT-SD-1_34_1.LIB が開けません

boost
http://www.boost.org/
新しいバージョン(1.34.1)のRegexをインストール

やり方は
boost::regexを試す(BCB6)
http://sanahi.seesaa.net/article/31252258.html
でいけるのですが、

インストール後、コンパイルエラー
Debugコンパイル
LIBBOOST_REGEX-BCB-MT-SD-1_34_1.LIB が開けません

Releaseコンパイル
LIBBOOST_REGEX-BCB-MT-S-1_34_1.LIB が開けません


1.33.1のときxxx1_33_1.LIBというファイル名だったことから察するに、bcb6.makのLIB作成でファイル名に"_1"が抜けてる模様

binとlibにコピーされた
*boost_regex-*1_34.*

*boost_regex-*1_34_1.*
に変更したらコンパイルできた


ちなみに、最新はないかとcvsを見ると、
http://boost.cvs.sourceforge.net/boost/boost/libs/regex/build/bcb6.mak?view=log

Sun Jul 16 17:23:56 2006 UTC (16 months, 2 weeks ago) by xxxx

1年以上前からこのままなんだ?
ラベル:boost BCB6
posted by sanahi at 01:33| 滋賀 ☀| Comment(0) | TrackBack(0) | C++Builder | このブログの読者になる | 更新情報をチェックする

Remarks
記事中にソースコードが含まれる場合、ソースコードの再利用、改変、「オレのものにする」等は自由ですが、
ソースコードを利用して起こった問題は一切責任を負いません。(自己責任での利用となります。)