解决OLE控件失去焦点的办法
2008-11-01 15:11
309 查看
■ OleContainerのフォーカス
[Delphi Q & A 掲示板] [過去ログの一覧]window.google_render_ad();
TKM 2007/04/05(木) 18:05:03 <初心者>
OleContainerでExcelを表示させています。
表示直後の動作に問題はなく、編集などもできます。
が、一度フォーカスがOleContainerからはずれると
OleContainerに戻れなくなります。
また、ツールバーも消えます。
正確には、OleContainer上で右クリック-編集とやれば
編集できます。
この時点でツールバーも復活します。
常にOleContainerを編集状態にしておくことは、
できないのでしょうか?
Mr.XRAY [HomePage] 2007/04/05(木) 22:16:36
OleContainerにはどのような手順でExcelを表示させたのでしょう.
また,DelhiのバージョンとWindowsのバージョンは?
Excelのバージョンは?
TKM 2007/04/06(金) 09:06:13 <初心者>
すみません。
環境を書くのを忘れてました。
Delphi5+WindowsXP+Excel2000です。
Excelを表示させている部分は、
//ExcelファイルをOleContainerオブジェクトとする
OleContainer.CreateObjectFromFile('C:/text.xls',False);
//OLEオブジェクトを表示
OleContainer.Visible:=True;
OleContainer.DoVerb(ovShow);
OleContainer.SetFocus;
こんな感じです。
Mr.XRAYさんのHPを参考にさせて頂きました。
UIActiveとかUIDeactivateあたりが怪しいと思われるのですが
このあたりがよくわかっていません・・・
TKM 2007/04/06(金) 10:38:29 <初心者>
その後いろいろと調べていると、
OleCtnrs.pasの
procedure TOleContainer.CMUIDeactivate(var Message: TMessage);
begin
if (GetParentForm(Self).ActiveOleControl = Self) and
(FOleInPlaceObject <> nil) then
Exit; ←追加
//FOleInPlaceObject.UIDeactivate; ←削除
end;
このようにすると見た目は問題なさそうですが、、、
Activeのときに動作がちょっとおかしくなる。
しかも、コンポーネントのソースは直接さわりたくないので。。。
何か良い方法はない物でしょうか?
TKM 2007/04/06(金) 15:52:39 <初心者>
コンポーネントを直接変更せずに
今回のプロジェクトのみに適用する方法はわかりました。
{宣言部}
type
TOleContainer = Class (OleCtnrs.TOleContainer)
private
procedure CMUIDeactivate(var Message: TMessage); message CM_UIDEACTIVATE;
end;
...
...
{実行部}
procedure TOleContainer.CMUIDeactivate(var Message: TMessage);
begin
if (GetParentForm(Self).ActiveOleControl = Self) then exit;
end;
後は、この状態で表示されているExcelをクリックしたときに
Excelを編集できる状態になればよいのですが・・・
現在では、ダブルクリックするなど一度Excelのセルを
編集状態にするとExcel側にフォーカスが移動します。
表示されているExcelをクリックしてもOleContainerのイベントが
発生しないようなのでお手上げです。。。
もうちょっとなんですが。
clone好きやねん 2007/04/06(金) 16:55:06
type
TOleContainerEx = class(TOleContainer)
private
function ShowToolBar: HRESULT;
procedure CMUIDeactivate(var Message: TMessage); message CM_UIDeactivate;
constructor CreateClone(Origin: TControl);
end;
constructor TOleContainerEx.CreateClone(Origin: TControl);
var
BinStream: TStream;
begin
Create(Origin.Owner);
BinStream := TMemoryStream.Create;
try
with TWriter.Create(BinStream, $800) do try
Root := Origin.Owner;
WriteSignature;
WriteComponent(Origin);
WriteListEnd;
finally
Free;
end;
with TReader.Create(BinStream, $800) do try
Root := Origin.Owner;
Parent := TControl(Origin).Parent;
Origin.Free;
Position := 0;
BeginReferences;
try
ReadSignature;
ReadComponent(Self);
FixupReferences;
AutoActivate := aaGetFocus; // クリックでActive
finally
EndReferences;
end;
finally
Free;
end;
finally
BinStream.Free;
end;
end;
procedure TOleContainerEx.CMUIDeactivate(var Message: TMessage);
begin
exit; // ナンもせーへん
end;
function TOleContainerEx.ShowToolBar: HRESULT;
var
View: IOleDocumentView;
Doc: IOleDocument;
begin
result := ERROR;
if Self.OleObjectInterface.QueryInterface(IOleDocument, Doc) <> 0 then Exit;
if Doc = nil then Exit;
if Doc.CreateView(Self, nil, 0, View) <> 0 then Exit;
View.UIActivate(TRUE);
result := NOERROR;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TOleContainerEx.CreateClone(OleContainer1);
OleContainer1.CreateObjectFromFile(ExtractFilePath(Application.EXEName) + 'ほにゃ.xls', False);
OleContainer1.Visible := True;
OleContainer1.DoVerb(ovShow);
OleContainer1.SetFocus;
TOleContainerEx(OleContainer1).ShowToolBar; // ExcelToolbar隠れとったら表示
end;
TKM 2007/04/06(金) 17:49:25 <初心者>
clone好きやねんさん回答ありがとうございます。
試してみましたが、ダメでした。
マウスのクリック等は受け付けるのでちょっと前進です。
太字とか斜体とかは、効きます。
が、肝心のキーボード入力を受け付けてくれません。
同一フォームにOleContainerが乗ったPanel1と
TMemoなどが乗ったPanel2があり
一度、Panel2にフォーカスが当たると
Panel1に戻ったときにセルを編集しようとすると
ダブルクリックが必要です。
そのままキーボードをたたくとTMemoに文字が・・・
AutoActivate := aaGetFocus
はクリックでActiveのはずなのでセルのクリックでも
アクティブになるかと思ったのですが・・・
どうも、OleContainerがクリックに反応してなさそうです。
せっかく教えて下さったのですが、
他によい手はない物でしょうか?
Mr.XRAY [HomePage] 2007/04/07(土) 00:51:01 <常連>
FormにOleContainerだけであれば、常にFocusがあることになりますが、
他のコントロールを配置した場合は、わかりません。
OleContainerの場合、サーバが自分自身のウィンドウを持っている時には
必ずしもActiveプロパティが編集可能な状態にできるとは限らないからです。
ただし、外部のButton等からExcelのセルに値を代入したり、取得することは
は可能です。
それでも、Excelであれば、Excelのオブジェクトを
GetActiveOleObject
CreateOleObject
等で取得して、そのオブジェクトに対して操作することになります。
ネット上のサンプルがそうなっているのはそのためだと考えていい
と思います。
TKM 2007/04/09(月) 12:56:58 <初心者>
Mr.XRAYさん回答ありがとうございます。
やはり、OleContainerを使うときは、
単独フォームにして他のフォームとは
分けた方よさそうですね。
セルをダブルクリックすると編集状態にできるので
セルのクリックで同じ動作ができれば・・・
と思ったのですが、難しそうですねぇ。
しかし、ダブルクリックしたときは
内部的にどうなってるんだろう。。。
TKM 2007/04/09(月) 16:10:43 <初心者>
TExcelWorkSheetのSelectionChangeイベントに
下記のように書くとマウスでセルを変更した場合に
Excelにフォーカスを渡すことができました。
が、同じセルを選択するとイベントが発生しない・・・
何か良いタイミングは、無いものでしょうか?
var WinHnd : Integer;
begin
// エクセルのハンドルを検索
WinHnd := FindWindow('XLMAIN', nil);
if WinHnd > 0 then begin
SetForegroundWindow(WinHnd);
end;
TKM 2007/04/09(月) 16:45:55 <初心者>
[[解決]]
clone好きやねんさんに教えて頂いたクローンにイベントを追加
マウスがコントロールに入ったときにエクセルをアクティブにする。
{宣言部}
TOleContainerEx = class(TOleContainer)
private
function ShowToolBar: HRESULT;
procedure CMUIDeactivate(var Message: TMessage); message CM_UIDeactivate;
procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER; // <-追加
constructor CreateClone(Origin: TControl);
end;
{実行部}
・・・
procedure TOleContainerEx.CMMouseEnter(var Msg: TMessage);
var WinHnd : Integer;
begin
// エクセルのハンドルを検索
WinHnd := FindWindow('XLMAIN', nil);
if WinHnd > 0 then begin
SetForegroundWindow(WinHnd);
end;
end;
・・・
とりあえず、これで何とか思うようになりました。
clone好きやねんさん、Mr.XRAYさんありがとうございました。
毎週金曜日はポイント最大3倍!さらに4倍のチャンスも!
Programming Library
相关文章推荐
- 在ListView里添加viewPager为header时,viewPager滑动失去焦点的解决办法
- ListView 添加viewPager为header时,viewPager滑动失去焦点的解决办法
- [导入]关于DATAGRID数据更改时点2次/行号跟不准/失去焦点/丢失e等一系列问题的解决办法:
- WPF 在TextBox失去焦点时检测数据,出错重新获得焦点解决办法
- WPF 在TextBox失去焦点时检测数据,出错重新获得焦点解决办法
- 电脑优化后窗口失去焦点键盘失灵解决办法
- Silverlight Textbox在失去焦点之前无法获取到Text值的解决办法
- 关于ListView中含有CheckBox,Button等控件失去焦点的解决办法
- 电脑无故失去焦点,罪魁祸首是谁?终极解决办法
- 用DirectSound在窗口中播放声音,可当窗口失去焦点后却不播放的解决办法
- 关于wxPython中的TextCtrl响应失去焦点事件后不能再次编辑或出现不正常现象的解决办法
- 单击 numberfield后,如失去焦点后非数字部分消失问题的解决办法
- 关于RecyclerView中含有CheckBox,Button等控件失去焦点的解决办法
- ListView 添加viewPager为header时,viewPager滑动失去焦点的解决办法
- ListView+EditText失去焦点和软键盘问题解决办法
- 控件进行Animation动画后失去焦点的几个解决办法
- 电脑无故失去焦点,罪魁祸首是谁?终极解决办法
- WORD程序失去焦点再获得焦点后无法使用鼠标功能的解决办法(已解决)
- WPF 在TextBox失去焦点时检测数据,出错重新获得焦点解决办法
- Win10系统当前窗口失去焦点的解决办法