Win32:

2009-05-27 18 views
26

top bir pencere getir ben içinde iki 2 pencere bulunmaktadır Windows programı: Ben hwnd üzerine çift tıkladığımdaWin32:

hwnd (main interface) 

hwnd2 (toplevel window, no parent, created by hwnd) 

, ben hwnd2 açılır ve bazı verileri göstermek gerekir, bu yüzden üst için hwnd2 getirmek için bu işlevi kullanın:

BringWindowToTop(hwnd2); 

hwnd2 üste getirilir, ancak tek bir şey var. Yine hwnd2'ye tıkladığımda, hwnd (ana arayüz) otomatik olarak tekrar açılır. Bu sorunu çözmek için aşağıdaki işlevi kullanmayı denedim, ancak bunlar çalışmıyor.

SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
                    //doesn't work 

BringWindowToTop(hwnd2); //This is the function brings hwnd2 to top 

SetForegroundWindow(hwnd2); //doesn't work 

SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
                    //doesn't work 

SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
             // hwnd2 "always" on top, not what I want 

SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks) 

SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function 
SwitchToThisWindow(hwnd2, FALSE); 

Bu sorunu nasıl çözebilirim? Şimdiden teşekkürler.

(hwnd2 oluşmaktadır bir medya oynatıcı (o geri diğer pencerelerin/önünde olabilir, böylece üst düzey olarak pencere gerektiğinden AJ yanıtlamak, hwnd2 üst öğesi yok) birçok pencere, pencere birinin video dispaly, ilerleme çubuğu ve hacim çubuğu, kontrol paneli için bir araç çubuğu kontrolü için diğer iki trackbar kontrolleri içindir.)

(bu ben tıklayın hangi pencere olursa olsun, yardımcı olabilecek biri var hwnd2, hwnd, "fare, Z-düzeninde hwnd'nin üstündedir," menü çubuğu ve istemci olmayan alan dahil olmak üzere, otomatik olarak açılır.)

(Bu medya oynatıcı Direct Show'da yazılmıştır. Video penceresini video penceresi olarak koymak için IVideoWindow :: put_Owner kullanıyorum, Direct Show dahili olarak video penceresinin alt öğesi olarak bir alt video penceresi oluşturur. Kaynak kodunu göremediğim bu alt-video penceresi dışında, hwnd2'de şüpheli bir şey göremiyorum.)

Bunun sebebini, Direkt Şov nedeniyle buldum. Bunu yapmak için multithread kullanıyorum ve sonra problem çözüldü. Ama neden??

Bu sorun PostMessage (SendMessage yerine) kullanılarak çözülebilir.

+2

hwnd2'nin neden ebeveynleri yok? hwnd oluşturma sırasında ebeveyn olarak ayarlanabilir. –

+0

hwnd2'nin fare tuşu işlem kodunda ne yaparsınız? Orada balık var mı? –

+1

PostMessage kullanarak nasıl çözdünüz? –

cevap

6

SwitchToThisWindow benim için en uygun olanıdır.

+15

MSDN: Bu işlev, kullanımdan kaldırılmıştır ve genel kullanıma yönelik değildir. Yeni programlarda kullanmamanız önerilir çünkü Windows'un sonraki sürümlerinde değiştirilmiş ya da kullanılamayabilir. –

+2

Microsoft bir şey onaylanmadığını söylüyorsa, ahbap, o zaman kullanımdan kaldırıldı. Hala kullanıp kullanmayacakları. –

4

SwitchToThisWindow() hiç kullanımdan kaldırılmamıştır.
14 yıl üretim ortamında kullanıyorum.
bakınız, Windows kaynak kodu ve bunu her yerde denir göreceksiniz ...

+0

Burada "hile" için sadece onu aramak gerekmez. Ama bu durumda, zaten bir ön pencereye sahibiz, bu yüzden aktif pencereyi değiştirme hakkımız var – Anders

13

Hem büyük iş:

::SetForegroundWindow(wnd) 

veya

::SetWindowPos(m_hWnd,  // handle to window 
      HWND_TOPMOST, // placement-order handle 
      0,  // horizontal position 
      0,  // vertical position 
      0, // width 
      0, // height 
      SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE// window-positioning options 
      ); 

Ama sonuncusu penceresini her zaman batmaz unutmayın üst.

+9

Her ikisi de win10 üzerinde çalışmaz –

+0

Biraz gecikebilirim, fakat pencereyi göstermeden önce ':: SetForegroundWindow' çağırmalısınız. Pencereyi güncellediğinizden emin olun). – Cedric

-4

// harika çalış!

Var 
WndHandle:HWND; 

begin 
WndHandle :=FindWindowEx(0,0,nil,'Calculator'); 
PostMessage(WndHandle,WM_SHOWWINDOW,SW_RESTORE,0); 
SetForegroundWindow(WndHandle); 
end; 
15

bu deneyin, bu sorunun çözümü aşağıdaki birçok denemeden ve errors.I sonra M $

HWND hCurWnd = ::GetForegroundWindow(); 
    DWORD dwMyID = ::GetCurrentThreadId(); 
    DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL); 
    ::AttachThreadInput(dwCurID, dwMyID, TRUE); 
    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
    ::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
    ::SetForegroundWindow(m_hWnd); 
    ::AttachThreadInput(dwCurID, dwMyID, FALSE); 
    ::SetFocus(m_hWnd); 
    ::SetActiveWindow(m_hWnd); 
+0

Bu sihirli şarkı ve dansı uzun zamandır arıyordum. Benim için mükemmel çalışıyor. – ulatekh

+0

Hala ne yaptığını anlayamıyorum, ama sadece –

+0

çalışır. Bu yüzden neden "büyü" diye isimlendirdim :-) – ulatekh

0

gelen bulundu söylenir:

SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); // restore the minimize window 
SetForegroundWindow(hwnd); 
SetActiveWindow(hwnd); 
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); 
RedrawWindow(hwnd,nil,0,RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); // redraw to prevent the window blank. 

hwnd windows olduğunu HWND. Lütfen sadece kopyalayıp yapıştırmayın. Ayrıca, her sesli aramadan sonra api hatasını kontrol etmek için GetLastError kullanmanız gerekir.

  • pencere ve hiçbir hata geri dönüşü en aza geri Can:

    benim win7 üzerinde onayla aşağıdaki sonucu vardır.

  • Eğer pencere zaten üstte ise, pencere başlığı yanıp söner ve hiçbir hata geri dönmez.
  • Pencere kapalıysa, "0x578 Geçersiz pencere tanıtıcısı" hatasını döndürür.
  • Pencereyi en üstteki pencerede olmayan pencerelere getirebilir ve hata döndürür (örneğin, en üstteki görev yöneticisinin arkasında kalır)
  • Pencereyi en iyi şekilde yapmaz. Kullanıcı bunun üstünde başka bir pencere yapabilir.