oleコントロールのウィンドウハンドルの取得に失敗しました

解決


リラ  2013-02-16 03:26:27  No: 43862

以前、InkEditについて質問させていただいた者です。

InkEditを実装し、exeで起動させ、フォームを開くときに、

OLEコントロールのウィンドウハンドルの取得に失敗しました

というようなエラーメッセージが出て
フォームが開きません。

開発環境では問題ないのですが、
客先のPCで動く環境と動かない環境があります。

無知で申し訳ありませんが、解決方法はありますでしょうか?
教えていただけると助かります。


リラ  2013-02-16 03:46:06  No: 43863

追記です。

環境はDelphiXE3  Win7  32bitです。


DEKO  2013-02-17 00:16:08  No: 43864

> 環境はDelphiXE3  Win7  32bitです。
客先の (動かない) 環境は何でしょう?

[InkEdit 再び]
http://ht-deko.minim.ne.jp/ft1302.html#130216

↑で作ったサンプルを "動かない環境" で
動作するかどうか試してみてはいかがでしょうか?


リラ  2013-02-18 19:33:58  No: 43865

記載漏れ失礼しました。

客先のPCは、Win7  Proです。  恐らく32bitだと思うのですが、
今ちょっと分かりません…
Win7  Proで動く環境と動かない環境があります。

ちなみに、MS Win Server 2008 x64  R2 SP1 SE  のサーバ上では
InkEditを含むフォームを開くと「クラスが登録されていません」という
エラーが出ていましたが、
ご教授いただいたものを試してみましたら、エラーは起こりませんでした。

ただ、手入力ができない状態です。マウスを動かしても、
カーソルが出て、キーボード入力状態になってしまいます。

客先のPCでは試せないので、サーバ上で動作できれば
大丈夫かと思っているのですが…原因がはっきりしません。

以下、DEKOさんのInkEdit再びをそのまま引用させていただき、
インク入力タイムアウト時間のプロパティを追加しました。

見よう見まねなのですが…

//-------------------------

unit uInkEdit;

interface

uses
  Winapi.Windows, Winapi.Messages, Winapi.RichEdit, Vcl.Controls, Vcl.ComCtrls;

type
  TInkMode =
    (IM_Disabled      = 0,
     IM_Ink           = 1,
     IM_InkAndGesture = 2);

  TInkInsertMode =
    (IEM_InsertAsText = 0,
     IEM_InsertAsInk  = 1);

  TInkDisplayMode =
    (IDM_Ink          = 0,
     IDM_Text         = 1);

  TInkEditStatus =
    (IES_Idle         = 0,
     IES_Collecting   = 1,
     IES_Recognizing  = 2);

  TInkEdit = class(Vcl.ComCtrls.TRichEdit)
  private
    function GetUseMouseForInput: Boolean;
    procedure SetUseMouseForInput(const Value: Boolean);

    function GetRecTimeOut: Integer;
    procedure SetRecTimeOut(const Value: Integer);

  protected
    procedure CreateParams(var Params: TCreateParams); override;
  published
    property UseMouseForInput: Boolean read GetUseMouseForInput write SetUseMouseForInput;
    property UseRecTimeOut: Integer read GetRecTimeOut write SetRecTimeOut; // インク入力タイムアウト時間
  end;

const
  InkEditClassName = 'INKEDIT';
  IEC__BASE               = WM_USER + $0200;
  EM_GETINKMODE           = IEC__BASE +  1;
  EM_SETINKMODE           = IEC__BASE +  2;
  EM_GETINKINSERTMODE     = IEC__BASE +  3;
  EM_SETINKINSERTMODE     = IEC__BASE +  4;
  EM_GETDRAWATTR          = IEC__BASE +  5;
  EM_SETDRAWATTR          = IEC__BASE +  6;
  EM_GETRECOTIMEOUT       = IEC__BASE +  7;
  EM_SETRECOTIMEOUT       = IEC__BASE +  8;
  EM_GETGESTURESTATUS     = IEC__BASE +  9;
  EM_SETGESTURESTATUS     = IEC__BASE + 10;
  EM_GETRECOGNIZER        = IEC__BASE + 11;
  EM_SETRECOGNIZER        = IEC__BASE + 12;
  EM_GETFACTOID           = IEC__BASE + 13;
  EM_SETFACTOID           = IEC__BASE + 14;
  EM_GETSELINK            = IEC__BASE + 15;
  EM_SETSELINK            = IEC__BASE + 16;
  EM_GETMOUSEICON         = IEC__BASE + 17;
  EM_SETMOUSEICON         = IEC__BASE + 18;
  EM_GETMOUSEPOINTER      = IEC__BASE + 19;
  EM_SETMOUSEPOINTER      = IEC__BASE + 20;
  EM_GETSTATUS            = IEC__BASE + 21;
  EM_RECOGNIZE            = IEC__BASE + 22;
  EM_GETUSEMOUSEFORINPUT  = IEC__BASE + 23;
  EM_SETUSEMOUSEFORINPUT  = IEC__BASE + 24;
  EM_SETSELINKDISPLAYMODE = IEC__BASE + 25;
  EM_GETSELINKDISPLAYMODE = IEC__BASE + 26;
  IECN__BASE              = $0800;
  IECN_STROKE             = IECN__BASE + 1;
  IECN_GESTURE            = IECN__BASE + 2;
  IECN_RECOGNITIONRESULT  = IECN__BASE + 3;

var
  FInkEditModule: THandle;

implementation

{ TInkEdit }

procedure TInkEdit.CreateParams(var Params: TCreateParams);
const
  dHideScrollBars: array[Boolean] of DWORD = (ES_DISABLENOSCROLL, 0);
  dHideSelections: array[Boolean] of DWORD = (ES_NOHIDESEL, 0);
begin
  if FInkEditModule = 0 then
    begin
      FInkEditModule := LoadLibrary('InkEd.dll');
      if FInkEditModule <= HINSTANCE_ERROR then
        FInkEditModule := 0;
    end;
  inherited CreateParams(Params);

  CreateSubClass(Params, InkEditClassName);
  with Params do
    begin
      Style := Style or dHideScrollBars[HideScrollBars] or
        dHideSelections[HideSelection];
      WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
    end;
end;

function TInkEdit.GetUseMouseForInput: Boolean;
begin
  result := SendMessage(Self.Handle, EM_GETUSEMOUSEFORINPUT, 0, 0) <> 0;
end;

procedure TInkEdit.SetUseMouseForInput(const Value: Boolean);
begin
  SendMessage(Self.Handle, EM_SETUSEMOUSEFORINPUT, WPARAM(Value), 0);
end;

// インク入力タイムアウト時間
function TInkEdit.GetRecTimeOut: Integer;
begin
  result := SendMessage(Self.Handle, EM_GETRECOTIMEOUT, 0, 0);
end;

procedure TInkEdit.SetRecTimeOut(const Value: Integer);
begin
  SendMessage(Self.Handle, EM_SETRECOTIMEOUT, WPARAM(Value), 0);
end;

initialization
  FInkEditModule := 0;

finalization
  if FInkEditModule <> 0 then
    FreeLibrary(FInkEditModule);
end.

procedure TForm1.FormCreate(Sender: TObject);
begin
  RichEdit1.UseMouseForInput := True;
  RichEdit1.UseRecTimeOut := 1000;
end;

なにか原因がありますでしょうか?


DEKO  2013-02-18 21:37:50  No: 43866

> ただ、手入力ができない状態です。マウスを動かしても、
> カーソルが出て、キーボード入力状態になってしまいます。

単なる RichEdit になっているようですが、
TForm1 が含まれるユニットに以下のコードが含まれていますか?

type
  TRichEdit = class(TInkEdit); // これを追加


DEKO  2013-02-18 21:40:13  No: 43867

失礼しました。あの行がなければ、

>  RichEdit1.UseMouseForInput := True;
>  RichEdit1.UseRecTimeOut := 1000;

このコードでエラーになりますよね (^^;A


リラ  2013-02-18 21:47:44  No: 43868

そうですね、下記は書いています。

type
  TRichEdit = class(TInkEdit); // これを追加


リラ  2013-02-18 21:49:19  No: 43869

補足ですが、上記のソースで、自分の環境では、InkEditと同じ動きをしました。


DEKO  2013-02-18 21:57:46  No: 43870

"Tablet PC Input Service" が停止されてるとかはないですか?


リラ  2013-02-18 22:17:04  No: 43871

ありがとうございます。

自分の環境でTablet PC Input Serviceのサービスを停止してみましたが
手書き入力はできるので違う理由かなと思います…


DEKO  2013-02-18 22:22:58  No: 43872

> ちなみに、MS Win Server 2008 x64  R2 SP1 SE  のサーバ上では
> InkEditを含むフォームを開くと「クラスが登録されていません」という
> エラーが出ていましたが、
"デスクトップ エクスペリエンス機能" はインストールされていますか?

[デスクトップ エクスペリエンスの概要]
http://technet.microsoft.com/ja-jp/library/cc772567.aspx


DEKO  2013-02-18 22:47:20  No: 43873

> 自分の環境でTablet PC Input Serviceのサービスを停止してみましたが
> 手書き入力はできるので違う理由かなと思います…
では、"Tablet PC コンポーネント" ですかね?

[ファイル名を指定して実行] から OptionalFeatures.exe と入力し、
"Tablet PC コンポーネント" にチェックが入っているかどうかを確認してみてください。
([コントロールパネル | Windows の機能の有効化または無効化] です)


DEKO  2013-02-18 22:48:55  No: 43874

誤: [コントロールパネル | Windows の機能の有効化または無効化]
正: [コントロールパネル | プログラムと機能 | Windows の機能の有効化または無効化]


リラ  2013-02-18 23:27:17  No: 43875

ありがとうございます。

どうやらこの設定が怪しいですね…
自分の環境でやってみたら似たようなハンドルエラーになりました。

今度試してみようと思います。

サーバの設定についても確認してみます。

とりあえず解決ということにさせていただきます。
ありがとうございました。


DEKO  2013-02-18 23:42:04  No: 43876

Windows Vista / 7 の高速化とかいうトピックには
大抵この "Tablet PC" 関連の無効とか削除が掲載されていますからね。

[Google 先生に聞いてみた]
https://www.google.co.jp/search?q=Tablet+PC+コンポーネント+削除+高速化&ie=utf-8&oe=utf-8

サーバでない限り、デフォルトで有効かつ簡単には外せるものではないので、
高速化の記事を見たどなたかが外されたのかもしれませんね。

逆にサーバでは Vista / 7 の幾つかの機能がインストールされていないので、
必要であれば "デスクトップ エクスペリエンス機能" 等を
手動でインストールする必要があります。


リラ  2013-02-19 17:54:14  No: 43877

情報ありがとうございます。

このような設定があることを知りませんでした…

他社のシステムも入っているPCなので導入時に外されたのかもしれません…

今後留意したいと思います。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加