■No33367に返信(魔界の仮面弁士さんの記事)
> 試しに、フォーム "Form1" の ThunderRT6FormDC なウィンドウハンドル(要するに Me.hWnd) ではなく、> > 具体的には GetWindowLong に GWL_HWNDPARENT を渡して最上位ウィンドウまでのチェーンを辿るか、> 例)https://support.microsoft.com/en-us/kb/259673> なお、この検証はコンパイルした EXE から行ってみてください。開発環境から実行した場合には、> ウィンドウクラス名が異なっていたような気もしますので(ThunderMain だったかな?)。
トップレベルだとは思いますが一応やってみました。
Dim nRet As Long
Dim nMainhWnd As Long
nRet = GetWindowLong(Me.HWND, GWL_HWNDPARENT)
Do While nRet
nMainhWnd = nRet
nRet = GetWindowLong(nMainhWnd, GWL_HWNDPARENT)
Loop
Dim c As VirtualDesktopManager
Set c = New VirtualDesktopManager
If c.IsWindowOnCurrentVirtualDesktop(nMainhWnd) Then
MsgBox "OK"
End If
このようにしてみましたが、やはりエラーが出ます。
※コンパイル実行しました。
>>※なぜにエラーを発生させているのでしょうか ・・・> IsWindowOnCurrentVirtualDesktop メソッドの戻り値の説明文を見てください。> https://msdn.microsoft.com/en-us/library/windows/desktop/mt186442.aspx
つまり、エラー処理して対応しなさいということですね。
自作プログラム的には未解決ですが、当初のスレ題目の「C#で作成したDLLがVB6.0で利用できない」
は一応解決(参照は出来た)ということで一端切り上げようと思います。
話がそれてしまい誠に申し訳ないです。
魔界の仮面弁士さんには色々勉強させていただきました。
VB6.0でこんな細かいところまで踏み込めるとは思っていませんでしたので、改めて勉強したいと思います。
ありがとうございました。
■No33365に返信(魔界の仮面弁士さんの記事)
> であれば、API 側を Alias せず、そのまま GetObjectW / GetObjectA として> 呼び出すようにするか、
これで切り分けは問題なく出来ました。
但し、新たな問題が発生しました。
Public Function IsWindowOnCurrentVirtualDesktop(ByVal topLevelWindow As Long) As Boolean の Err.Raise hr で発生します。
実行時エラー'-2147319765(8002802b)'
オートメーションエラーです。
要素が見つかりません。
と出ます。
※なぜにエラーを発生させているのでしょうか ・・・
> 参照設定はできたのですね。> VB 側の呼び出し部のコードはどうなっていますか?
Dim obj As ClassLibrary1.Class1
Set obj = New ClassLibrary1.Class1
If obj.IsVirtualDesktop(Me.HWND) Then
MsgBox "OK"
End If
このようにしています。
DLLの作成に問題があるのかもしれません。
> 試しに作ってみました。Form1 からであれば > Dim c As VirtualDesktopManager > Set c = New VirtualDesktopManager > If c.IsVirtualDesktop(Me.hWnd) Then > MsgBox "OK" > End If > のように利用できるはずです。
プログラム内に新しく VirtualDesktopManager というクラスモジュールを作り 実行すると IsVirtualDesktop がないと出てきます。 そこでもしかすると If c.IsVirtualDesktop(Me.hWnd) を If c.IsWindowOnCurrentVirtualDesktop(Me.hWnd) とするとうまくいくかなぁと思いやってみました。 ここはすんなり通ったみたいなのですが、下記のところでエラーが出ます。
> Call IIDFromString(StrPtr("{a5cd92ff-29be-454c-8d04-d82879fb3f1b}"), iid(0)) > Set oVirtualDesktopManager = GetObject("new:aa509086-5ca9-4c25-8f95-589d3c07b48a") > Call Invoke32(ObjPtr(oVirtualDesktopManager), 0, VarPtr(iid(0)), VarPtr(pIVirtualDesktopManager)) > End Sub
エラーは「GetObject は引数が足りません。」です。
本体の標準モジュールで下記のように宣言しています。
Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
■No33349に追記(魔界の仮面弁士の記事)
> なお、質問内容からは外れてしまいますが、もしもやりたいことが> {a5cd92ff-29be-454c-8d04-d82879fb3f1b} の IVirtualDesktopManager を> 利用するという点だけなのであれば、C# を介さずに、> VB6 や VBA から直接呼び出すという選択肢もあるかも。
試しに作ってみました。Form1 からであれば
Dim c As VirtualDesktopManager
Set c = New VirtualDesktopManager
If c.IsVirtualDesktop(Me.hWnd) Then
MsgBox "OK"
End If
のように利用できるはずです。
(手元に VB6 が無いので、動作検証は 32bit 版の Excel 2016 で行っています)
'-----------------------------------------------------------
'クラスモジュール "VirtualDesktopManager"
Option Explicit
Private oVirtualDesktopManager As IUnknown
Private pIVirtualDesktopManager As Long
Private Declare Function IIDFromString Lib "ole32" _
(ByVal lpsz As Long, _
ByRef lpiid As Byte) As Long
Private Declare Function StringFromGUID2 Lib "ole32" _
(ByVal rguid As Long, _
ByVal lpstrClsId As Long, _
ByVal cbMax As Integer) As Long
Private Declare Function DispCallFunc Lib "oleaut32" _
(ByVal pvInstance As Long, _
ByVal oVft As Long, _
ByVal cc As Integer, _
ByVal vtReturn As Integer, _
ByVal cActuals As Long, _
ByRef prgvt As Integer, _
ByRef prgpvarg As Long, _
ByRef pvargResult As Variant _
) As Long
Private Sub Class_Initialize()
Dim iid(0 To 15) As Byte
Call IIDFromString(StrPtr("{a5cd92ff-29be-454c-8d04-d82879fb3f1b}"), iid(0))
Set oVirtualDesktopManager = GetObject("new:aa509086-5ca9-4c25-8f95-589d3c07b48a")
Call Invoke32(ObjPtr(oVirtualDesktopManager), 0, VarPtr(iid(0)), VarPtr(pIVirtualDesktopManager))
End Sub
Private Sub Class_Terminate()
Call Invoke32(pIVirtualDesktopManager, 2)
pIVirtualDesktopManager = 0
Set oVirtualDesktopManager = Nothing
End Sub
Private Function Invoke32(ByVal pInstance As Long, ByVal fIdx As Long, ParamArray args() As Variant) As Variant
Dim l As Long, u As Long, c As Long
l = LBound(args)
u = UBound(args)
c = u - l + 1
Dim vp() As Long
Dim vt() As Integer
ReDim vp(IIf(c = 0, l, u))
ReDim vt(IIf(c = 0, l, u))
Dim i As Long
For i = l To u
vt(i) = VarType(args(i))
vp(i) = VarPtr(args(i))
Next
Dim hr As Long
hr = DispCallFunc(pInstance, fIdx * 4, 4, vbLong, c, vt(l), vp(l), Invoke32)
If hr <> 0 Then
Err.Raise hr
End If
End Function
Public Function IsWindowOnCurrentVirtualDesktop(ByVal topLevelWindow As Long) As Boolean
Dim outBool As Long
Dim hr As Long
hr = CLng(Invoke32(pIVirtualDesktopManager, 3, (topLevelWindow), outBool))
If hr = 0 Then
IsWindowOnCurrentVirtualDesktop = CBool(outBool)
Else
Err.Raise hr
End If
End Function
Public Function GetWindowDesktopId(ByVal topLevelWindow As Long) As String
Dim hr As Long
Dim iid() As Byte
ReDim iid(0 To 15)
hr = CLng(Invoke32(pIVirtualDesktopManager, 4, (topLevelWindow), iid(0)))
If hr = 0 Then
Dim bIID() As Byte
bIID = String$(40, 0)
Call StringFromGUID2(VarPtr(iid(0)), VarPtr(bIID(0)), 40)
GetWindowDesktopId = Left$(UCase(bIID), 38)
Else
Err.Raise hr
End If
End Function
Public Sub MoveWindowToDesktop(ByVal topLevelWindow As Long, ByVal desktopId As String)
Dim iid(0 To 15) As Byte
Call IIDFromString(StrPtr(desktopId), iid(0))
Dim hr As Long
hr = CLng(Invoke32(pIVirtualDesktopManager, 5, (topLevelWindow), iid(0)))
If hr <> 0 Then
Err.Raise hr
End If
End Sub
C#のソースです '------------------------------------------------------------- ClassLibrary1 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WindowsDesktop;
namespace ClassLibrary1 { public class Class1 { public static Boolean IsVirtualDesktop(IntPtr Handle) { return (VirtualDesktopManager.DesktopManager.IsWindowOnCurrentVirtualDesktop(Handle)); } } } '------------------------------------------------------------- using System; using System.Runtime.InteropServices;
public class VirtualDesktopManager { public static readonly IVirtualDesktopManager DesktopManager;
static VirtualDesktopManager() { var type = Type.GetTypeFromCLSID(new Guid("aa509086-5ca9-4c25-8f95-589d3c07b48a")); DesktopManager = (IVirtualDesktopManager)Activator.CreateInstance(type); } } '------------------------------------------------------------- VirtualDesktopManager.cs