2013-03-06 9 views
7

Próbuję utworzyć okno bez obramowań, które zachodzi na pasek zadań potencjalnie w trybie pełnoekranowym (bez używania ChangeDisplaySettings(&settings, CDS_FULLSCREEN);) i nie mogę w pełni określić, jak to zrobić. Próbowałem prawie każdej możliwej kombinacji stylu CreateWindowEx bez powodzenia.win32 (pełnoekranowy) okienkowy nakładający się na siebie pasek z nakładaniem okna

Ma to na celu wyrenderowanie w oknie bez ramki, za pomocą opengl/directx, przy jednoczesnym zezwoleniu na alt-tabbing przy dalszym renderowaniu w tle. Odbywa się to w wielu grach, takich jak opcja wow i dota2 (windowed fullscreen), a także w aplikacjach takich jak menedżer zadań windows7 (wykonano dwa zrzuty ekranu w vm, aby udowodnić ten pomysł) (Windows 8 nie ma takiego zachowania).

menedżer

Zadanie nie koncentruje:

Menedżer zadań koncentruje:

To jest jakiś minimalny kod używam do łatwego testowania kilka pomysłów miałem, ale żaden Naprawdę to zrobiłem. Tworzy tylko okno bez obramowania o rozmiarze ekranu-20 i wysokości ekranu-20.

#include <windows.h> 

static bool quit = false; 

static LRESULT CALLBACK message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) 
{ 
    switch(umsg) 
    { 
     case WM_DESTROY: 
      PostQuitMessage(0); 
     break; 
     case WM_CLOSE: 
      quit = true; 
     break; 
    } 

    return DefWindowProc(hwnd, umsg, wparam, lparam); 
} 

int main() 
{ 
    WNDCLASSEX wc; 
    HMODULE hInstance; 
    HWND hwnd; 
    MSG msg; 

    ZeroMemory(&msg, sizeof(MSG)); 
    hInstance = GetModuleHandle(NULL); 

    wc.style   = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
    wc.lpfnWndProc  = message_handler; 
    wc.cbClsExtra  = 0; 
    wc.cbWndExtra  = 0; 
    wc.hInstance  = hInstance; 
    wc.hIcon   = LoadIcon(NULL, IDI_WINLOGO); 
    wc.hIconSm   = wc.hIcon; 
    wc.hCursor   = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)COLOR_WINDOWFRAME; 
    wc.lpszMenuName  = NULL; 
    wc.lpszClassName = "test"; 
    wc.cbSize   = (unsigned int)sizeof(WNDCLASSEX); 

    RegisterClassEx(&wc); 

    hwnd = CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 10, 10, (int)GetSystemMetrics(SM_CXSCREEN)-20, (int)GetSystemMetrics(SM_CYSCREEN)-20, NULL, NULL, hInstance, NULL); 
    //hwnd = CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 0, 0, (int)GetSystemMetrics(SM_CXSCREEN), (int)GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL); 

    ShowWindow(hwnd, SW_SHOW); 
    SetForegroundWindow(hwnd); 
    SetFocus(hwnd); 

    while (!quit) 
    { 
     if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 

    return 0; 
} 

Korzystanie

CreateWindowEx(WS_EX_APPWINDOW, "test", "test", WS_OVERLAPPED|WS_POPUP, 0, 0, (int)GetSystemMetrics(SM_CXSCREEN), (int)GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL); 

ma zachodzić na pasek zadań, ale ma jakieś dziwne zachowanie podczas OpenGL renderuje na nim (miga/migotanie ekranu, takie jak przy zmianie trybu wideo. Same skutki wystąpiły przez kogoś on this forum jakiejś biblioteki, która tworzy okna między platformami do renderowania i innych rzeczy. Ktoś również zamieścił w tym wątku a video (careful, loud music), który pokazuje dokładnie to, co próbuję osiągnąć).

Mam pobraną bibliotekę opensource i próbowałem dowiedzieć się, co się dzieje, ale nie mogłem znaleźć nic specjalnego na temat sposobu, w jaki tworzy to okno.

Używanie g++ (Built by MinGW-builds project) 4.8.0 20121225 (experimental) w systemie Windows8.

+0

Widziałem twoją próbę edycji mojej odpowiedzi i doceniam to, co próbujesz zrobić. Typowe podejście do pokazania, co w końcu zadziałało, to zmodyfikowanie go na swoje pytanie. –

+0

@MarkRansom Rozumiem, dziękuję za poinformowanie mnie o tym. Kiedy robiłem to wszystko, nowa odpowiedź pojawiła się jednak, grając trochę z pomysłem "SetWindowPlacement", zanim zdecyduję, którego użyć. –

+0

Jeśli poczujesz potrzebę zmiany wybranej odpowiedzi, nie wezmę jej osobiście. –

Odpowiedz

3

Użyj SetWindowPos function, aby ustawić okno TOPMOST. Gdy pojawi się komunikat, że utraciłeś fokus, ustaw go ponownie na nieznajomy, aby wyświetlić inne okno, na które się przestawiłeś.

+0

Mark, Czy możesz skomentować, który komunikat powiedziałby, że stracił ostrość? Dzięki! (Właśnie wpadłem na ten sam problem). – bodacydo

+0

@bodacydo spróbuj ['WM_KILLFOCUS'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646282 (v = vs.85) .aspx). –

9

Raymond Chen explained how to switch in and out of full screen mode raczej po prostu zmieniając styl okna z SetWindowLong(Ptr) korzystając SetWindowPlacement do zmiany rozmiaru okna, a SetWindowPos aby upewnić się, że rama odświeża.

Pasek zadań wykrywa, kiedy okno próbuje być w trybie pełnoekranowym i automatycznie usuwa się z drogi.

+0

Interesujące informacje na temat zachowania paska zadań, założyłem, że musisz być na górze, aby dostać się na szczyt. –