Borland C ++ Builder中的Windows子类化

时间:2022-12-15 15:10:14

We're trying to convert a piece of C++ code written in MFC which uses the CWnd.SubclassWindow method, into Borland C++ Builder code. Does anyone know how to do subclassing (subclass with a TForm object) - we're completely stuck. Any pointers will be much appreciated! TIA!

我们正在尝试将使用CWnd.SubclassWindow方法编写的MFC编写的C ++代码转换为Borland C ++ Builder代码。有谁知道如何做子类化(带有TForm对象的子类) - 我们完全陷入困境。任何指针将非常感谢! TIA!

Specifics:

We have an existing base class written in Borland C++ which inherits from TForm, which is used to give all forms that inherits from it a certain look and feel (it processes WM_NCPAINT and WM_NCHITTESTheavily, for example).

我们有一个用Borland C ++编写的现有基类,它继承自TForm,它用于为从中继承的所有表单提供一定的外观(例如,它处理WM_NCPAINT和WM_NCHITTESTheavily)。

Now we'd like to use this code to give forms written in other languages (MSVC++/MFC and C# to be exact) the same look and feel.

现在我们想使用这段代码给用其他语言编写的表单(准确地说是MSVC ++ / MFC和C#)具有相同的外观。

Instead of rewriting all the code we thought that using windows subclassing would be a great idea. Then we could stuff all the existing and tested code into a DLL and then just call it with a hWnd and that window would automagically get the new look and feel.

而不是重写我们认为使用Windows子类化的所有代码将是一个好主意。然后我们可以将所有现有的和经过测试的代码填充到DLL中,然后用hWnd调用它,该窗口将自动获得新的外观。

Exactly why this is so impossible is really not up to me to say - I don't code in Borland C++ myself. I wrote a stub in MFC in just a few minutes to show the Borland C++ developers what I wanted and they have spent days trying to mimic the MFC CWnd::SubclassWindow method without success.

究竟为什么这么不可能真的不能由我来说 - 我自己不用Borland C ++编写代码。我在几分钟内在MFC中写了一个存根来向Borland C ++开发人员展示我想要的东西,他们花了几天时间试图模仿MFC CWnd :: SubclassWindow方法而没有成功。

From what I understand, the problem is that when you do a "new TForm()", then a new window is automatically created before you have any chance to stop it. So replacing then WindowProc works BUT an unwanted TForm window is floating around on the screen to no use!!!!

根据我的理解,问题在于当你执行“新的TForm()”时,在你有机会停止之前会自动创建一个新窗口。所以替换然后WindowProc工作,但一个不需要的TForm窗口在屏幕上浮动,没有用!

2 个解决方案

#1


I'll assume you mean VCL. You can set the WindowProc property of a TControl object to your own window procedure or another control's WindowProc.

我假设你的意思是VCL。您可以将TControl对象的WindowProc属性设置为您自己的窗口过程或另一个控件的WindowProc。

EDIT: More answer, based on more specifics

编辑:更多答案,基于更具体的细节

To prevent new TForm from creating a window to float uselessly around the screen, you should just need to set its Visible property to false. Alternatively, you could override CreateParams to remove the WS_VISIBLE style from the window:

为了防止新的TForm创建一个在屏幕上无用地浮动的窗口,您只需要将其Visible属性设置为false。或者,您可以覆盖CreateParams以从窗口中删除WS_VISIBLE样式:

void __fastcall TBlahForm::CreateParams(TCreateParams &Params)
{
    TForm::CreateParams(Params);
    Params.Style&=~WS_VISIBLE;
}
//---------------------------------------------------------------------------

There'll still be an invisible window getting created, but as I understand the use case, this shouldn't be a big deal.

仍然会有一个不可见的窗口被创建,但正如我理解的用例,这应该不是什么大问题。

Overriding TCustomForm::CreateWnd is potentially another way of attacking the same problem.

覆盖TCustomForm :: CreateWnd可能是另一种攻击同一问题的方法。

My other suggestion would be to just port the code from BCB to VC++. If it's doing lots of mucking around with WM_NCPAINT and WM_NCHITTEST then it sounds an unlikely candidate to have lots of VCL-specific stuff in it - it's probably just banging straight on the Win32 API? If there's nothing VCL in there, compiling in VC++ should pretty much just magically work.

我的另一个建议是将代码从BCB移植到VC ++。如果它正在使用WM_NCPAINT和WM_NCHITTEST进行大量处理,那么它听起来不太可能有很多VCL特定的东西 - 它可能只是直接敲击Win32 API?如果那里没有VCL,那么在VC ++中编译应该只是神奇地工作。

In any event: it's almost certainly possible. I have an app built with BCB5 (which predates WinXP) that through clever use of window hooks, subclassing and the like (most of which isn't my own) is still perfectly happy dealing with XP and even Aero (which isn't to say it isn't a pain to maintain). If that's possible, your application certainly should be. VCL follows a different paradigm to MFC, but it's nonetheless flexible.

无论如何:几乎可以肯定。我有一个用BCB5构建的应用程序(早于WinXP),通过巧妙使用窗口挂钩,子类化等(大多数不是我自己的)仍然非常高兴处理XP甚至Aero(这不是说保持不痛苦)。如果可能,您的应用程序肯定应该是。 VCL遵循与MFC不同的范例,但它仍然是灵活的。

#2


Have a look at the Codegear Online Docs, which describes the WindowProc mechanism for subclassing.

查看Codegear Online Docs,它描述了用于子类化的WindowProc机制。

C++Builder uses the underlying Delphi VCL, so searching for "Delphi Window subclassing" will be more fruitful than trying to find something specifically C++. C++Builder programmers have to at least be capable of reading Delphi code, even if they don't have to write any!

C ++ Builder使用底层的Delphi VCL,因此搜索“Delphi Window子类化”比尝试查找特定的C ++更有成效。 C ++ Builder程序员必须至少能够阅读Delphi代码,即使他们不必编写任何代码!

#1


I'll assume you mean VCL. You can set the WindowProc property of a TControl object to your own window procedure or another control's WindowProc.

我假设你的意思是VCL。您可以将TControl对象的WindowProc属性设置为您自己的窗口过程或另一个控件的WindowProc。

EDIT: More answer, based on more specifics

编辑:更多答案,基于更具体的细节

To prevent new TForm from creating a window to float uselessly around the screen, you should just need to set its Visible property to false. Alternatively, you could override CreateParams to remove the WS_VISIBLE style from the window:

为了防止新的TForm创建一个在屏幕上无用地浮动的窗口,您只需要将其Visible属性设置为false。或者,您可以覆盖CreateParams以从窗口中删除WS_VISIBLE样式:

void __fastcall TBlahForm::CreateParams(TCreateParams &Params)
{
    TForm::CreateParams(Params);
    Params.Style&=~WS_VISIBLE;
}
//---------------------------------------------------------------------------

There'll still be an invisible window getting created, but as I understand the use case, this shouldn't be a big deal.

仍然会有一个不可见的窗口被创建,但正如我理解的用例,这应该不是什么大问题。

Overriding TCustomForm::CreateWnd is potentially another way of attacking the same problem.

覆盖TCustomForm :: CreateWnd可能是另一种攻击同一问题的方法。

My other suggestion would be to just port the code from BCB to VC++. If it's doing lots of mucking around with WM_NCPAINT and WM_NCHITTEST then it sounds an unlikely candidate to have lots of VCL-specific stuff in it - it's probably just banging straight on the Win32 API? If there's nothing VCL in there, compiling in VC++ should pretty much just magically work.

我的另一个建议是将代码从BCB移植到VC ++。如果它正在使用WM_NCPAINT和WM_NCHITTEST进行大量处理,那么它听起来不太可能有很多VCL特定的东西 - 它可能只是直接敲击Win32 API?如果那里没有VCL,那么在VC ++中编译应该只是神奇地工作。

In any event: it's almost certainly possible. I have an app built with BCB5 (which predates WinXP) that through clever use of window hooks, subclassing and the like (most of which isn't my own) is still perfectly happy dealing with XP and even Aero (which isn't to say it isn't a pain to maintain). If that's possible, your application certainly should be. VCL follows a different paradigm to MFC, but it's nonetheless flexible.

无论如何:几乎可以肯定。我有一个用BCB5构建的应用程序(早于WinXP),通过巧妙使用窗口挂钩,子类化等(大多数不是我自己的)仍然非常高兴处理XP甚至Aero(这不是说保持不痛苦)。如果可能,您的应用程序肯定应该是。 VCL遵循与MFC不同的范例,但它仍然是灵活的。

#2


Have a look at the Codegear Online Docs, which describes the WindowProc mechanism for subclassing.

查看Codegear Online Docs,它描述了用于子类化的WindowProc机制。

C++Builder uses the underlying Delphi VCL, so searching for "Delphi Window subclassing" will be more fruitful than trying to find something specifically C++. C++Builder programmers have to at least be capable of reading Delphi code, even if they don't have to write any!

C ++ Builder使用底层的Delphi VCL,因此搜索“Delphi Window子类化”比尝试查找特定的C ++更有成效。 C ++ Builder程序员必须至少能够阅读Delphi代码,即使他们不必编写任何代码!