我制作了一个TForm导数,它的作用就像组合体的下拉部分、提示窗口或弹出菜单--这是暂时的事情。它没有标题-它的BorderStyle被设置为bsNone。在设置了窗体的位置后,将非模式地使用Show显示窗体。
为了使它脱颖而出,它需要在其边界周围投下一个阴影。但是,将其边框设置为bsNone的结果是drop阴影消失。
谷歌的各种消息来源提出了各种不同的建议:
procedure TdlgEditServiceTask.CreateParams(var Params: TCreateParams);
const
CS_DROPSHADOW = $00020000;
begin
inherited;
{ Enable drop shadow effect on Windows XP and later }
if (Win32Platform = VER_PLATFORM_WIN32_NT) and
((Win32MajorVersion > 5) or
((Win32MajorVersion = 5) and (Win32MinorVersion >= 1))) then
Params.WindowClass.Style := Params.WindowClass.Style or
CS_DROPSHADOW;
end;但是它不工作-阴影没有显示(除非我也设置了一个可调整大小的边框与WS_THICKFRAME设置,这看起来很糟糕)。这是一个弹出窗口,而不是一个子窗口,所以我不明白为什么它会失败。
请给我建议?
注:这是一个类似的问题,这问题,仍然没有答案。
NB2:有一个名为TShadowWindow的晦涩的VCL组件,它看起来会做正确的事情,但它的编写过于粗糙,不太实用。
更新:在安德烈亚斯下面的评论之后,我对此做了进一步的调查,并发现了一些细节。
在Windows 7下,我发现当弹出窗口在同一应用程序的另一个窗口上时,阴影不会出现。
下面是一个简单的Delphi应用程序,它使用弹出窗口上的CreateParams请求阴影,如前所述。

看到放置阴影是如何出现在主窗口之外的地方的吗?
但是我想用无边界窗口作为主窗口的弹出窗口。下拉阴影将弹出窗口与下面的窗口区分开来。我上面所有的描述都提到了这种情况。显然,某些Windows机制正在干扰这里。
我也在Windows下尝试过相同的应用程序。下面是它的样子。

这对任何地方的阴影都是正确的。啊!
因此,正如安德烈亚斯所建议的那样,这似乎是Vista/W7的一件事。
(*较早版本的文本和屏幕显示没有影子出现。然而,这是因为我关闭了Windows显示选项“菜单下的阴影”。)
发布于 2010-08-21 13:10:08
找到了!这是证据:

正如您所看到的,下拉阴影现在正确地显示在窗体上。
问题出在Z秩序上。事实证明,阴影本身就是Windows自己维护的一个单独的窗口。在Windows 7中,它似乎显示了主窗口下面的阴影。为了使它正确地显示,需要将它向上移动。
一个名为Łukasz Płomiński的天才在Embarcadero新闻组的一个线程中解释了这一点。下面是他整理的代码:
procedure TForm1.FixSysShadowOrder;
function FindSysShadowOrderProc(WindowHandle: HWND; // handle to window
Form: TForm1 // application-defined value, 32-bit
): BOOL; stdcall;
var
Buffer: array [0 .. 255] of char;
Rect: TRect;
begin
Result := True;
if IsWindowVisible(WindowHandle) then
begin
// this code search for SysShadow window created for this window.
GetClassName(WindowHandle, Buffer, 255);
if 0 <> AnsiStrComp(Buffer, PChar('SysShadow')) then
Exit;
GetWindowRect(WindowHandle, Rect);
if (Rect.Left <> Form.Left) or (Rect.Top <> Form.Top) then
Exit;
Form.FSysShadowHandle := WindowHandle;
// stop enumeration
Result := False;
end;
end;
begin
if not(csDesigning in ComponentState) and
((GetClassLong(Handle, GCL_STYLE) and CS_DROPSHADOW) = CS_DROPSHADOW)
and IsWindowVisible(Handle) then
begin
// for speed, proper SysShadow handle is cached
if FSysShadowHandle = 0 then
EnumThreadWindows(GetCurrentThreadID(), @FindSysShadowOrderProc,
lParam(Self));
// if SysShadow exists, change its z-order, and place it directly below this window
if FSysShadowHandle <> 0 then
SetWindowPos(FSysShadowHandle, Handle, 0, 0, 0, 0,
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOOWNERZORDER or SWP_NOSIZE);
end;
end;您必须确定何时调用FixSysShadowOrder(),因为Z命令会发生变化,而且不会保持正确。WM_WINDOWPOSCHANGED ukasz建议在空闲例程中调用它(例如,在更新操作时),并在收到Ł消息时调用它。
发布于 2010-08-20 14:09:55
“它在我的电脑上工作。”

但这是相当有趣的,因为我有一个微弱的记忆,作出了与您相同的结论,即,没有厚的,可调整的框架,CS_DROPSHADOW是无法工作的。您可能还在运行Windows吗?
发布于 2010-10-01 10:26:24
要使drop阴影工作,我们必须调用带有SystemParametersInfo win32参数的SPI_SETDROPSHADOW API,以打开整个系统的下降阴影效果,有关更多信息,请参见:
SystemParametersInfo
https://stackoverflow.com/questions/3530051
复制相似问题