日記帳
本ページはプロモーションが含まれています
カテゴリー
Links
blog(ブログ)マスター
アンドロイドの巣
ゼロから始めるベランダ菜園
タイトル
ラジコン
2024年5月
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

アーカイブ

2011年10月 のアーカイブ

flashのハンドルを取得してみよう。

執筆:2011.10.19
編集:2011.10.19

TWebBrowser.HWNDを取得する方法 (メモ: その2)
flashのハンドルを取得してみよう。

【方法1】 : Tag名からリストアップする
  var
    H : THandle;
    i : Integer;
    v_Doccument, v_elems , v_attr : Variant;
    s : string;
begin
  v_Doccument := WebBrowser1.Document;

  if VarIsClear(v_Doccument)
    or
    ('Internet Explorer_Server'
      <> GetClassNameText(GetWindowHandleFromIDispatch(v_Doccument)))
     then
   begin
     Exit;
   end;

  v_elems   := v_Doccument.getElementsByTagName('OBJECT');
  if Not VarIsClear(v_elems)
     and (v_elems.length > 0) then
   begin
     s := 'count: '+IntToStr(v_elems.length) + sLineBreak;
     for i := 0 to v_elems.length -1 do
      begin
        v_attr := v_elems.Item(i).getAttribute('CLASSID');
        if Not VarIsClear(v_attr)
           and (VarToStr(v_attr)
              = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000')
            then
         begin
           s := s + v_attr + sLineBreak;
           H := GetWindowHandleFromIDispatch(v_elems.Item(i));
           s := s + ' HWND: ' + IntToStr(H) + sLineBreak + sLineBreak;
         end;
      end;
     ShowMessage(s);
   end;
end;

【方法2】 : 子Windowから探す
flashオブジェクトが htmlの
最上位に貼り付けられている場合の例です。
※iframeなどに入っている場合は、下位階層まで追いかける必要があります。

※単一のflashが htmlに張り付いている場合。
function SearchFlashHandle(p_hwnd : HWND) : HWND;
    var
      c_hwnd : HWND;
begin
  Result := 0;
  c_hwnd := GetWindow(p_hwnd, GW_CHILD );
    while (c_hwnd > 0) do
      begin
        // ClassName[MacromediaFlashPlayerActiveX]
          if (Pos('MacromediaFlashPlayerActiveX',
                   GetClassNameText(c_hwnd)) = 1) then
           begin
             Result := c_hwnd;
             break;
           end;
          c_hwnd := GetWindow(c_hwnd, GW_HWNDNEXT );
     end;
end;


使用例 : SetFocusする。
h := GetWindowHandleFromIDispatch(WebBrowser1.Document);
flash_handle := SearchFlashHandle(h);
if (flash_handle > 0) then
  Windows.SetFocus(flash_handle);

GetWindowHandleFromIDispatch関数については、
TWebBrowser.HWNDを取得する方法 (メモ: その1)
に書いてあります。


TWebBrowserで、どうしても入力フォーカスを当てたい際に役に立ちます。
flash以外の他のオブジェクトも同様に応用することができます。



さようなら Delphi
 レッツゴー  ドットネット
 それいけ ドットネット
  それいけ C#



TWebBrowser.HWNDを取得する方法 (メモ: その1)

執筆:2011.10.17
編集:2011.10.17

今日は、
  C#へレッツゴー
  さぁ Delphiなんか捨てて みんなドットネットへ Go !!
  それいけ ドットネット推進派 の 禁断のDelphiネタです。

次期Windows8 の 「Windows Developer Preview版」が無償公開 されていますが
もう みなさんは、お使いですか?
※OSのアンインストール機能がないそうなので、インス トールは気をつけてください
Visual Studio 11 Expressの同梱版もあり すごいお試し版OSです。
“Win RunTime(WinRT)”と呼ばれる新しいAPIが追加され
新しいデスクトップ“Metro”では、新しい“Metro”対応のアプリケーション(“Metro style apps”)
なんていうものが必要になるそうです。
キット古い開発環境とアプリを市場から強制排除したいのでしょうね。
もう、Visual Studio意外に開発環境の選択の余地がないって感じになってきましたね。
ということで、 ほらほら、 みんなドットネットへ Go !!

では、本題です。

TWebBrowser.HWNDへのアクセスは不正なエラーに なります。
WebBrowser1.Handleでいいようです。

構造
 
ClassName  

- Shell Embedding ← GetClassName(WebBrowser1.Handle)

-- Shell DocObject View 不明

--- Internet Explorer_Server ← 操作画面
解説URL

ページを表示するとコンテンツに応じて 上の3つが、階層構造で多様につながる。
iframeなどの要素があると多重構造になるようです。

※ コードを参考にする場合は、自己責任で参考にされてください。
※ 十分なテストが必要です。
※ 将来的に、仕様などの変更で利用できなくなることも考えられます。


【TWebBrowser.HWNDは、無効なプロパティ】
  (MSDN 文書番号: 244310):
 ※要約 子WindowをたどっていくとHandleを取得することができます。
※ TWebBrowser.HWND
Web ブラウザの Window ハンドルへのアクセスを提供します。
※ Delphiでは、TWebBrowser.HWNDは使えません。
コード WebBrowser1.HWND;
実行結果 デバッガ例外通知
 プロジェクト は例外クラス EOleException (メッセージ 'エラーを特定できません')を送出しました。


【HTML要素からhandleを取得する方法。】
ハンドルを 直接要求する方法

// [エラー] : E2010 'System.TGUID' と 'Ole2.TGUID' には互換性がありません
const // From Ole2.pas
  IID_IOleWindow: TGUID = (
  D1:$00000114;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46));

function GetWindowHandleFromIDispatch(disp: IDispatch) : HWND;
 var
     h : hwnd;
     Res : HRESULT;
     oWin : IOleWindow; // Unit ActiveX.pas
begin
  // example: GetWindowHandleFromIDispatch(WebBrowser1.Document)
  Result := 0;
  Res := disp.QueryInterface(IID_IOleWindow, oWin);
  if Succeeded(Res) then
   begin
     Res := OWin.GetWindow(h);
     if (SUCCEEDED(Res)) then
        Result := h;
   end;
end;
使


// Class : Internet Explorer_Server
h := GetHTMLObjectWindowHandle(WebBrowser1.Document);
if (h > 0) then
  Windows.SetFocus(h);
(参考)正 規のhtml要素のfocusの使い方
 
// HtmlElement から直接呼び出す場合
// HtmlElement.focus();
  var
    v : Variant;
begin
  v_Doccument := WebBrowser1.Document;
  if Not VarIsClear(v_Doccument) then
    v_Doccument.focus();

 
  var
    v_Doccument, v_elems : Variant;
begin
  v_Doccument := WebBrowser1.Document;
  if VarIsClear(v_Doccument) then exit;
  v_elems   := v_Doccument.getElementsByName('ここにhtml要素の名前');
  if Not VarIsClear(v_elems)
     and (v_elems.length > 0) then
     v_elems.Item(0).focus();

擬似キー入力を送るコード:Function Key
  var
    H : THandle;
begin
  h := GetWindowHandleFromIDispatch(WebBrowser1.Document);
  Windows.PostMessage(H , WM_KEYDOWN, VK_F1 , 0);

擬似キー入力を送るコード:通常文字
  var
    H : THandle;
begin
  h := GetWindowHandleFromIDispatch(WebBrowser1.Document);
  Windows.PostMessage(H , WM_CHAR, Byte('a') , 0);
end;

ALT+F4(終了)を呼びたい場合は
WM_SYSKEYDOWN を使います
Windows.PostMessage(TargetHandle ,
            WM_SYSKEYDOWN , wParam, lParam);

wParam
lParam
VK_F4 + ALT VK_F4 
1 shl 29

VK_F1
IEのF1(ヘルプ)の呼び出しは、反応しないのでわかりません。
Firefox系の他のブラウザでは反応します。

テキストボックスに文字列をいれるだけなら、
普通にgetElementsByNameやgetElementByIdなどで
要素にアクセスして代入した方が安全に入力できます。

普通にテキストボックスに入力する方法
( 応用例:ログインIDなどの自動入力 )

  v_elems.Item(0).innerText := 'abc';
  .innerText
 
.innerHTML
コンボボックス
(selectタグのoption要素)
e.options[e.selectedIndex].text
e.options[e.selectedIndex].value
使い方は、基本的にJavaScriptと同じ。


【一番上のShell DocObject View の HWND 取得方法】
  GetWindow(WebBrowser1.Handle, GW_CHILD )
 ※ ClassNameで、確認した方がいい 、 GW_HWNDNEXT
  Navigateでフォルダを指定した場合、エクスプローラーが内蔵されるので注意。 SysListView32などが現れる。
function GetWebBrowser_Root_ShellDocObject_Handle(AWebBrowser : TWebBrowser) : hwnd;
// Shell DocObject View
 var
   h : hwnd;
begin
  h := GetWindow(AWebBrowser.Handle, GW_CHILD );
  while (h > 0) do
  begin
    if (Pos('Shell DocObject View', GetClassNameText(h)) = 1) then
     begin
       Result := h;
       Break;
     end;
    h := GetWindow(h, GW_HWNDNEXT );
  end;
end;
function GetWebBrowser_Root_IE_Server_Handle(AWebBrowser : TWebBrowser) : hwnd;
// Internet Explorer_Server
 var
   h : hwnd;
   h_child : hwnd;
begin
  h := GetWindow(AWebBrowser.Handle, GW_CHILD );
  while (h > 0) do
  begin
    if (Pos('Shell DocObject View', GetClassNameText(h)) = 1) then
     begin
       h_child := GetWindow(h, GW_CHILD );
       while (h_child > 0) do
        begin
          if (Pos('Internet Explorer_Server',
                   GetClassNameText(h_child)) = 1) then
           begin
             Result := h_child;
             break;
           end;
          h_child := GetWindow(h_child, GW_HWNDNEXT );
        end;
       if (Result > 0) then
         Break;
     end;
    h := GetWindow(h, GW_HWNDNEXT );
  end;
end;
 

【場所から取得する方法】
・ ChildWindowFromPoint関数を使用します。


ついでに、それいけみんなドットネットなので

C#で、ハンドルにメッセージを送る方法は
知らないので
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private extern static System.Boolean PostMessage(
          System.IntPtr hWnd, 
          System.UInt32 Msg,
          System.Int32 wParam,
          System.Int32 lParam);
で回避することができる。

C#で WebBrowserを使ってみよう(その1)

執筆:2011.10.15
編集:2011.10.16


Delphiで作ると実行ファイルが大きくなるし、Tabで WebBrowserコ ントロール内に移動できないので

さぁ C#だー
 はっはっはっ!
  って 試験動作させると
    瞬時に ずっこけました。

OnNewWindowで、Dispatchが設定したかったのです。

他にもいっぱいあるのですけど
NewWindowでDelphi相当の機能が実装されていないのです。
開くURLも取得できないし、Dispatchも設定できないなんて、酷い(ひどい)話です。

.Netには、なんの嫌がらせか知りませんが、本来つけておくべきイベントがたくさんないのです。

なんでもかんでも
新しいWindowで開くで、IEに送るのでは、WebBrowserを内蔵する意味がほとんどないでしょ。
(※IEに送るとセッションCookie?が引き継がれないから問題なんです。)

ということで、
.NetのWebBrowserを拡張して本来あるべきイベントを追加して対処しました。


 private void exWebBrowser1_NewWindow3(
    object sender,
    WebBrowserExtendedNewWindow3EventArgs e)
 {
     // メモ
     //  (1)e.pDisp に設定しない。新しいIEとして開く。
     //  (2)e.pDisp を設定する。指定したWebBrowserで開く。
     //     ※同じWebBrowserでは、e.pDispは、動作しない。
     //  (3)同じWebBrowserで開く。キャンセルNavigateを呼ぶ。
     //     ※POSTなどが失われるので注意。
     // MessageBox.Show((string) e.URL);
     // open as self WebBrowser
     //  e.Cancel = true; exWebBrowser1.Navigate((string) e.URL);
     // open as new WebBrowser
     //  e.pDisp = exWebBrowser2.ActiveXInstance;
 }

// using System.Runtime.InteropServices;
    public event EventHandler<WebBrowserExtendedNewWindow3EventArgs> NewWindow3;

    protected void OnNewWindow3( ... 省略
    ..... 省略

    [ComImport, Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"),
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
    TypeLibType(TypeLibTypeFlags.FHidden)]
    public interface DWebBrowserEvents2
    {
       [DispId(273)]
       void NewWindow3(
           [In, Out, MarshalAs(UnmanagedType.IDispatch)] ref object pDisp,
           [In, Out] ref bool cancel,
           [In] ref object flags,
           [In] ref object URLContext,
           [In] ref object URL);
    }


読者に作る機会を与え、動作原理を理解させるために
あえて、完全なコードは開示していません。
不足分は、参考サイトを見ながら完成させましょう。

参考にした フォーラム が型とか ウソ書いていたので
少し手間だったヨ。

◎よくできました
とりあえず、目的の動作をするようにしたのでので「よし」としよう。


【参考サイト】
  • webBrowserで別のウインドウで開くときの開く先のURLの取得法
    とその中のリンク記事
    (VSUG フォーラム → .NET 開発  → Visual C#  → webBrowserで別のウインドウで開くときの開く先のURLの取得法)
  • MSDN Library for Visual Studio 2008
    ・CreateSink メソッド (使用例)
    ・他

「1時間以内なら、電源を切るよりスタンバイが節電になる」はウソ!!

執筆:2011.9.30
編集:2011.9.30

TVでよく、
1時間以内に再使用するなら、電源を切るよりスタンバイが節電になる
といっているが
前々から 非常に うそくさい と思っていたので 検証してみました。

デスクトップPCで
電力計を使って検証してみました。

ノートPCは、携帯性・移動性などの面から省電力に特化されているので今回は比較しません。

【まとめ : デスクトップPC】
  • スタンバイを使うときは慎重に
    周辺機器、ソフトウェア エラーなどの問題がないかの検討・検証が必要です。

  • スタンバイよりモニターの省電力機能を使うだけのほうが安全です。

  • 数時間使用しない場合は、待機電力自体を節電タップで落としたほうがよい。
    ※スタンバイになっている時に節電タップで電源を落とす事故のないようにお気を付けください。

  • 運用時間に節電しても1日数十円と1台あたりの費用効果が非常に低いので、
    使用時間・頻度・保有台数・節電による遅延、作業不履行損失など慎重に検討したうえで、節電計画をたてよう。

  • 筆者PCでは、5~6分が「電源を切る」と「スタンバイ」の損益分岐点である

  • システム構成と電源の供給方法で大きく電力消費が変わるので
    おおよその節電になる正確な時間を知るには、電力計(ワットメーター)が必要になります。
モニターの制御は、
 画面のプロパティ - モニタ電源 - 電源オプションのプロパティ
で、簡単に設定することができます。

 マザーボード説明書では、2種類のスタンバイモードに対応で、設定を変えても電力は同じ値でした。
 もともと低電力CPUのためか、メインボードがアホなのか、非対応周辺機器への配慮のためなのかはわかりませんが、
スタンバイになってもPC本体の電力変化が期待するほどありませんでした。
 ※普段使用する実環境で、計測しないと意味がないと思いますし、
取り外しが面倒なので、スタンバイ非対応のUSB PCIボードは接続したままです。
 今回の調査で、筆者のPCは、
「スタンバイ時」と「モニターだけ電源を切った状態」との電力差が7W未満とあまり差がないので
スタンバイ使用自体に意味がないことがわかりました。

筆者のPCは、5分が分岐点なので、
トイレくらいならモニターを切って対処し
それ以外で、席を離れる際は、今まで通り 電源を切ることにしました。

コンセントに1日中つなぎっぱなしの場合は、
半日使用しないとすると節電タップの費用は半年~1年で回収できるので節電タップの購入をお勧めします。

なお 節電を極めるには、ノートPCのほうが効率がいいでしょう

【内容 デスクトップ PC】

パソコン(モニターを含む)
CPU:1900MHz 45W
(2.5インチHDD)
消費電力
1日あたり
30日間
1年間
待機時
3.5W
3.4円/日
102円
1241円
On直後
90.7W



OS起動
92.7W



ロゴ中
77.6~82W
Max 94W



ユーザー
選択画面
73-82W
しばらく待つと
72.3-78W



選択クリック
73.9-87-93W
の間で変動



このページの編集中
72.1W
36.3円/日

このページの編集中
+モニター電源切断
52.5W
26.8円/日

スタンバイ時
45.9W



スタンバイ時
+モニター電源切断
44.6~44.7W




上の表をみても、スタンバイでMAXの半分程度なので
電源を切るより、スタンバイのほうが、1時間以内では節電なんていうことは 明らかにウソ。

では、計算で、分岐点を調べて見ましょう
起動中は 平均80W程度なのですが、大きめに見積もって90Wで計算します。
再起動をクリックして、起動後のデスクトップの砂時計が消えるまでの時間:2分30秒間(150秒)
終了+起動に2分30秒間(150秒)かかるという計算で
150秒×90W = t 秒×45.9W
t = 150秒×90W ÷ 45.9W  = 294秒 ≒ 約5分
(安定までに180秒で大きめに見積もっても、6分弱が分岐点。)
単純に5分以上使わないときは、PCを丸ごと切った方がいいということになります。
いくつかのソフトを起動して作業環境を構築する時間を考慮すると1~3分は加味した方がいいかもしれないです。

即座に利用しないといけないような環境の場合は、電源を切ると不都 合があるので注意が必要です。

 
スタンバイにすることによって、スタンバイ非対応の周辺機器やアプ リケーションが不安定やエラーになることがあるので
スタンバイを安易に使うのは避けたほうがいいでしょう。
スタンバイ・休止機能を使う際は、問題が発生しないか十分検証しましょう。



スタンバイにすることによって、スタンバイ非対応の周辺機器やアプリケーションが不安定やエラーになることがあるので
5分以内ならモニターの電源を切るだけがもっとも安定性のいい節電といえる。
節電タップを使わなくても
電源オプションのプロパティのモニターの設 定で、未使用時間に応じて自動でモニターの電源を切ることができる。



では、待機電力が1起動分の電力になる時間を計算してみよう。
電源Pushから起動までに約130秒
130秒×90W = t 秒×3.5W
t = 130秒×90W ÷ 3.5W  ≒ 約55.7分
60分間使わない場合は、1起動分の電力になるので、待機電力自体を節電タップで落としたほうがよさそうです。

スタンバイは、CPUとメモリに最低限の通電をしている状態なので、どんなにがんばっても待機電力より大きい値となります。
仮にBIOSの設定をいじって、 スタンバイが待機電力に近い値になると想定し、
+1W : t = 150秒×90W ÷ (3.5W+1W)  ≒ 約50分
+2W : t = 150秒×90W ÷ (3.5W+2W)  ≒ 約41分
+5W : t = 150秒×90W ÷ (3.5W+5W)  ≒ 約26.5分
で計算しても
百歩譲っても 分岐点は 50分以上に設定することは困難です。

以上より
本PCでは
 「1時間以内なら、電源を切るよりスタンバイが節電になる」
というのは、当てはまりません。

なお、何度も言っていますが、本PCでは、デフォルト状態では、5~6分が分岐点です!!

【内容 ノートPC Windows 7】
参考までに、ノートPCでも計測しました。
バッテリーがフル充電になるのを待ってから 計測。
※スタンバイモードがないので未計測。

消費電力
1日あたり
30日間
1年間
待機時
W
-円/日
-円
-円
スタンバイ時
W



OS起動
W



ロゴ中
~W



ユーザー
選択画面
-W
しばらく待つと
-W



選択クリック
-W
の間で変動



このページの編集中
22.5W
11.4円/日

t = 起動時間×起動電力 ÷ スタンバイ電力
 = 60秒×0W ÷ .W  ≒ 約.分


【資料】

今回使用した道具

ワットメーター(TAP-TST8)

商品はこれ
TAP-TST8

SANWA SUPPLY ワットモニター TAP-TST8

サンワサプライ

SANWA SUPPLY ワットモニター TAP-TST8



 
買ったときは発売開始直後だったので、 送料込みで、3445円で買いました。
先日値段をみたときは、3000円を下回ってしました。

購入しても元を取り戻せるような商品ではありませんが
もっていると壊れるまで、いろいろ計測できて楽しめる商品です。

 待機電力は、家電の寿命、電気代に影響し、不幸な家電事故の原因になる可能性がありますので、
待機が不要な電気製品の不要な待機電力の削減をおすすめします。

ワット計の購入よりも
節電タップを持っていない場合は、節電タップの購入を優先した方がいいと思います。
節電タップは、ホームセンターや電気屋さんで600円前後くらいで売っていると思います。
ブレーカーや雷サージ付きの節電タップは1000~2000円くらいすると思います。

付近への落雷で電気製品がよく壊れるっていうかたは、
破損を防いでくれる場合があるそうなので
雷サージ付きのタップの購入をお勧めします。



PR

[PR]