2010-08-20 20 views
14

Bir açılan pencerenin veya bir açılan pencerenin veya bir açılır pencerenin aşağı açılan kısmı gibi davranan bir TForm türevi yapıyorum - geçici bir şey. Altyazısı yok - BorderStyle bsNone'a ayarlandı. Form, pozisyonunu ayarlayarak, formu kullanarak moda olmayan bir şekilde görüntülenir. Alt gölge içeren kenarlıksız TForm

Göze çarpmasını sağlamak için, sınırının etrafında bir alt gölgeye ihtiyaç duyar. Bununla birlikte, sınırının bsNone'a ayarlanmasının bir sonucu, alt gölgenin kaybolmasıdır.

Çeşitli Google kaynakları bu varyasyonlarını önermek:

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; 

ama çalışmıyor - gölge gösterilmez (Ben de korkunç görünüyor WS_THICKFRAME seti ile yeniden boyutlandırılabilir bir sınır oluşturur sürece). Bu bir açılır pencere, bir çocuk penceresi değil, bu yüzden neden başarısız olduğunu anlamıyorum.

Öneriler lütfen?

NB: Bu soru, yanıtsız kalan this sorusuna benzer bir sorudur.

NB2: TShadowWindow adlı bir belirsiz VCL bileşeni var, doğru olanı yapacak gibi görünüyor, ancak pratik olması için çok kaba yazılmış olduğu ortaya çıkıyor.

Güncelleme: Aşağıdaki Andreas 'yorumları aşağıda, bunu daha fazla araştırmış ve bazı bulgular buldum.

Windows 7 altında, aynı uygulama'dan başka bir pencerenin üzerindeyken, açılır pencerenin açıldığında gölgenin görünmediğini keşfettim.

Burada açıklandığı gibi bir gölge istemek için bir açılır pencerede CreateParams kullanan basit bir Delphi uygulaması.

Windows 7 with shadow only over desktop

ana pencerenin dışına taştığı gölge nasıl göründüğünü görün?

Ancak kenarlıksız pencereyi ana pencerede bir açılır pencere olarak kullanmak istiyorum. Alt gölge, pencereyi altından pencereden ayırır. Yukarıdaki tüm açıklamalarım bu duruma işaret ediyor. Açıkçası, bazı Windows mekanizmaları burada karışıyor.

Aynı uygulamayı Windows XP altında da denedim. İşte göründüğü gibi.

Same application under XP

Bu * her yerde gölge ile düzgün çalışır. Gah! Andreas'ın da belirttiği gibi, bir Vista/W7 olayı gibi görünebilir.

(* Bu metin ve ScreenDump bir önceki sürümü hiçbir gölge Windows XP ekran seçeneğin 'Shadows menüler altında' olduğu için kapalı. Ancak bu olduğu ortaya çıktı ortaya çıktı önerdi. Duh.)

+0

Bilmiyorum Pencerenizi nasıl istediğinizi tam olarak anlayın. Bunu yapmak istemiyorsunuz * RAD Studio IDE'de Code Insight açılır penceresi (kalın yeniden boyutlandırılabilir bir kenarlığa sahip) olmasını ister misiniz? –

+0

@Andreas: Doğru. Yeniden boyutlandırılabilir bir kenarlık istemiyorum - bu soruda belirtildiği gibi WS_THICKFRAME ayarlayarak bunu yapabilirim. Sınırlarının, bir menü, yani gölgeli tek ince çizgi gibi görünmesini istiyorum. Aslında, bundan bahsettiniz, ben Code Insight'ın içeriğe bağlı olarak en az üç farklı pencere olduğunu fark ettim. Yeniden boyutlandırılabilir sınırları olmayanlar gibi olmak istiyorum! :-) – willw

cevap

6

buldum İşte kanıtı.

alt text

Gördüğünüz gibi, gölge şimdi formda üzerinde düzgün gösterilene

Sorun Z-düzeninden biriydi. Gölgenin kendisi Windows tarafından korunan ayrı bir pencere olduğu ortaya çıkıyor. Windows 7'de, ana pencerenin altındaki gölgeyi gösteriyor gibi görünüyor. Düzgün görüntülenmesini sağlamak için, onu hareket ettirmek gerekiyor.

Łukasz Płomiński adında bir dahi, bunu Embarcadero haber grubundaki bir başlıkta açıkladı. İşte bunu çözmek için onun kodudur:

Sen Z emir değişmesi sonucu FixSysShadowOrder() aramaya ve bunun doğru kalmayacak zaman dışarı çalışmak zorunda
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; 

. Łukasz, boş bir rutinde (örneğin bir Eylem güncellenirken) ve WM_WINDOWPOSCHANGED mesajının alınması üzerine onu çağırmayı önerdi.

+0

Hm ... Microsoft Windows'da buna bir hata diyebiliriz. –

+0

d2010 altında bu satır derleyemez, 'Form.FSysShadowHandle' ... –

+0

@Edwin Yip: Evet yapabilir. Kodun yorumunda belirtildiği gibi, tanıtıcıyı önbelleğe almak için FSysShadowHandle'ı TForm1'de ilan edersiniz. – willw

3

"Bilgisayarımda çalışıyor."

http://privat.rejbrand.se/shdw.png
(High-res)

Ama yaptığınız gibi aynı sonuca yapma soluk hafızaya sahip için, o CS_DROPSHADOW kalın, yeniden boyutlandırılabilir, çerçeve olmadan çalışmaz yani, oldukça komik. Hala öyle misin ?! belki Windows Vista çalıştıran

+0

Bu mükemmel bir nokta - çok teşekkürler. Windows 7 kullanıyordum ve kendi testimden fark yaratan ... en az iki farklı şekilde çalışmıyor! Sorunu, durumu bildiğimden daha karmaşık yansıtacak şekilde düzenlemek üzereyim. – willw

3

gölge yapmak için daha fazla bilgi için, tüm sistemin gölge etkisi açmak için, SPI_SETDROPSHADOW parametresi SystemParametersInfo win32 API çağırmak zorunda çalışmak, bakınız:

SystemParametersInfo