Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 64位应用程序+;进程外32位模态对话框_Winapi_Plugins_Vb6_Modal Dialog_Out Of Process - Fatal编程技术网

Winapi 64位应用程序+;进程外32位模态对话框

Winapi 64位应用程序+;进程外32位模态对话框,winapi,plugins,vb6,modal-dialog,out-of-process,Winapi,Plugins,Vb6,Modal Dialog,Out Of Process,我们致力于第三方应用程序的插件扩展(工具栏)。新版本的应用程序也是64位的——问题来了。我们的插件是在VB6下开发的。在32位应用程序中,一切正常 应用程序的制造商还提供了自动运行32位插件的包装器(64位版本),所以我们的插件运行“进程外”。一般来说,它工作正常,但(显然)需要一些必要的变通方法 我们的插件只有模态形式。当它运行64位应用程序的“进程外”时,需要像这样设置所有者和父级 Declare Function FindWindow Lib "user32" Alias "FindWin

我们致力于第三方应用程序的插件扩展(工具栏)。新版本的应用程序也是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
1) 第一个小问题是,单击“父”应用程序窗口会导致我们的窗口从插件中失去焦点(但插件窗口仍然位于顶部,父应用程序已禁用控件)。在32位版本中,它以标准方式运行-在模式对话框窗口上播放“嘟嘟”声和聚焦闪光灯-如何在“进程外”上完成

在上描述了这个问题(黄色矩形),然后给出了类似的解决方案

在进程B中调用DialogBox时,将hwndA作为所有者窗口传递

但在VB6中,有函数
Form.Show([Modal],[ownermer])
,其中
ownermer
表示类型,而不是hWnd

应用程序窗体的类型在其界面中不可用。我无法使用WinAPI找到解决方案

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
*** Parent Window (32bit App None, 64bit App - Main Application hWnd) 
Owner Window (32bit and 64bit App - Main Application hWnd)
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
*** Parent Window (32bit App None, 64bit App - Main Application hWnd) 
Owner Window (32bit and 64bit App - Main Application hWnd)

您还必须调用EnableWindow来禁用父窗口,修复#1。如果没有,则从AttachThreadInput获得死锁,这是Raymond警告的,修复了#2。如果我尝试调用
EnableWindow(hWndMain,0)
,它返回0,这意味着之前未禁用主应用程序窗口-这是正常的。但是它的行为仍然是一样的。你必须确保你有正确的窗口句柄。使用Spy++进行双重检查。从GetLastActivePopup()获得正确的窗口句柄的几率肯定不是很大。是的,我有正确的窗口句柄(通过Spy++检查)。代码每次都通过Else语句(至少在调试模式下)
hWndMain
等于
hWndParent
,直到它不是插件对话框的新子对话框。请参见问题的编辑-64位应用程序下的插件对话框窗口是否同时具有所有者和父对象。我尝试了
SetParent(FormHwnd,0)
,但windowparent仍然存在。