つまるところ「エクスプローラのインスタンスを取得する」必要があるのだと分かってきて
検索していたら、MSDNでこんなページを付け、これが糸口になって全てが解決しました。
[[Java を使って、実行中の Internet Explorer のインスタンスに接続する方法]]
http://support.microsoft.com/kb/299356/ja
で、ShellWindowsインターフェイスを取得すればいいんだなーと思って調べてみたら
http://www5a.biglobe.ne.jp/~javajava/ar ... ript1.html
>//ShellWindows implements IShellWindows type coclass
>//prid = "SHDocVw.ShellWindows"
>//guid = {9BA05972-F6A8-11CF-A442-00A0C90A8F39}
とあったのでこれを使って
コード:
Dim NumOfWindow As Long 'ウィンドウの数
Dim pShellWin As *IShellWindows ' Explorerのコレクションを取得
Dim pMalloc As *IMalloc ' メモリ確保用
Dim ProgID_WB As String ' プログラムID
Dim ClsID_WB As GUID ' クラスID
Dim hr As Long ' エラーメッセージ取得用
hr = CoInitialize(0)
hr = CoGetMalloc(1, pMalloc)
ProgID_WB ="{9BA05972-F6A8-11CF-A442-00A0C90A8F39}" ' SHDocVw.ShellWindows
hr =egtrGUIDFromString_Str(ProgID_WB, ClsID_WB)
hr =egtrCoCreateInstance_ClsID(ClsID_WB, IID_IShellWindows, VarPtr(pShellWin))
hr =pShellWin->get_Count(NumOfWindow) ' コレクションの数を取得
としたところ、見事取得することができました。
ここからはトントン拍子で、
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード:
Dim pDisp As *IDispatch ' コレクションからアイテムを取得
Dim pSPV As *IServiceProvider '
Dim pFldView As *IFolderView ' ウィンドウの表示モードを取得
Dim pBrowser As *IWebBrowser2 ' ウィンドウのパスとハンドルを取得
Dim cURL As BSTR ' 取得したURL
Dim cHandle As Int64 ' ハンドル
Dim cMode As DWord ' 表示モード
Dim its As WINDOWPLACEMENT ' ウィンドウの位置情報を記録
Dim Index As Long
Dim v_idx As VARIANT ' VARIANT型Indexに変換するために使用
Dim qw_idx As *QWord ' VARIANT型Indexを渡すために基本型に代入
For Index=0 To NumOfWindow-1
/* Explorerのコレクションから単一のアイテムを取得 */
SetVariantLong(VarPtr(v_idx), Index)
qw_idx =VarPtr(v_idx) As *QWord
hr =pShellWin->Item(qw_idx[0],qw_idx[1], pDisp)
/* IWebBrowser2インターフェイスを取得 */
hr =pDisp->QueryInterface(IID_IWebBrowser2, VarPtr(pBrowser))
/* IFolderViewインターフェイスを取得 */
hr =pBrowser->QueryInterface(IID_IServiceProvider, VarPtr(pSPV))
hr =pSPV->QueryService(IID_IFolderView, IID_IFolderView, VarPtr(pFldView))
/* ウィンドウのパスとハンドルを取得 */
hr =pBrowser->get_LocationURL(VarPtr(cURL))
hr =pBrowser->get_HWND(VarPtr(cHandle))
/* ウィンドウの表示モードを取得 */
hr =pFldView->GetCurrentViewMode(VarPtr(cMode))
/* ウィンドウの位置情報の取得 */
GetWindowPlacement(cHandle As HWND, its)
Next Index
コード:
'api_Variant.sbp
Type VARIANT ' 128bitのなんでもござれの構造体
vt As VARTYPE
wReserved1 As Word
wReserved2 As Word
wReserved3 As Word
Val[ELM(8)] As Byte
End Type
Function SetVariantLong(lpdata As *VARIANT, num As Long)
' Const VT_I4=3 /** 4-byte signed int. <Long> **/
lpdata->vt = VT_I4
memcpy(VarPtr(lpdata->Val),VarPtr(num),4)
End Function
こんな感じで、URL(パス)・ハンドル・表示モードと、欲しい物を全て取得することができるようになりました。
ここまでたどり着くのは相当時間がかかりました。COMはやっぱりむずいです。
同じように、COMで悩んでいる人の力に少しでもなれたらいいと思います。
でもこれ見たら、イグトランス様が言っていたように、ほとんどWSHでやってることとやり方は同じなんですね。
ウィンドウコレクションからアイテムを一つ一つ取得して、そのプロパティを取得する感じ。
あと、IShellWindowsインターフェイスはなぜかMSDNでは見つからなかったんですが、この名前自体は
WSHでCreateObject("Shell.Application").Windowsというのがあるので、なんか似ているなあと…
案外最初にWSHでプログラムを作っておくと、COMの理解がしやすいのかも。
ref.開いているフォルダウィンドウのアドレスの取得について
http://www.activebasic.com/forum/viewto ... highlight=