我对 Embarcadero C++ Berlin 10.1 中的 VCL 样式有疑问。我有一个用 BCB C++ 编写的应用程序,它调用 pspiHost.dll(用 VS 2017 编写),它执行 Photoshop 8bf 插件过滤器(https://github.com/spetric/Photoshop-Plugin-Host)。
一切正常,直到我将项目应用程序外观更改为某种 VCL 样式。当从样式化的应用程序调用插件时,它的窗口也被样式化了!?此外,插件窗口会不断重新绘制,窗口中的任何操作(如平移图像)都会减慢。
我还注意到一个扫描仪预览对话框上的这种奇怪行为,该对话框也有样式,它绝对不是 VCL 应用程序。
如何禁用从 DLL 调用的非 VCL 窗口的 VCL 样式?
以下是炭黑板岩风格的示例:
请忽略图像方向(在校正 TBitmap 样式容器之前)。
这是没有样式的相同应用程序的示例(Windows 默认):
Styled 插件完全没用(缩放、平移或任何图像更改时速度很慢)。最后一个示例是图像方向校正,但与此问题无关(仅供参考)。
这是一个简单的应用程序。一种在面板上有 TImage、一个 TPanel 和两个速度按钮的表单(“加载图像”和“执行插件”)。
这是“加载图像”按钮的 OnClick 事件:
//---------------------------------------------------------------------------
void __fastcall TfrmSimple::SpeedButton1Click(TObject *Sender)
{
// load BMP in Image1
Image1->Picture->LoadFromFile("974-1.bmp");
// set our bitmap to pspiHost - we know that it's 24 bit bgr, no alpha, so we know the TImgType
int w, h;
srcImage = Image1->Picture->Bitmap;
TImgType type = PSPI_IMG_TYPE_BGR;
w = srcImage->Width;
h = srcImage->Height;
// let's say we don't know if TBitmap has contiguous buffer, so we'll add scanlines one by one
pspiStartImageSL(type, w, h);
for (int i = 0; i < h; i++)
pspiAddImageSL(srcImage->ScanLine[i]);
pspiFinishImageSL(); // done
}
在这个例子中,扫描线被一一“发送”到 pspiHost.dll,所以有 3 个 API 调用。
这是“执行插件”按钮的 OnClick 事件:
//---------------------------------------------------------------------------
void __fastcall TfrmSimple::SpeedButton2Click(TObject *Sender)
{
// let's deal with filter
if (srcImage->Width < 2 || srcImage->Height < 2)
return;
// some 8bf filter for testing
String filter = "curves3 (32 bits).8bf";
// load filter
if (pspiPlugInLoad(filter.c_str()) == 0)
{
void *FP = DisableTaskWindows((HWND)(this->Handle)); // so that plugin window stays on top like modal (required for some filters)
int rc;
// execute filter
try {
rc = pspiPlugInExecute((HWND)(this->Handle));
} catch (...) {
rc = -1;
}
EnableTaskWindows(FP); // back to normal
Image1->Refresh();
if (rc != 0)
{
// error executing
}
}
else
{
// error loading -> plugin not loaded
}
}
有两个 API 调用,加载过滤器和执行过滤器。就这样。架构非常简单:Application -> pspiHost.dll -> 8bf 过滤器(同样是 DLL)。应用程序外观影响插件窗口。问题是如何禁用这种行为?