shi さん 2005年 02月 11日 22時 04分 00秒

下の私の書き込み [2005年 02月 10日 19時 04分 25秒]
の補足をさせてください。

> > KB197956, 217114, 243548 などを見ると、やはりVBScriptから
> > コンポーネント側の「ByRef X As (Variant以外の型)」な引数に、
> > 変数を「参照渡し」で呼び出す事はできないみたいですね。
>
> 前述のように、IDispatch(Ex)にはVariantの内部形式として
> 渡されてきますので、この部分を自力で処理できる言語で、
> 対応する処理を作れば、一応可能です。
> (ただ、普通はスクリプトからの呼び出しに対応したければ、
> Variantにするでしょうね)

この部分は、元発言の主旨を私が誤解しているかもしれません。

私が書いたのは、コンポーネント側があえて対応すれば
可能である。といった話です。
が、一般的には、そのようなことは しないでしょうし、
仕様としては、型の不一致エラーを返す方が妥当であるとも
思います。

ですから、原則としては、魔界の仮面弁士さんが書かれている
ように「できない」と考えた方がよいと思います。


あともう一点、
> 多分お気づきだとは思いますが、そのページで、
> VT_BYREF | VT_VARIANT のように書かれているものは、
> 実際の引数への参照が格納されている状態です。
> つまり、その LPVARIANT のポイント先には、

この LPVARIANTという表現は紛らわしいですね。
ここでは、渡されたVARIANTに格納されているポインタ
(pvarValメンバ)のことを LPVARIANTと表現しました。

あか さん 2005年 02月 11日 17時 35分 23秒

>魔界の仮面弁士さん

>セキュリティ設定を甘くすれば、一応は動作可能です。
ただし標準の設定だと、"WScript.Shell"の生成が拒否され、起動に失敗します。

IEのセキュリティを甘くすることでうまくいきました。
めちゃめちゃ悩んでたんで、ほんとにありがとうございました!!

>「ローカルリソースを使わなければならない理由」が特に無ければ、仕様を見直した方が良いと思いますよ。

すいません。。。これだけはゆずれないもんで。。。


shi さん 2005年 02月 10日 19時 04分 25秒

通りがかりで失礼いたします。
下で話題になっているメソッド呼び出しの引数の件ですが、
認識違いの点があるように感じますので、書かせていただきます。
(関連する発言をすべて読んだわけではありませんので、
もしも早とちりなどがありましたら、すみません)


(1)
参考にされている、
http://program.station.ez-net.jp/special/vc/atl-com/variant.asp
のページにある、VBScriptにおける引数の表は、
オブジェクトに渡された時点の状態とは違います。

ご存知かと思いますが、VBScriptからはオブジェクトの
実際のメソッドを呼び出すわけではなく、IDispatch(Ex)
インターフェイスのメソッドを呼び出しますね。
そして、その先は、オブジェクトが自分自身で本来の
メソッドを呼び出しているわけです。

そこの表にあるのは、オブジェクト側の処理によって、
実際のメソッドに配信された後の引数の状態であり、
この結果は、オブジェクトのInvoke(Ex)メソッドの
実装内容によっても変わってきます。

そこでは VisualC++ とだけ書かれていますが、そもそも
コンパイラだけで決まる話でもないので、
URLや標題から推測して、おそらくATLのIDispatchImplクラス
辺りを使った既定の実装の話ではないかと思います。
(ただし、ATLでなくても、一般的に使われている、
DispInvoke とか ITypeInfo::Invoke のようなヘルパーに
単純に処理を委ねていれば、そのページと同じ結果になるはずです)


(2)
多分お気づきだとは思いますが、そのページで、
VT_BYREF | VT_VARIANT のように書かれているものは、
実際の引数への参照が格納されている状態です。
つまり、その LPVARIANT のポイント先には、
期待通りの内部形式を持ったVariant型が存在している
ということです。


(3)
これまたお気づきかもしれませんが、VBScriptとVBの違い
というより、
実行時バインディングと事前バインディングの違いですね。

旧VBやVBAであっても、実行時バインディングで、かつ
Variant型のデータを使っていれば、VBScriptの場合と
同じように引数が渡されます。
ただし、呼び出しに使われるインターフェイスは違う場合も
ありますね。(IDispatch: or IDispatchEx)


(4)
これらの言語の実行時バインディング呼び出しでは、
そもそもプロシージャがどのように定義されているかなど、
呼び出し側では関知しませんので、
実際のプロシージャの定義がどうなっているかに関わらず、
呼び出し側のソースに記述された通りに引数を渡すことになります。

この時、変数を使って渡せば、常に値でなく参照が渡されます
(式の話はここでは例外として)。
実際の定義がByValとByRefのどちらかがわからないため、
その両者に対応するために、値でなく参照を渡すのは
当然の仕様であると個人的には思います。


といったわけで、実行時バインディングでクライアントから
IDispatch(Ex) へ渡される引数は、たとえば
 s = "a"
 obj.Func s
とした時は、コンポーネント側の定義に関係なく、常に
VT_VARIANT | VT_BYREF
であり、そのポイント先が、内部形式StringのVariant型です。

(式や定数で記述されていれば、参照を渡す必要もないので、
そのまま VT_BSTR で渡されますね)

そこから先は、オブジェクト側で、その引数を解析して、
実際のメソッドを、パラメータ定義に基づいて呼び出したり、
あるいはエラーを返すなどの対応をします。
(COMのヘルパー関数が利用されるケースも含みます)


IEとかShellオブジェクト関連でありがちな引数の型の問題は、
すべて、コンポーネント側で当然対応すべきことを していない
から、というのが原因だと思います。


魔界の仮面弁士 さん
> KB197956, 217114, 243548 などを見ると、やはりVBScriptから
> コンポーネント側の「ByRef X As (Variant以外の型)」な引数に、
> 変数を「参照渡し」で呼び出す事はできないみたいですね。

前述のように、IDispatch(Ex)にはVariantの内部形式として
渡されてきますので、この部分を自力で処理できる言語で、
対応する処理を作れば、一応可能です。
(ただ、普通はスクリプトからの呼び出しに対応したければ、
Variantにするでしょうね)

> VB6でDLLを作り、渡された値を RtlMoveMemoryでダンプして確認しているのですが、
> 上記の現象を再現できないんですよね……。問題なく VT_固有型 が渡されてます。

これも、VB側のIDispatch::Invokeの実装がそういう仕様である
(実メソッドを呼び出す前に変換している)のだと思います。

> ただ、VBからVariant値をAPIに渡す時に、再変換補正がかかってしまっているのかも
> 知れませんので、他言語で ActiveX DLLを書く必要がありそうです……。

VariantをAPIに参照渡しして補正がかかるなんてことが
ありましたっけ?

管理人むたぐち さん 2005年 02月 10日 19時 01分 39秒

AnHTTPDのCGIが落ちている(500エラーを返す)ときに、AnHTTPDを再起動するスクリプトです。
最近、コメント・トラックバックspamが海外から物凄い勢いでやってきて、
良く落ちるんですよ。困ったもんです。
で、これをタスクスケジューラで定期的に動かして対処してます。

スクリプトとしては小品ですが、公開。

Set xh = WScript.CreateObject("microsoft.xmlhttp")
Set WshShell=WScript.CreateObject("WScript.Shell")
Set Fs=WScript.CreateObject("Scripting.FileSystemObject")
Set Locator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set Service = Locator.ConnectServer
strURL="http://librage.mine.nu:2424/blog/blosxom.cgi"
On Error Resume Next
     xh.Open "GET", strURL, False
     xh.Send
     nStatus=xh.Status
     If nStatus = 500 Then
          Set oProcs = Service.ExecQuery _
          ("Select * From Win32_Process Where Description=""httpd.exe""")
          For Each oProc In oProcs
               sPath = oProc.ExecutablePath
               oProc.Terminate
          Next
          WshShell.Run """" & sPath & """"
          Set ts=Fs.OpenTextFile("restart_httpd.log",8)
          ts.WriteLine Date & " " & Time
          ts.Close
     End If
On Error Goto 0

管理人むたぐち さん 2005年 02月 10日 18時 56分 09秒

To: いりや さん

うちでもちゃんと動作しました。
mixi一部有料化で、メッセージが60日で消されるようになってしまったので、
これから重宝すると思います。ありがとうございます。

魔界の仮面弁士 さん 2005年 02月 10日 18時 13分 32秒

》あかさん 2005年02月10日 15時43分32秒
> ローカルExeファイル(メモ帳など)の起動方法について質問です。
「ローカルリソースを使わなければならない理由」が特に無ければ、仕様を見直した方が良いと思いますよ。

> WScriptを使ってるんですけど、ローカルで.jsや.vbsファイルを実行すると
WScript上でホストされる場合、HTML上で実行される場合、ASP上で実行される場合、WSCの場合、ScriptControl上とで、それぞれ使用可能なオブジェクトは異なります。

> Web上で実行すると、そんなオブジェクトはないって怒られます。
例えば、
 <input type="button" onclick="X()" value="test">
 <script type="text/vbscript">
 Sub X()
  CreateObject("WScript.Shell").Run "CALC.EXE"
 End Sub
 </script>
というHTMLがあった場合、セキュリティ設定を甘くすれば、一応は動作可能です。
ただし標準の設定だと、"WScript.Shell"の生成が拒否され、起動に失敗します。

> WScriptはHTMLでは利用できないのでしょうか?
「ファイルを開く/保存する」のダイアログを表示させてもよければ、
サーバ側から、*.wsfファイルなどをダウンロードさせるようにして、
WScriptの利用は可能です。ちょっとみっともないですけれどね。

あか さん 2005年 02月 10日 15時 43分 32秒

こんにちわ。
ローカルExeファイル(メモ帳など)の起動方法について質問です。

この行為が危ないのは重々承知なのですが、Webページに表示してあるリンク(「メモ帳を起動」など)をクリックすると、ローカルPC(Webサーバではない)のメモ帳を起動するようにしたいのですが、どのようにすればよろしいのでしょうか?
WebサーバのExeを起動するのではなく、アクセスしてきたPC(クライアント)のExeを起動させたいのですが。。。

WScriptを使ってるんですけど、ローカルで.jsや.vbsファイルを実行するとちゃんと実行されるんですが、Web上で実行すると、そんなオブジェクトはないって怒られます。
色々調べましたが、もうギブアップ。。。WScriptはHTMLでは利用できないのでしょうか?

すみませんが、誰かアドバイスいただけないでしょうか?
よろしくお願いします。

いりや さん 2005年 02月 09日 23時 20分 04秒

ご無沙汰しております。
本年もどうぞよろしくお願いいたします。

うちは会計年度が十一月から始まるのですが、期のはじめのピークをすぎてふと気がついてみれば第一四半期ももうおわり。こちらの方もずいぶんご無沙汰のような気がします。

またお邪魔します。

いりや

おまけ

ミクシィに参加されている人にはちょっと役立つかも。メッセージをファイル保存する goodie です。

http://iriyak.adam.ne.jp/arc/mixi/backupMessageBox_0.2.js

ばんのしゃーによかばんた さん 2005年 02月 08日 17時 15分 11秒

デスクトップの異常増殖はSP2の前から起きてたような気がします。

別件。
フォルダへのリンクをクィック起動に置いてエクスプローラを開くと、
通常は、フォルダバーの該当フォルダが展開されますが、
サブフォルダの数が100を超えていると、展開されないばかりか、
「+」も付きません。これでは展開できません。ぶつぶつ。。。

なので、XXXに対して、XXX_というダミーフォルダを作って、これを開く。
その上にXXXが「+」付きで現れるので、そっちを展開する。なんてね。

ところで、
ペースト側のスクリプトから、コピーかカットかの区別を付ける方法は
ありませんか?


ばんのしゃーによかばんた さん 2005年 02月 08日 17時 14分 44秒

>kai714 さん 2005年 02月 04日 13時 22分 17秒
>ADODB.Streamというものを使うとバイナリファイルからバイト列が読み込める
>ということを知り、4バイトごと読み込んで4バイト整数や4バイト実数を
>求めるスクリプトを書いてみたのですが、もっと良い(速い)方法は無いもの
>でしょうか。VBSでなくJScriptでもよいのですが。

そんなに性能クリティカルなら、

Byte2Lng=AscB(MidB(buf,1,1))+AscB(MidB(buf,2,1))*256+AscB(MidB(buf,3,1))*65536+AscB(MidB(buf,4,1))*16777216

のようにに変えて、関数呼び出しを止め、インライン処理にすれば、
相当速くなるのではないでしょうか。


ごん助 さん 2005年 02月 08日 13時 13分 31秒

魔界の仮面弁士さん、ご助言ありがとうございます。サーバの管理者に連絡しましたら、なんとwsfファイルが入っているフォルダは1つ上の階層にあって、というより、リンクがそもそもは存在しないフォルダへアクセスするようになっていたということです。
ブラウザはいまだにネスケを使用しています。なにしろシロウトなものですから、ワラをもつかむ心地でここに書き込みました。魔界の仮面弁士さん、いろいろ専門的なサゼスチョンを本当にありがとうございました。わたしも勉強中の身なので、もうちょっとましなトラブルで仮面弁士さんのおっしゃるようなレベルで問題解決ができるようがんばりたいと思います。ありがとうございました。

むちゃ さん 2005年 02月 08日 10時 48分 46秒

125-38 の追記です。

英語サイトの
http://webfx.eae.net/dhtml/dhtmlmenu4/simpledemo.html
では、createPopup を利用したサンプルが見れます。
上記のダウンロードは、
http://webfx.eae.net/dhtml/dhtmlmenu4/demos.html
の最下行にある「Download」から。
Zip 書庫を展開したサブフォルダの中の「menu4.js」がメインで動いているようです。

サンプルでは、クラス化を施して複雑な処理をしていますがやろうとしていることは同じであると思います。

むちゃ さん 2005年 02月 08日 09時 58分 18秒

To: 管理人むたぐち さん

> To: むちゃ さん
>
> > 現在、createPopup() でメニューを作成中ですが、何故かポップアップのウィンドウが、マウス操作中に突然消えてしまうんです。
> > mouseover mouseout イベント時のスクリプト操作をやめると消えなくなるのですが・・・
>
> WinXP pro SP2で再現しました。
> SP2ではcreatePopupメソッドの仕様が変更になったので、その影響があるのかも。
> 非SP2な環境な方に、追試をお願いしたいです。

私の環境は、Windows XP SP1 Home/Pro で再現しています。

ちなみに、あれから色々試してみたところ、
Popuup オブジェクトにて表示された window の onunload イベントをいじくると、
何故か正常に動作するようになります。なぜ??(~-~)
ですが、組み方によっては効果が見られない場合もありました。

<html lang=ja>
<head>
<title>xxxxx - [xxxxx]</title>

<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Cache-Control" content="no-store">
<meta http-equiv="Expires" content="0">
<meta http-equiv="imagetoolbar" content="no">

<script language="javascript">
function showPopup(id)
{
   try {
     if(!window.createPopup) return;
     var objPopup = window.createPopup();
     var objElement = document.getElementById(id);
     var objBody = objPopup.document.body;

     objBody.innerHTML = objElement.outerHTML;
     objPopup.show(100, 100, 100, 100, document.body);

     var objTarget = objPopup.document.getElementById(id);
     objPopup.show(100, 100, objTarget.offsetWidth, objTarget.offsetHeight, document.body);

     // Popup オブジェクトの onunload イベントに空の関数を割り当てると
     // 何故か消えなくなる。
     objBody.onunload = function(){};
   }
   catch (e) {
     alert(e.description);
   }
}
function Set(objElement, strColor)
{
   // この操作をコメントアウトするか、タグの onmouseover onmouseout 属性を削除すると消えなくなる
   objElement.style.backgroundColor = strColor;
}
function test()
{
   alert(event.fromElement.tagName);
}
</script>

</head>

<body bgcolor="red" oncontextmenu="return false;" onselectstart="return false;" leftmargin="0" topmargin="0">

<button onclick="showPopup('IDM_FILE');" HIDEFOCUS>ポップアップの表示</button>

<span style="display:none;">
<div id="IDM_FILE">
<table border="1" bordercolor="BUTTONFACE" cellspacing="0" cellpadding="0">
<tr onmouseover="parent.Set(this,'HIGHLIGHT');" onmouseout="parent.Set(this,'');">
<td></td><td>全て選択</td><td></td>
</tr>
<tr onmouseover="parent.Set(this,'HIGHLIGHT');" onmouseout="parent.Set(this,'');">
<td></td><td>全て選択</td><td></td>
</tr>
<tr onmouseover="parent.Set(this,'HIGHLIGHT');" onmouseout="parent.Set(this,'');">
<td></td><td>全て選択</td><td></td>
</tr>
</table>
</div>
</span>
</body>
</html>

魔界の仮面弁士 さん 2005年 02月 08日 09時 21分 32秒

》ごん助 さん 2005年02月07日 18時09分23秒
> 上記のようなwsfファイルをWeb上にアップロードしてダウンロードすると、

wsfファイルを、IEから直接ダウンロードできるかどうかは、
Webサーバ側の「HTTP応答ヘッダ」次第です。サーバ側の設定ですね。
(XMLHTTP等を用いて、直接 HTTP/HTTPS の通信を行う場合は別ですが)

サーバの管理者に連絡して、そのサーバから、
 Content-Typeヘッダで、"application/x-download"などが、
 Content-Dispositionヘッダで、"inline; filename=test.wsf"などが
返されるようになっているか、サーバ側設定を確認してみてください。

自分で調整する場合は、IISならば、メタデータの設定で指定できます。
Apatchならば、.htaccess でしょうか。(詳細はヘルプで確認してください)

なお、サーバ側スクリプトで調整するなら、例えばaspの場合は、
Response.ContentType = "application/x-download"
Response.AddHeader "Content-Disposition", "inline; filename=test.wsf"
のような指定を行う事もできます。


> ファイルの中身が以下のようになってしまいます。
あれ、なんだか妙なHTMLですね。bodyタグも省略されていますし。

ただ、『<H1>Not Found</H1>』のような記述が見られる事から、これは何らかの理由で、そのアップロードしたwsfファイルにアクセスできていないような気もします。

指定したURLが間違っていたり、あるいは(認証が必要なサイトの場合)ログインが行われていない、という事はありませんでしょうか。

ごん助 さん 2005年 02月 07日 18時 09分 23秒

<job>
<script language="VBScript">

    (省略)

</script>
</job>

上記のようなwsfファイルをWeb上にアップロードしてダウンロードすると、ファイルの中身が以下のようになってしまいます。本当はwsfファイルをそのままの形でダウンロードしたいのですが、どうしらよいでしょう?

HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=ISO-8859-1"><TITLE>Not Found</TITLE></HEAD>
<H1>Not Found</H1> The requested object does not exist on this server. The link you followed is either outdated, inaccurate, or the server has been instructed not to let you have it. Please inform the site administrator of the <A HREF="http://dbhost1/mofa/jokanhp/hp2004/exe/test_sample.htm">referring page</A>.

kai714 さん 2005年 02月 07日 18時 04分 36秒

> 魔界の仮面弁士 さん 2005年 02月 07日 17時 26分 30秒

>現在、どの程度の速度になっていて、それをどの程度まで
>短縮させたいのか、といった目標値はありますか?

特にはないです。VBAと比較して遅いなと思ったものですから。

>> VBSでなくJScriptでもよいのですが。
>JScript.NET にすれば、厳密な型が使えますよ。

>バイト配列から、4バイト整数や4バイト実数を得たいなら、
> var I : int = BitConverter.ToInt32(myBinary, 0);
> var F : float = BitConverter.ToSingle(myBinary, 0);
>という感じで、簡単に変換できます。

>また、バイナリファイルからの変換なら、 BitConverter クラスよりも、
>BinaryReader クラスの ReadInt32 / ReadSingle メソッドの方が便利。

なるほど。Jscript.NETというものがあるとは知りませんでした。
.NET環境のないPCにも配るので今回の例では使えませんが、個人環境なら
かなり強力そうですね。一度勉強してみます。

ありがとうございました。

魔界の仮面弁士 さん 2005年 02月 07日 17時 26分 30秒

》kai714 さん 2005年02月07日 15時22分17秒
> > 速度上で問題があるわけですか?
> 4バイト整数ならそうでもないのですが、実数になると結構な計算量になるんです。
> それが数万回くりかえしておきるものですから。

現在、どの程度の速度になっていて、それをどの程度まで
短縮させたいのか、といった目標値はありますか?


> VBSでなくJScriptでもよいのですが。
JScript.NET にすれば、厳密な型が使えますよ。

バイト配列から、4バイト整数や4バイト実数を得たいなら、
 var I : int  = BitConverter.ToInt32(myBinary, 0);
 var F : float = BitConverter.ToSingle(myBinary, 0);
という感じで、簡単に変換できます。

また、バイナリファイルからの変換なら、 BitConverter クラスよりも、
BinaryReader クラスの ReadInt32 / ReadSingle メソッドの方が便利。

ばんのしゃーによかばんた さん 2005年 02月 07日 17時 23分 36秒

1ファイル化しました。
任意のVBSファイルに組み込むことが出来ます。:-):-):-)

ファイル(複数可)を選択/コピーしてから
PASTE.VBSを起動するとファイル名を受け取って処理します。

PASTE.VBS
――――――――――――――――――――――――――――――――――――――
If WScript.Arguments.Count=0 Then
 Set Shell=CreateObject("Shell.Application")
 Set Folder=Shell.NameSpace(Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"\")))
 Set FolderItem=Folder.Items.Item(WScript.ScriptName)
 For Each Verb In FolderItem.Verbs
  If Verb.Name="貼り付け(&P)" Then Exit For
 Next
 If Not IsEmpty(Verb) Then
  Verb.DoIt
  WScript.Quit
 End If
End If
For Each arg In WScript.Arguments
 WScript.Echo arg
Next
――――――――――――――――――――――――――――――――――――――
※あと、シフトキーの状態が分かればなぁ。。。


蒼那 憐 さん 2005年 02月 07日 16時 14分 34秒

管理人むたぐちさん

ありがとうございます。
スリープに関してはDHCPに変更したときにゲートウェイのパラメータが
一時的に消滅することとIPのリリースを待つための処理のために組み込もうと思ったのですがそれ以前に、
ControlEnabler True
          UpdateInfo("<font color=""red"" >" & strDevice & "をDHCPに変更中...</font>")
          '変更処理
          Set colNetAdapters = objWMIService.ExecQuery _
          ("Select * From Win32_NetworkAdapterConfiguration " _
               & "Where Description='" & strDevice & "'", , 48)
          For Each objNetAdapter In colNetAdapters
               errEnable = objNetAdapter.EnableDHCP()
               If errEnable = 0 Then
                    UpdateInfo("<font color=""red"" >変更完了!</font>")
               Else
                    MsgBox "エラーが発生しました。" & vbCrLf & "No." & errEnable & "/" & Err.Description,vbExclamation,"IP Setting"
                    UpdateInfo("<font color=""red"" >エラーが発生しました。<br>No." & errEnable & "</font>")
               End If
              
               ControlEnabler False
          Next
このような感じで処理を書いてあるのですが、
静的IPの状態からDHCPに切り替えると
UpdateInfo("<font color=""red"" >変更完了!</font>")
この行がスルーされているような感じでメッセージが変更中から変わらない
状況に陥ってしまいました。
ただ、処理は続行されている様で、DHCPへの変更そのものは完了しています。
複数のマシンで検証していますがどのマシンでも同様の症状になります。

これって、何が原因だか、分かりますでしょうか?
検証環境はXPのSP2です。

kai714 さん 2005年 02月 07日 15時 22分 17秒

> むたぐち さん

> ご紹介いただいたサンプルが、いちばん素直な解だと思ったんですが、
> 速度上で問題があるわけですか?

4バイト整数ならそうでもないのですが、実数になると結構な計算量になるんです。
それが数万回くりかえしておきるものですから。
やはり、Variant型しかないからしょうがないんでしょうね。
VBAだとちゃんと型があるので、LongやSingleの変数で読み込むだけでいいんです
けど。

魔界の仮面弁士 さん 2005年 02月 07日 10時 50分 54秒

VBScript と COM との連携に関する資料を探す場合には、
ASP や MTS 関連の情報を探った方が近道のようです。

KB197956, 217114, 243548 などを見ると、やはりVBScriptから
コンポーネント側の「ByRef X As (Variant以外の型)」な引数に、
変数を「参照渡し」で呼び出す事はできないみたいですね。

また、Microsoftの J.D. Meier氏が書かれた、
「ASP コンポーネント ガイドライン(ASP Component Guidelines)」の
“パラメータの引き渡し(Passing Parameters)”にも、関連情報がありました。
http://www.microsoft.com/japan/msdn/columns/server/server01242000.asp#pass
http://web.archive.org/web/20030615030200/msdn.microsoft.com/library/en-us/dnserv/html/server01242000.asp


》ばんのしゃーによかばんた さん 2005年02月06日 16時53分22秒
> VBScriptで、VARIANTに変数を渡したとき、と、
> VBで、LPVARIANTに変数を渡したとき、
> が変ですね。
この件、いまだに検証が終わらないんですよ。

VB6でDLLを作り、渡された値を RtlMoveMemoryでダンプして確認しているのですが、
上記の現象を再現できないんですよね……。問題なく VT_固有型 が渡されてます。

ただ、VBからVariant値をAPIに渡す時に、再変換補正がかかってしまっているのかも
知れませんので、他言語で ActiveX DLLを書く必要がありそうです……。


> VBScriptもVBも、変数を渡すと変なので、変数は括弧で囲んで渡す、
> というのが安全策でしょうか。
ただし、しかし、そのルールが使える場面というのは限定されますよね。
括弧を付ける事で、正しく動作しなくなってしまうケースもありますから。

COM側が「input Parameters」であれば、括弧で渡しても良いのですが、
「output Parameters」だとすれば、そういうわけにもいきません。

意味を十分に理解した上で括弧を付けるのならば構いませんが、無条件に
括弧を付けて呼び出すという短絡的な覚え方は避けねばならず、できる限り
適切な場面でのみ括弧を付けるようにコーディングするべきかと思います。


例えば、先の ExecWBメソッドで OLECMDID_ZOOM を指定した場合。

Const OLECMDID_ZOOM = 19
Const OLECMDEXECOPT_DODEFAULT = 0

L = CLng(4) '4:最大サイズ
V = Empty  'output専用引数に渡すので、中身は何でも良い
MsgBox TypeName(L)
IE.ExecWB OLECMDID_ZOOM, OLECMDEXECOPT_DODEFAULT, L, V 'サイズが変更される
MsgBox TypeName(V) & vbCrLf & CStr(V) '正常動作。変数Vは整数の4(内部Long型)になる。

L = CLng(2) '2:通常サイズ
V = Empty  'output専用引数に渡すので、中身は何でも良い
IE.ExecWB (OLECMDID_ZOOM), (OLECMDEXECOPT_DODEFAULT), (L), (V) 'サイズが変更される。
MsgBox TypeName(V) & vbCrLf & CStr(V) '★変数Vの中身が、Emptyのまま変わらない★

VIM さん 2005年 02月 07日 08時 59分 19秒

>TAK さん

dcomを使えばOKです。
過去ログ引用です。
http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list28.shtml
>管理人むたぐち さん (mutaguchi@roy.hi-ho.ne.jp) 2001年 01月 21日 20時 41分 23秒
> ○WMIでリモート管理 Win98-Win2000編 Part2
>Win98のDCOMのデフォルト設定では、リモートアクセスの許可がされていないので、
>まずその設定をおこないます。
>そのためには、dcomcnfg.exeというプログラムを使うのですが、標準では添付されていないので、
>http://www.asia.microsoft.com/japan/com/dcom/dcom98/dcom13.asp
 から
>「DCOM98コンフィグレーション・ユーティリティ」をダウンロードします。
>DCOMのバージョンが異なっていると動作しないので、最新版のDCOM98もダウンロードしておくと良いでしょう。(現時点でver 1.3が出てます)
>インストール・再起動がすめば、dcomcnfg.exeを実行し、
>「既定のプロパティ」タブを開きます。
>「このコンピュータ上で分散COMを使う」にチェックが入っていることを確認し、
>既定の認証レベルを「接続」にします。
>次に「既定のセキュリティ」タブを開いて、「リモート接続を使用する」にチェックを入れます。
>「OK」をクリックすると再起動を促されるので再起動します。

あとは、DCOMCnfgの[Microsoft Excelアプリケーション]のIDタブの欄を、
「対話ユーザー」(interactive)に設定します。

あらかじめ、Excelを起動するPC(HOGEHOGE)にログオンしておきます。
実行元のPCにログオンして、以下のスクリプトを流します。
With CreateObject("Excel.Application","HOGEHOGE")
     .Visible = True
     .Workbooks.Add.Worksheets(1).Range("A1").Value = Now
End With
HOGEHOGEにExcelが起動しているはずです。

VIM さん 2005年 02月 07日 08時 59分 05秒

>TAK さん

dcomを使えばOKです。
過去ログ引用です。
http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list28.shtml
>管理人むたぐち さん (mutaguchi@roy.hi-ho.ne.jp) 2001年 01月 21日 20時 41分 23秒
> ○WMIでリモート管理 Win98-Win2000編 Part2
>Win98のDCOMのデフォルト設定では、リモートアクセスの許可がされていないので、
>まずその設定をおこないます。
>そのためには、dcomcnfg.exeというプログラムを使うのですが、標準では添付されていないので、
>http://www.asia.microsoft.com/japan/com/dcom/dcom98/dcom13.asp
 から
>「DCOM98コンフィグレーション・ユーティリティ」をダウンロードします。
>DCOMのバージョンが異なっていると動作しないので、最新版のDCOM98もダウンロードしておくと良いでしょう。(現時点でver 1.3が出てます)
>インストール・再起動がすめば、dcomcnfg.exeを実行し、
>「既定のプロパティ」タブを開きます。
>「このコンピュータ上で分散COMを使う」にチェックが入っていることを確認し、
>既定の認証レベルを「接続」にします。
>次に「既定のセキュリティ」タブを開いて、「リモート接続を使用する」にチェックを入れます。
>「OK」をクリックすると再起動を促されるので再起動します。

あとは、DCOMCnfgの[Microsoft Excelアプリケーション]のIDタブの欄を、
「対話ユーザー」(interactive)に設定します。

あらかじめ、Excelを起動するPC(HOGEHOGE)にログオンしておきます。
実行元のPCにログオンして、以下のスクリプトを流します。
With CreateObject("Excel.Application","HOGEHOGE")
     .Visible = True
     .Workbooks.Add.Worksheets(1).Range("A1").Value = Now
End With
HOGEHOGEにExcelが起動しているはずです。

ちゃっぴ さん 2005年 02月 07日 00時 51分 17秒

> 一方、WSHには「リモートWSH」という仕組みがあり、これを利用すると
> ネットワークを介して他PC上でスクリプトを動作させることが可能です。
> 詳しくはWSHのリファレンスおよびWikiの記事をどうぞ。
> http://winscript.s41.xrea.com/wiki/index.php?%5B%5BRemoteWSH%5D%5D

これですと、Remote Machineの設定が必要になるので
WMIのWin32_Process Class の Create Method 使用したほうが
いいのではないでしょうか?

ビッグフットと結婚したよ。それから Service Pack 2 にコンピュータを消されちゃった。
http://www.microsoft.com/japan/technet/community/columns/scripts/sg1104.mspx

Excelを起動するだけなら、これだけで事足りますし、
Excelを制御したいというなら、別途Excel制御用のVBSを
用意すればいいだけですし・・・

管理人むたぐち さん 2005年 02月 06日 21時 40分 33秒

To: TAK さん

> イントラネット内の他PCのエクセルを起動させようとしていますが、
> 頭で、接続できないエラーになります。

> Set objxls=createobject("Excel.Application","FS")

VB6のCreateObject関数の第二引数は、以下のURLの記事によると次のようなものらしいです。
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9811/vb6/
> ■CreateObject関数の機能拡張 
>  CreateObjectで,マシン名を省略可能な第二引数として指定できるようになった.APIのCoCreateInstanceExに対応したもの.DCOMなどの使用時に便利.

というわけで、DCOMの設定が必要になるんだと思います。
が、VBSのCreateObject関数の第二引数を利用して、他のPCのアプリケーションを
操作した例を、私は見たことがありません。
もしかするとVBS(on WSH)では無効なのかもしれないですね。

一方、WSHには「リモートWSH」という仕組みがあり、これを利用すると
ネットワークを介して他PC上でスクリプトを動作させることが可能です。
詳しくはWSHのリファレンスおよびWikiの記事をどうぞ。
http://winscript.s41.xrea.com/wiki/index.php?%5B%5BRemoteWSH%5D%5D


To: 蒼那 憐 さん

> WSHであれば『Wscript.Sleep』を利用して処理の停止時間を作成できますが
> HTAで同様の処理を行う方法って、あるのでしょうか?

windowオブジェクトのsetTimeoutメソッド、clearTimeoutメソッドを利用すれば可能です。
詳しくはMSDNのリファレンスをどうぞ。

http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpisdk/dhtml/references/methods/setTimeout.asp

# このリファレンスはいつまでたってもIE5以降に追加された機能が載りませんね。
# 英語版しかないです。


To: kai714 さん

> ADODB.Streamというものを使うとバイナリファイルからバイト列が読み込める
> ということを知り、4バイトごと読み込んで4バイト整数や4バイト実数を
> 求めるスクリプトを書いてみたのですが、もっと良い(速い)方法は無いもの
> でしょうか。

ご紹介いただいたサンプルが、いちばん素直な解だと思ったんですが、
速度上で問題があるわけですか?


To: むちゃ さん

> 現在、createPopup() でメニューを作成中ですが、何故かポップアップのウィンドウが、マウス操作中に突然消えてしまうんです。
> mouseover mouseout イベント時のスクリプト操作をやめると消えなくなるのですが・・・

WinXP pro SP2で再現しました。
SP2ではcreatePopupメソッドの仕様が変更になったので、その影響があるのかも。
非SP2な環境な方に、追試をお願いしたいです。

ばんのしゃーによかばんた さん 2005年 02月 06日 20時 06分 51秒

ちょっとまだ具体的な用途を考えていないのですが、
何かに使えるのではないか、というアイデアです。

今までVBSファイルはドロップ/ペーストしたファイル名は取得できましたが、
それ以外で、コピーされたファイル名を取得することは出来ませんでした。

複数のファイルをコピーして、PASTE.VBSを単に起動してみてください。

PASTE.VBS
――――――――――――――――――――――――――――――――――――――
Set Shell=CreateObject("Shell.Application")
Set Folder=Shell.NameSpace(Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"\")))
Folder.Items.Item("ARGS.VBS").InvokeVerb("paste")
――――――――――――――――――――――――――――――――――――――
ARGS.VBS
――――――――――――――――――――――――――――――――――――――
For Each arg In WScript.Arguments
 WScript.Echo arg
Next
――――――――――――――――――――――――――――――――――――――



ばんのしゃーによかばんた さん 2005年 02月 06日 20時 06分 34秒

私の場合、ここへの記事は、デスクトップにhoge.txtで作って、
投稿したら、とあるフォルダに放り込むのですが、同名ファイルがあると、
名前に番号のサフィックスを付けて(hoge2.txt)、放り込み直したり、と不便です。
そこで、以下のVBScriptを作りました。
――――――――――――――――――――――――――――――――――――――
Option Explicit
Dim dst
dst="C:\Folder"

Dim fso
Dim arg

Set fso=CreateObject("Scripting.FileSystemObject")
If Right(dst,1)<>"\" Then dst=dst & "\"

For Each arg In WScript.Arguments
 call FileProc(fso.GetFile(arg))
Next
WScript.Quit

Sub FileProc(File)
Dim k
Dim alias
Dim ext
For k=1 To 999
 If k=1 Then
  alias=File.Name
  Call FileOP(File,dst)
 Else
  alias=fso.GetBaseName(File.Name) & k
  ext=fso.GetExtensionName(File.Name)
  If ext<>"" Then alias=alias & "." & ext
  Call FileOP(File,fso.BuildPath(dst,alias))
 End If
 If Err.Number=0 Then Exit For
 If vbCancel=MsgBox(Err.Number&" "&Err.Description&vbCrLf&dst&vbCrLf&alias,_
   vbOkCancel) Then WScript.Quit
Next
End Sub

Sub FileOP(File,dst)
On Error Resume Next
Call File.Move(dst)
End Sub


管理人むたぐち さん 2005年 02月 06日 17時 47分 29秒

To: ばんのしゃーによかばんた さん 2005年 02月 06日 16時 52分 17秒

> エクスプローラのフォルダバーに「デスクトップ」がいっぱい出来ます。
> 発生条件は不明です。

某所でも話題になっていました。
私の環境でも発生するんですよね、これ。SP2をあてた、XP Pro/Homeで発生するようです。

私は、リムーバブルドライブが鍵を握っていると推測していますが、再現性が取れたらまた報告します。
エクスプローラがフォーカスを持っているときには発生しない事実も、
何か謎を解明する秘密が隠されている気がします。


最近ついた質問投稿は、後ほど(今晩)返信しますのでお待ちください。

ばんのしゃーによかばんた さん 2005年 02月 06日 16時 53分 22秒

EZ-NET 研究室: VARIANT 型を受け取る際の注意
http://program.station.ez-net.jp/special/vc/atl-com/variant.asp

を見ると、
VBScriptで、VARIANTに変数を渡したとき、と、
VBで、LPVARIANTに変数を渡したとき、
が変ですね。
同じ象限でなく、対角が変なのは、必然性のないことの証左なのでは。

VT_BYREFにする必然性がないのに、よく考えないでインプリメントしたら、
たまたま出来ちゃった仕様、なのではないでしょうか。

インターフェース設計では、原則を設けて、バリエーションを
少なくするのが、正道だと思います。
値型に出来るものは、参照型にしない。とか。

VBScriptもVBも、変数を渡すと変なので、変数は括弧で囲んで渡す、
というのが安全策でしょうか。


ばんのしゃーによかばんた さん 2005年 02月 06日 16時 52分 53秒

カレントディレクトリについて。

以下のカレントディレクトリは?

[Q1] VBSファイルをダブルクリックしたとき。
[Q2] リンク/メニューからVBSファイルを起動したとき。
[Q3] リンク/メニューからVBSファイルのショートカットを起動したとき。
[Q4] VBSファイルにドロップしたとき。
[Q5] VBSファイルのショートカットにドロップしたとき。

Q1,Q3は順当。Q2,Q4,Q5は意外です。特にQ5は吃驚。

Q2,Q4,Q5はデスクトップエクスプローラ空間(?)のカレントディレクトリです。
このカレントディレクトリは、SendToのメール受信者を起動すると
MAPIのフォルダに移ります。戻し方は分かりません。

ただし、これはエクスプローラの場合です。
IEのQ2,Q4,Q5はデスクトップになります。

このQ2,Q4,Q5の仕様に、メリットはないと思います。
出来れば順当な仕様に直してもらいたいものです。特にQ5。

スクリプトで、カレントディレクトリを使うときは、
MAPIのフォルダにファイルを作ったりしないよう、気を付けましょう。


ばんのしゃーによかばんた さん 2005年 02月 06日 16時 52分 17秒

エクスプローラのフォルダバーに「デスクトップ」がいっぱい出来ます。
発生条件は不明です。
階層の下で仕事をして、上に戻ると出来てることがよくあります。
実害はないようですが、鬱陶しいです。

エクスプローラのアドレスバーが名前欄だけで、値欄が表示されません。
IEだとちゃんと出るのに。なぜでしょう。


ばんのしゃーによかばんた さん 2005年 02月 06日 16時 51分 46秒

>ばんのしゃーによかばんた さん 2004年 12月 26日 16時 03分 02秒
>はい、では、hidden explorer方式。

hidden ie方式もあります。

Set Shell=CreateObject("Shell.Application")
Set Folder=Shell.NameSpace(フォルダ)
の代わりに、

Set ie=CreateObject("InternetExplorer.Application")
ie.Navigate フォルダ
Do While ie.Busy Or ie.ReadyState<>4
 WScript.Sleep 100
Loop
Set Shell=ie.Document.Application
Set Folder=ie.Document.Folder

作業

ie.Quit


まろん さん 2005年 02月 05日 21時 10分 15秒

>魔界の仮面弁士 さん 2005年 01月 30日 20時 12分 46秒
こんにちは、まろんです。
先日はXMLHTTPコンポーネントについて、アドバイスありがとうございました。
魔界の仮面弁士さんにアドバイス頂いたとおり試しておりまして、
今やっと、光が見えてきたところです。
「InetSpy」のツールを使って、ブラウザから手動でアップロードしたときのデータと、
XMLHTTPコンポーネントを使用してデータを送った時と、ログを見比べているのですが、
異なる点が2点あり、その2点をどうしても解決することが出来ません。

■送信するバイナリデータが文字化けしてしまう。
sendキーで送信しているバイナリデータを「InetSpy」で確認すると、文字化けしています。
手動時のログでは文字化けしていないところを見ると、手動でアップロードボタンを押す時には
、裏で文字コードの変換が行われているのではないかと思われます。
というわけで、何らかの文字コードに変換する必要があるようですが、
文字コードの変換の仕方がわかりません。

■cookie情報の取得の仕方がわからない
POST送信する際に、どうやらcookie情報も乗せないといけないようなのですが、
cookie情報を取得する方法はあるのでしょうか?

以上、2点おわかりになりましたら、教えて頂きたく。
よろしくお願い致します。




むちゃ さん 2005年 02月 05日 10時 44分 43秒

現在、createPopup() でメニューを作成中ですが、何故かポップアップのウィンドウが、マウス操作中に突然消えてしまうんです。
mouseover mouseout イベント時のスクリプト操作をやめると消えなくなるのですが・・・
どなたかご教授ください。

<html lang=ja>
<head>
<title>xxxxx - [xxxxx]</title>

<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Cache-Control" content="no-store">
<meta http-equiv="Expires" content="0">
<meta http-equiv="imagetoolbar" content="no">

<script language="javascript">
function showPopup(id)
{
     try {
          if(!window.createPopup) return;
          var objPopup = window.createPopup();
          var objElement = document.getElementById(id);
          var objBody = objPopup.document.body;

          objBody.innerHTML = objElement.outerHTML;
          objPopup.show(100, 100, 100, 100, document.body);

          var objTarget = objPopup.document.getElementById(id);
          objPopup.show(100, 100, objTarget.offsetWidth, objTarget.offsetHeight, document.body);
     }
     catch (e) {
          alert(e.description);
     }
}
function Set(objElement, strColor)
{
     // この操作をコメントアウトするか、タグの onmouseover onmouseout 属性を削除すると消えなくなる
     objElement.style.backgroundColor = strColor;
}
function test()
{
     alert(event.fromElement.tagName);
}
</script>

</head>

<body bgcolor="red" oncontextmenu="return false;" onselectstart="return false;" leftmargin="0" topmargin="0">

<button onclick="showPopup('IDM_FILE');" HIDEFOCUS>ポップアップの表示</button>

<span style="display:none;">
<div id="IDM_FILE">
<table border="1" bordercolor="BUTTONFACE" cellspacing="0" cellpadding="0">
<tr onmouseover="parent.Set(this,'HIGHLIGHT');" onmouseout="parent.Set(this,'');">
<td></td><td>全て選択</td><td></td>
</tr>
<tr onmouseover="parent.Set(this,'HIGHLIGHT');" onmouseout="parent.Set(this,'');">
<td></td><td>全て選択</td><td></td>
</tr>
<tr onmouseover="parent.Set(this,'HIGHLIGHT');" onmouseout="parent.Set(this,'');">
<td></td><td>全て選択</td><td></td>
</tr>
</table>
</div>
</span>
</body>
</html>

ばんのしゃーによかばんた さん 2005年 02月 04日 20時 05分 19秒

>ばんのしゃーによかばんた さん 2005年 02月 01日 19時 20分 52秒
>ところで、TTSのSpeechEngineについて。
>2000にはSamさん一人が標準で付いていましたが、私のXPには、Samさんが居ません。
>代わりに、プレインストール元のToshibaのお兄さんお姉さんたちが居ます。
>他のXPではどうでしょうか?誰か標準で付いていますか?

「音声認識のプロパティ」にはSamさん一人がいました。
そして、
Set SAPI=CreateObject("SAPI.SPVoice")
では、Samさんがしゃべります。

しかし、
Set TTS=CreateObject("TextToSpeech.TextToSpeech.1")
では、Samさんが居ません。代わりにお兄さんたちが居ます。

2000とXPでは、Samさんのファイル拡張子も異なっているし、
互換性がなくなったのかなぁ。

XP
C:\Program Files\Common Files\SpeechEngines\Microsoft\TTS\1033\sam.spd
C:\Program Files\Common Files\SpeechEngines\Microsoft\TTS\1033\sam.sdf

2000
D:\Program Files\Common Files\Microsoft Shared\SpeechEngines\TTS\sam.cfg
D:\Program Files\Common Files\Microsoft Shared\SpeechEngines\TTS\sam.vce

みなさんのXPでは、TTSやMSAgentでSamさんが喋るんですよね。
なんか設定が足りないのかなぁ。


ばんのしゃーによかばんた さん 2005年 02月 04日 20時 04分 41秒

>魔界の仮面弁士 さん 2005年 02月 02日 17時 45分 20秒
>あれ? 当方では期待動作しましたよ。
>Integer を渡していたりはしませんか?
>VBScriptって、0〜4 の範囲の Long型定数を作れましたっけ。

VBScriptでは、1&が通らないので&H1&でテストして、
それがIntegerなのに気が付いて、&H10001-&H10000でテストしたのですが、
&H1&の結果を&H10001-&H10000の結果と混同していたようです。

しかし、Longだと言っているのに、何でIntegerなんでしょうね。
全く摩訶不思議な世界だ。ぶつぶつ。。。
「右」と書いて「ひだり」と読ませるような「極悪の仕様」です。

もう一度&について復習すると、
&H8000&〜&HFFFF&にだけ効果があります。これらをShortの負数にするか、
Longの正数にするかを区別するためだけの表記です。
しかも、&H8000だけは例外で、\xFFFF8000か\x00008000で両方Longです。
なんとも紛らわしい。赤色で黄色と書くてあるようです。何色ですか?
に何と答えます?


kai714 さん 2005年 02月 04日 13時 22分 17秒

はじめまして。

ADODB.Streamというものを使うとバイナリファイルからバイト列が読み込める
ということを知り、4バイトごと読み込んで4バイト整数や4バイト実数を
求めるスクリプトを書いてみたのですが、もっと良い(速い)方法は無いもの
でしょうか。VBSでなくJScriptでもよいのですが。

ちなみに4バイト整数(IEEEリトルエンディアン)の場合はこんなFunctionで
整数に戻しています。

Function Byte2Lng(buf)
'bufは4バイトのバイト列
Dim num,asc1,i
num = 0
For i = 1 to 4
     asc1 = AscB(MidB(buf,i,1))
     num = num + asc1 * 256^(i-1)
Next
Byte2Lng = num
End Function

蒼那 憐 さん (flamberage[nospam]@naiads.net) 2005年 02月 04日 01時 22分 45秒

はじめまして、蒼那と言います。
現在、こちらで公開されている『ネットワークドライブの接続(HTA)』
をベースに、処理を変更して、WMIを利用してIPアドレスの変更を行う
HTAを作成しています。
そこで、現在右側のステータス表示の部分にネットワークのデバイス等
状況表示を行っているのですが、DHCPに切り替えを行った場合に
IPのリリースされるまでの時間をWaitとしてはさんで処理を続行しないと
エラーになることが分かったのですが、
WSHであれば『Wscript.Sleep』を利用して処理の停止時間を作成できますが
HTAで同様の処理を行う方法って、あるのでしょうか?
開発言語はVBSを利用しています。
どなたか、分かる方がいらっしゃればご教授お願いいたします

TAK さん 2005年 02月 03日 19時 36分 14秒

こんばんは
イントラネット内の他PCのエクセルを起動させようとしていますが、
頭で、接続できないエラーになります。原因、対応のご教示お願いしたく
ターゲットコンピュータとは、相手の共有フォルダーが見える様に繋げる
ことは可能です。
WSHでコントロールするには、先方のセキュリティのハザードを変える、何か
プログラムを仕込む等 必要なのでしょうか?

Set objxls=createobject("Excel.Application","FS")

ターゲットPC:コンピュータ名  FS
        OS Win98
        開いているポート 139

こちらのPC:OS Win98

魔界の仮面弁士 さん 2005年 02月 02日 17時 45分 20秒

》ばんのしゃーによかばんた さん 2005年02月02日 16時25分00秒
> とすれば、代入以外のケースで、何か、必要性があったのだろうから、
私はむしろ、Variantを返す実装になっている方が自然だと思っています。
必ず Variant が必要とされる言語で、わざわざ Variant では無い型を
返す関数が存在するとしたら、そちらの方が異質に思えてしまうので。

もっとも、CStr関数の実装を調べたわけではありませんので、
本当に VBAではBSTR型、VBScript では VT_BSTR な VARIANT を返すように
なっているのかどうかは、私もわかりませんけれどね……。
どうにかして調べる方法は無いものでしょうか。


> ※この場合、何が渡るのでしょう?
先の
http://program.station.ez-net.jp/special/vc/atl-com/variant.asp
の表から推測すると……『VT_BYREF | VT_I4』では無いでしょうか?

> さて、ExecWBをVBScriptで試すと、
> 『内部処理形式 Long の Variant型』の変数を渡しているのに、駄目。
あれ? 当方では期待動作しましたよ。
Integer を渡していたりはしませんか?

L = 32768 - 32764 '4:最大サイズ
MsgBox TypeName(L)
IE.ExecWB OLECMDID_ZOOM, OLECMDEXECOPT_DODEFAULT, L  '成功
L = CLng(2) '2:普通サイズ
MsgBox TypeName(L)
IE.ExecWB OLECMDID_ZOOM, OLECMDEXECOPT_DODEFAULT, L  '成功
MsgBox "Finish"


> その他変数や定数がNGで、唯一、CLng(1)を指定したときだけOKでした。
定数、ってConst 定義の事ですよね。
VBScriptって、0〜4 の範囲の Long型定数を作れましたっけ。

魔界の仮面弁士 さん 2005年 02月 02日 16時 48分 11秒

》ばんのしゃーによかばんた さん 2005年02月02日 16時24分07秒
>>「Method 引数1」=「Call Method(引数1)」であって、
>>「Method (引数1)」=「Call Method((引数1))」なのですよ。

これって、VBAユーザーだと経験的に知っている人も多いんですよね。

MsgBox関数を使おうとしたとき、
 MsgBox("abc")

 MsgBox ("abc")
に自動編集される(空白増加)点と、
 MsgBox("abc", vbInformation)
が即座にエラー報告されるという点などから。



そういえば、ByRef引数に渡すときに、括弧を付けると値渡しになるという点については、
http://www.microsoft.com/japan/developer/library/vbenlr98/vamsgArgTypeMismatch.htm
に少し書かれていますね。『Call SomeSub((MyVar))』な構文も載っています。

一方 VBScriptのドキュメントでは、上記の点について書かれた資料を発見できませんでした。
型の概念が希薄な言語だから、仕方がないのかな。
COMと連携させない限り、上記の現象にお目にかかる事もないので、仕方が無いとも言えますが。


> ポピュラーな誤解を防ぐのはマニュアルの大事な使命です。>MS
こういうのって、Documents Team にフィードバックすればよいのかな……。

ばんのしゃーによかばんた さん 2005年 02月 02日 16時 25分 00秒

>魔界の仮面弁士 さん 2005年 02月 01日 10時 13分 45秒
>> CStr(〜)とCVar(CStr(〜))の違いが出るのは、どういうときでしょうか?
>違いが出るというか、代入先がVariantなら自動的にCVarされる、という認識です。
>VBScriptの場合、CVar関数はありませんが、代入先は必ずVariantですよね。

そう、なので、疑問なんです。
VBScriptの場合、代入先は必ずVariantなのに、何で、CStr()の仕様を
「各関数は式を特定のデータ型に変換します。」
から、
「指定された式をバリアント型 (内部処理形式が文字列型 (String) の Variant) に変換して返します。」
に変える必要があったのか?
変えなくても代入すれば、そうなるのでわざわざ変えることはなかろうに。と。
とすれば、代入以外のケースで、何か、必要性があったのだろうから、
それは何だろう、という疑問です。
代入でないとすれば、やはり、関数呼び出し時の扱いでしょうか。

>> VBScript側の「障害」ですね。
>こうした現象は、VBScriptだけに発生するわけではありませんよ。

いえいえ。

>今回は VBScript からの呼び出しの場合でしたが、Variant型を受け取るメソッドの
>呼び出しで、データ型を強く意識しなければならない場合があるという点では、
>VBA でも一緒です。

それは問題ありません。

>  IE.ExecWB OLECMDID_ZOOM, OLECMDEXECOPT_DODEFAULT, ZoomSize
>という風に書くのですが、この場合の ZoomSize というのは、
>『内部処理形式 Long の Variant型』を渡す必要があります。(Integerは不可)

の場合に、

>  Dim ZoomSize As Long
>  ZoomSize = 1&
>  IE.ExecWB OLECMDID_ZOOM, OLECMDEXECOPT_DODEFAULT, ZoomSize
>のようにした場合、文字サイズの変更は行われません。無視されます。

違う型を渡してるんだから、まぁ仕方がないかと納得できなくもない。
※この場合、何が渡るのでしょう?

>  IE.ExecWB OLECMDID_ZOOM, OLECMDEXECOPT_DODEFAULT, (ZoomSize)
>のように括弧をつけて渡すか、もしくは、
>  Dim ZoomSize As Variant
>  ZoomSize = 1&
>  IE.ExecWB OLECMDID_ZOOM, OLECMDEXECOPT_DODEFAULT, ZoomSize
>のように、Variant型で渡す必要があります。定数値を渡してもOK。

なので、こちらの方はあまり文句が言えない。

ところが、InvokeVerbの方は、
「内部処理形式String型の Variant 型」を渡す必要があって、
「内部処理形式String型の Variant 型」の変数を渡しているのに、
「内部処理形式String型の Variant 型」が渡らない。
というのですから、「障害」だと思います。

さて、ExecWBをVBScriptで試すと、
『内部処理形式 Long の Variant型』の変数を渡しているのに、駄目。
その他変数や定数がNGで、唯一、CLng(1)を指定したときだけOKでした。
※ひょっとして、これがCLng()変更の理由でしょうか。

やはり、VBScriptの「障害」だと思います。


ばんのしゃーによかばんた さん 2005年 02月 02日 16時 24分 30秒

ExecWBのテストをしていて、

>魔界の仮面弁士 さん 2004年 12月 07日 11時 07分 13秒
>》 ばんのしゃーによかばんた さん
>>> ie.Navigate "about:<html><body><input type=file id=txtFile></body></html>"
>>> の記述が利用できないようです。(IE6SP1からだったかな?)
>> こっちは、まだ使えます。(XP SP2)
>当方では使えません。
>…うぅむ。この違いは何でしょうね。
>OSやIEの違いではなく、どこかの設定の問題という事なのかな。

動かないケースに遭遇しました。(XP SP2)
他にIEが動いていると、動きません。
他にIEが居ないと動きます。でも、こんな条件じゃ、やはり使えない。
こういう振る舞いはなんか歪ですね。
怪しい。。。

なら、もうひとつのほうも、きっと条件があるのだろう、と、

>>> ie.Navigate2 "javascript:document.write('<html><body><input type=file id=txtFile></body></html>');"
>>> のような記述であれば、現在のバージョンでも動作するようです。
>> これは、使えなくなった?みたい。(XP SP2)
>当方も同じくXP SP2ですが、この記法が使えています。

Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.Navigate2 "javascript:document.write('<html><body><input type=file >id=txtFile></body></html>');"
Do While ie.Busy Or ie.ReadyState<>4
 WScript.Sleep 100
Loop
は、インターネットゾーンのセキュリティレベルが高だと、
---------------------------
セキュリティの警告
現在のセキュリティ設定では、このファイルをダウンロードできません。
---------------------------
が出ます。
そこで、中にすると、今度は不定なエラーが出ます。
これは、ieが不安定なときにieにアクセスしたときに出る状況に似ています。
それなら、安定させればよい。
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.Navigate "about:blank"
Do While ie.Busy Or ie.ReadyState<>4
 WScript.Sleep 100
Loop
ie.Navigate2 "javascript:document.write('<html><body><input type=file >id=txtFile></body></html>');"
Do While ie.Busy Or ie.ReadyState<>4
 WScript.Sleep 100
Loop
と二段重ねにすると漸く動きました。
でも、こんなセキュリティ条件だとやはり使えないですね。


ばんのしゃーによかばんた さん 2005年 02月 02日 16時 24分 07秒

>魔界の仮面弁士 さん 2005年 01月 30日 23時 28分 39秒
>> この括弧は=xxx()やcall xxx()の括弧ではなく、式の括弧だったのですか。
>そう。他言語を知っている人には覚えにくいと言われますが、
>括弧の扱いに気をつけないといけません。
>「Method 引数1」=「Call Method(引数1)」であって、
>「Method (引数1)」=「Call Method((引数1))」なのですよ。

こういうのは、マニュアルに書いておいてほしいですね。
ポピュラーな誤解を防ぐのはマニュアルの大事な使命です。>MS


魔界の仮面弁士 さん 2005年 02月 02日 11時 47分 01秒

》 管理人むたぐち さん 2005年02月02日 10時53分51秒
> ZIPファイルがWindows/DOSのプラットフォームに特化したファイル形式ではないので、

「LHA」もそうですね。大文字小文字を区別可能なフォーマットです。
ついでに書くと、『同名パス、同名ファイル名のものも重複して格納可能』という。


> そういったところで不整合が出てきてしまうのではないかと、私は思います。

標準のZIP用エクステンションが、実装が少々中途半端な気もしますね。
区別するのかしないのか、仕様が曖昧な点が残念です。
レジストリオプション等で指定できれば良いのに。

管理人むたぐち さん 2005年 02月 02日 10時 53分 51秒

> ZIPファイルに同名ファイルがあるときに、追加すると、通常は置換されますが、
> もし、大文字/小文字の違いがあると、削除がエラーになります。

ZIPファイルがWindows/DOSのプラットフォームに特化したファイル形式ではないので、
そういったところで不整合が出てきてしまうのではないかと、私は思います。
UNIX系OSだと大文字小文字は厳格に区別されますからね。

ところでばんのしゃーによかばんたさんがこの前投稿された、ZIPファイルを操作するスクリプトですが、FileSystemObjectのTextStreamを使って空のZIPファイルを作成するあたりがちょっと痺れましたw
バイナリファイルとは言え、これくらいのことならできてしまうんだなぁ、と。

管理人むたぐち さん 2005年 02月 02日 01時 36分 54秒

VBScriptにおける型の話、私の知識が未熟なためついていけてませんが、
ちゃんと読んでますよー。と、管理人として一応存在をアピールしておきます(汗

Call文や引数の()の意味、バリアント型の内部形式等、
今まで漠然としていて、「何となくこう記述したら動いていた」的なところが、
より明確に理解できてきた感じがします。お二人に感謝です。
VBScriptも、ここまで深く研究されれば本望でしょうw

“LH Kenji”
“LH Naoko”は、日本語のスピーチエンジンの中の人ですね。
Office2003についてくるんですね。
単体でもダウンロードできます。

Microsoft Agent downloads for end-users
http://www.microsoft.com/msagent/downloads/user.asp#tts

Lernout & HauspieR TTS3000 TTS
engine - Japanese (3 MB exe) これです。
私はこれと英語のエンジンをインストールしたので、うちにはKenjiさん、Naokoさんのほかに10人ほどアメリカ人がいます。
初期状態に誰が居たのかはちょっと不明ですね。

魔界の仮面弁士 さん 2005年 02月 01日 20時 56分 08秒

》 ばんのしゃーによかばんた さん 2005年02月01日 19時20分52秒
> ところで、TTSのSpeechEngineについて。
> 2000にはSamさん一人が標準で付いていましたが、私のXPには、Samさんが居ません。
> 代わりに、プレインストール元のToshibaのお兄さんお姉さんたちが居ます。

WindowsCE/PocketPC機でも、オリジナルの物を搭載していますね。<東芝


> 他のXPではどうでしょうか?誰か標準で付いていますか?
会社のDELL機に居るのは、
“LH Kenji”
“LH Naoko”
“Microsoft Sam”
の三人衆でした。
LH家の2人は、Office 2003 から派遣されてきたんじゃないかな。

ばんのしゃーによかばんた さん 2005年 02月 01日 19時 23分 17秒

>ばんのしゃーによかばんた さん 2005年 01月 28日 19時 59分 05秒
>スクリプトからZIPファイルを自由自在に操作するサンプルアプリケーションです。

注意事項。

ZIPファイルに同名ファイルがあるときに、追加すると、通常は置換されますが、
もし、大文字/小文字の違いがあると、削除がエラーになります。

これって明らかに障害ですが、なかなか直りませんね。4、5年以上。
サードパーティ製なので、メンテされないのかなぁ。

回避方法は、先に同名ファイルがないか見て、削除するか、大文字/小文字を
合わせるか、です。


ばんのしゃーによかばんた さん 2005年 02月 01日 19時 22分 21秒

>管理人むたぐち さん 2004年 05月 20日 12時 27分 04秒
>Filterメソッドは、FolderItems3オブジェクトのメソッドで、
>その名の通り、FileItemsコレクションの絞込みに使います。
>Win2000, XPで使用可。

これを使ってコマンド用、ワイルドカード展開のサンプル。

>Const SHCONTF_FOLDERS = &H20 'フォルダだけに絞り込む
>Const SHCONTF_NONFOLDERS = &H40 'ファイルだけに絞り込む
はちょっと違って、
Const SHCONTF_FOLDERS = &H20 'フォルダを含む
Const SHCONTF_NONFOLDERS = &H40 'ファイルを含む
という意味のようです。
したがって、フォルダとファイルの場合は&H20+&H40となります。
――――――――――――――――――――――――――――――――――――――
Option Explicit
Dim fso
Dim Shell
Dim arg
Dim argv():ReDim argv(-1)
Set fso=CreateObject("Scripting.FileSystemObject")
Set Shell=CreateObject("Shell.Application")

For Each arg In WScript.Arguments
 If InStr(arg,"*") Then
  call glob(arg)
 ElseIf InStr(arg,"?") Then
  call glob(arg)
 Else
  ReDim Preserve argv(UBound(argv)+1)
  argv(UBound(argv))=arg
 End If
Next
WScript.Echo Join(argv,vbCrLf)
WScript.Quit

Function Glob(arg)
Dim Folder
Dim FolderItems
Dim FolderItem
Dim found
Set Folder=Shell.NameSpace(fso.GetParentFolderName(fso.GetAbsolutePathName(arg)))
Set FolderItems=Folder.Items
Call FolderItems.Filter(&H60,fso.GetFileName((arg)))
For Each FolderItem In FolderItems
 ReDim Preserve argv(UBound(argv)+1)
 argv(UBound(argv))=FolderItem.Path
 found=True
Next
If Not found Then
 ReDim Preserve argv(UBound(argv)+1)
 argv(UBound(argv))=arg
End If
End Function



Return