2

サードパーティ製アプリケーションのプラグイン拡張 (ツールバー) に取り組んでいます。アプリケーションの新しいバージョンも 64 ビットです。ここで問題が発生します。私たちのプラグインは VB6 で開発されています。32 ビット アプリケーションでは、すべて正常に動作します。

アプリケーションの製造元は、32 ビット プラグインに対して自動的に実行されるラッパー (64 ビット版) も提供するため、プラグインは「アウト プロセス」で実行されます。通常は問題なく動作しますが、(明らかに) いくつかの必要な回避策が必要です。

私たちのプラグインにはモーダルフォームしかありません。64ビットアプリケーションの「プロセス外」で実行する場合、所有者と親を次のように設定する必要があります

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetLastActivePopup Lib "user32" (ByVal hwnd As Long) As Long
Declare Function SetParent Lib "user32" (ByVal hwndC As Long, ByVal hwndP As Long) As Long
Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Sub PopupWindow(formHwnd As Long)
  '(Declarations here...)
  If (App.GetProcessId() <> GetCurrentProcessId()) Then
    hWndMain = FindWindow(vbNullString, App.Caption)
    hWndParent = GetLastActivePopup(hWndMain)
    CurrentStyle = GetWindowLong(formHwnd, GWL_STYLE)

    If (hWndParent = 0) Then
      hWndParent = hWndMain
      BringWindowToTop hWndParent
      SetWindowLong formHwnd, GWL_STYLE, CurrentStyle Or WS_POPUP
      SetParent formHwnd, hWndMain
    Else
      SetWindowLong formHwnd, GWL_STYLE, CurrentStyle Or WS_POPUP
      SetWindowLong formHwnd, GWL_HWNDPARENT, hWndParent
    End If
  End If
End Sub

フォームを表示するためのコードは次のとおりです。

PopupWindow formType.hwnd
formType.Show vbModal, [OwnerForm]

1)最初の小さな問題は、「親」アプリケーションウィンドウをクリックすると、プラグインからウィンドウのフォーカスが失われることです(ただし、プラグインウィンドウはまだ上にあり、親アプリケーションはコントロールを無効にしています)。32ビット版では、標準的な方法で動作します - 「ビープ音」を鳴らし、モーダルダイアログウィンドウでフラッシュをフォーカスします - 「プロセス外」でどのように実行しますか?

The Old New Thing ブログでは、この問題 (黄色の四角形) が説明されており、その後の解決策は次のようになります。

プロセス B で DialogBox を呼び出すときは、オーナー ウィンドウとして hwndA を渡します。

しかし、VB6 には functionForm.Show([Modal], [OwnerForm])があり、hWndではなくtypeOwnerFormを意味します。

アプリケーション フォームのタイプは、そのインターフェイスでは使用できません。WinAPI を使用して解決策を見つけることができません。

2)2番目の問題(原因は同じだと思います)は、プラグインモーダルダイアログを表示したときに、[デスクトップの表示](またはWin + M)をクリックすると、アプリケーションに戻ります(アイコンをクリックしますパネルで)、「ビープ」だけを再生し、何もしません。(解決策は、アプリケーションを強制終了することだけです)。繰り返しますが、32 ビット版は正常に動作します。

答えてくれてありがとう、そして私の英語をお詫びします。はい、VB6 は現在サポートされていません。プラグインはメンテナンス モードのみで、C# に基づく新しいバージョンの開発が進行中です。それが完了するまで、VB6 が動作する必要があります。


編集:

Spy++ では、32 ビット アプリと 64 ビット アプリでの実行時のウィンドウ プロパティの違い:

32 ビット アプリと 64 ビット アプリでのプラグイン ウィンドウ スタイルの違い:

WS_CAPTION
*** WS_POPUP (only with 64bit App, because of code above)
WS_VISIBLE
WS_CLIPSBLINGS
WS_CLIPCHILDREN
WS_SYSMENU
WS_THICKFRAME
*** WS_OVERLAPPED (only with 32bit App)
WS_MINIMIZEBOX

32 ビット アプリと 64 ビット アプリでのプラグイン ウィンドウの親/所有者の違い:

*** Parent Window (32bit App None, 64bit App - Main Application hWnd) 
Owner Window (32bit and 64bit App - Main Application hWnd)
4

0 に答える 0