创建父窗口的DLL插件无法正确处理消息

时间:2020-03-05 18:40:34  来源:igfitidea点击:

我正在创建一个插件框架,我的应用程序在其中加载一系列插件DLL,然后创建一个新窗口并将此新窗口的句柄传递给插件。然后,插件可以使用此句柄创建自己的GUI。

一切似乎都运行良好。唯一的问题是,当我在插件窗口小部件(例如,一个编辑框)上按TAB时,它不会跳转到另一个窗口小部件。我发现传递了一些Windows消息,而另一些则没有。 WM_KEYDOWN传递给其他键,因为我可以在编辑框中键入内容,但是此消息无法处理TAB键。

希望有人有所提示。

我将Borland VCL与CBuilder一起使用,但是我认为我可以在WIN32下使用任何框架来创建这些插件,因为它们永远不知道其父窗口是如何创建的。

解决方案

回答

我相信我们必须采取以下步骤:

  • 子类化编辑控件(和其他需要的控件)。
  • 在编辑控件的WndProc中捕获WM_KEYDOWN消息。
  • 检查当前是否按住Shift键(使用GetKeyState或者类似键)。
  • 调用GetWindow,将句柄传递到编辑控件以及GW_HWNDPREV或者GW_HWNDNEXT,具体取决于是否按住Shift键。这将为我们提供应获得焦点的窗口的句柄。
  • 调用SetFocus并传递我们在步骤4中获得的窗口句柄。

确保处理多行编辑控件,因为我们可能希望显示一个真实的制表符而不是移至下一个控件。

希望对我们有所帮助!

回答

确实,这是非常复杂的事情。

当我们单击TAB时,仅当这些控件属于"模态对话框"时,焦点才会跳转到另一个控件。实际上,有一些按钮,例如ESC,LEFT,RIGHT,DOWN,UP,TAB,其模式对话框消息功能以特殊方式处理。如果希望这些键在无模式对话框或者任何其他窗口中以类似的方式工作,则应更改消息处理功能并在其中使用IsDialogMessage。我们还将在MSDN中找到有关IsDialogMessage函数的更多信息,以便更好地了解这些内容,我们也可以在"对话框"部分中进行检查。

并且,如前所述,我们应该在需要时设置WS_TABSTOP和WS_GROUP样式。

祝你好运!

回答

我相信我们在每个dll和exe文件中都有不同的VCL实例。 dll中的类与exe中的类不同,即使它们被称为相同。此外,全局变量(应用程序,屏幕)不在它们之间共享。内存也不是,因为它们都有自己的内存管理器。

解决方案是让dll和exe共享VCL库和内存管理器。我不是BCB开发人员,而是Delphi开发人员。在Delphi中,我们只将rtl和vcl用作运行时包。也许我们可以做等效的BCB。

回答

DLL有其自己的TApplication对象。

提供统一的密钥处理。 DLL加载时。
将DLL :: TApplication分配给EXE :: TApplication
确保退出时进行相反的操作。

--

麦可