2010-03-04 36 views
22

Tôi có một cửa sổ, mà tôi SetWindowPos(window, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);Win32: toàn màn hình và ẩn thanh tác vụ

Nó bao gồm toàn bộ màn hình, ok, nhưng phải mất một thời gian (0,5 giây) để trang trải các thanh tác vụ là tốt.

Có cách nào để truy cập thanh tác vụ ngay lập tức không? Tôi thấy rằng thiết lập HWND_TOPMOST làm điều đó ngay lập tức, nhưng nó vẫn ở trên tất cả các cửa sổ khác, ngay cả khi tôi chuyển đổi ứng dụng - đây là điều tôi không muốn. Ngoài ra, nếu tôi lần đầu tiên ẩn cửa sổ và sau đó hiển thị nó, nó bằng cách nào đó lực lượng cửa sổ để vẽ lại và bao gồm thanh tác vụ ngay lập tức, nhưng nó flickers (vì ẩn). Có cách nào khác không?

Trả lời

34

Chỉnh sửa 2.Thậm chí còn có một cách tốt hơn để thực hiện toàn màn hình, cách crom, nguồn lấy từ đây:

http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=HEAD&view=markup

Sửa. Có lẽ tốt hơn nên tạo cửa sổ toàn màn hình khi BrendanMcK chỉ ra trong một nhận xét cho câu trả lời này, xem liên kết này: http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx ("Làm cách nào để che thanh tác vụ bằng cửa sổ toàn màn hình?")

Mã mới sử dụng liên kết ở trên sẽ là:

HWND CreateFullscreenWindow(HWND hwnd) 
{ 
HMONITOR hmon = MonitorFromWindow(hwnd, 
            MONITOR_DEFAULTTONEAREST); 
MONITORINFO mi = { sizeof(mi) }; 
if (!GetMonitorInfo(hmon, &mi)) return NULL; 
return CreateWindow(TEXT("static"), 
     TEXT("something interesting might go here"), 
     WS_POPUP | WS_VISIBLE, 
     mi.rcMonitor.left, 
     mi.rcMonitor.top, 
     mi.rcMonitor.right - mi.rcMonitor.left, 
     mi.rcMonitor.bottom - mi.rcMonitor.top, 
     hwnd, NULL, g_hinst, 0); 
} 

Cũ câu trả lời dưới đây - không sử dụng nó, vẫn chỉ dành cho các kỷ lục về cách kHÔNG để làm điều này.

Bạn phải ẩn thanh tác vụ và thanh thực đơn để xem toàn màn hình ngay lập tức.

Đây là mã (sử dụng WTL), gọi SetFullScreen (true) để đi vào chế độ toàn màn hình:

template <class T, bool t_bHasSip = true> 
class CFullScreenFrame 
{ 
public: 
    bool m_fullscreen; 
    LONG m_windowstyles; 
    WINDOWPLACEMENT m_windowplacement; 

    CFullScreenFrame() 
     : 
     m_fullscreen(false), 
     m_windowstyles(0) 
    { } 

    void SetFullScreen(bool fullscreen) 
    { 
     ShowTaskBar(!fullscreen); 

     T* pT = static_cast<T*>(this); 

     if (fullscreen) { 
      if (!m_fullscreen) { 
       m_windowstyles = pT->GetWindowLongW(GWL_STYLE); 
       pT->GetWindowPlacement(&m_windowplacement); 
      } 

     } 

     // SM_CXSCREEN gives primary monitor, for multiple monitors use SM_CXVIRTUALSCREEN. 
     RECT fullrect = { 0 };    
     SetRect(&fullrect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); 

     WINDOWPLACEMENT newplacement = m_windowplacement; 
     newplacement.showCmd = SW_SHOWNORMAL; 
     newplacement.rcNormalPosition = fullrect; 

     if (fullscreen) { 
      pT->SetWindowPlacement(&newplacement); 
      pT->SetWindowLongW(GWL_STYLE, WS_VISIBLE); 
      pT->UpdateWindow(); 
     } else { 
      if (m_fullscreen) { 
       pT->SetWindowPlacement(&m_windowplacement); 
       pT->SetWindowLongW(GWL_STYLE, m_windowstyles); 
       pT->UpdateWindow(); 
      } 
     } 

     m_fullscreen = fullscreen; 
    } 

    void ShowTaskBar(bool show) 
    { 
     HWND taskbar = FindWindow(_T("Shell_TrayWnd"), NULL); 
     HWND start = FindWindow(_T("Button"), NULL); 

     if (taskbar != NULL) { 
      ShowWindow(taskbar, show ? SW_SHOW : SW_HIDE); 
      UpdateWindow(taskbar); 
     } 
     if (start != NULL) { 
      // Vista 
      ShowWindow(start, show ? SW_SHOW : SW_HIDE); 
      UpdateWindow(start); 
     }  
    } 
}; 

Bạn cũng có thêm một số mã để WM_CLOSE nhắn:

case WM_CLOSE: 
    ShowTaskBar(true); 

Có một lời nhắc nhở với giải pháp này, nếu ứng dụng của bạn bị treo hoặc bị giết thông qua trình quản lý tác vụ, thì thanh tác vụ mất người dùng trên hệ thống của anh ta vĩnh viễn! (trừ khi anh ta chạy ứng dụng của bạn một lần nữa, đi vào toàn màn hình và thoát ra, sau đó anh ta sẽ thấy thanh tác vụ một lần nữa).

Đầu trong câu trả lời của tôi, tôi chỉ vào "atlwince.h" nhưng chức năng mà chỉ làm việc trên Windows CE, là tôi dán trên hoạt động tốt với XP, Vista và 7.

+2

-1 vì bạn không nên gây rối với thanh tác vụ; nó không cần thiết ở nơi đầu tiên; xem blog của Raymond Chen về điều này ở đây: [Làm cách nào để che thanh tác vụ bằng cửa sổ toàn màn hình?] (http://blogs.msdn.com/b/oldnewthing/archive/2005/05/05/414910.aspx) – BrendanMcK

+0

@ BrendanMcK: Tôi đã chỉnh sửa câu trả lời của mình. Chúc bạn ngày mới tốt lành. –

+0

Tuyệt vời, -1 được chuyển đổi thành +1. (Thực ra tôi hơi quá nhanh với điều đó -1 ngay từ đầu, tôi nên để lại lời bình trước. Tôi nghĩ mình đã trở nên quá nhạy cảm khi nhìn thấy cửa sổ hack trong nhiều năm -!) – BrendanMcK

-3
  1. Nhấp chuột phải vào thanh tác vụ
  2. chọn Thuộc tính
  3. bỏ chọn hộp kiểm nói rằng "Giữ thanh tác vụ trên các cửa sổ khác".

Thanh tác vụ thuộc về người dùng , Tùy thuộc vào việc phải tự động ẩn khi bạn sử dụng toàn màn hình mất 1/2 giây. Nếu họ muốn thay đổi hành vi đó thì họ có thể thay đổi hành vi đó.

Nếu bạn đang làm việc trong một hệ thống nhúng, thì bạn có thể có lý do chính đáng để ẩn thanh tác vụ. Nhưng trong trường hợp đó, không có lý do gì để không chỉ cần cấu hình thanh tác vụ để không phải lúc nào cũng ở trên cùng. Bạn cũng có thể xem SystemParametersInfo nếu bạn muốn thay đổi một số cài đặt này trong mã của mình.

+0

OK và mỗi lần bạn bắt đầu trò chơi, bạn muốn thực hiện ba bước trước và sau đó khôi phục trạng thái cũ? Có thật không? – user2328447

+0

user2328447, bạn có đang trolling không? Trạng thái của thanh tác vụ bị bỏ qua khi trò chơi chuyển sang chế độ toàn màn hình - vì vậy sẽ là cả ngu ngốc và bị hỏng cho các trò chơi gây rối với thanh tác vụ - nhưng chắc chắn bạn đã nhận thấy điều này ... –

+0

Trong chế độ toàn màn hình, thanh tác vụ KHÔNG bị bỏ qua. Đó là chính xác những gì các poster ban đầu yêu cầu. Một số trò chơi sử dụng này. – user2328447

1

Tôi tin rằng thanh tác vụ sẽ thoát ra khỏi con đường khi móc vỏ của nó cho biết về "ứng dụng thô lỗ", quá trình này có thể mất một chút thời gian.

Điều gì xảy ra nếu bạn bắt đầu với cửa sổ HWND_TOPMOST và đặt nó ở vị trí cao nhất sau 1 giây?

13

Yup, HWND_TOPMOST làm điều đó cho tôi. Đây là một phần của mã mà làm cho toàn màn hình cũng làm việc (và nhanh) cho tôi:


bool enterFullscreen(HWND hwnd, int fullscreenWidth, int fullscreenHeight, int colourBits, int refreshRate) { 
    DEVMODE fullscreenSettings; 
    bool isChangeSuccessful; 
    RECT windowBoundary; 

    EnumDisplaySettings(NULL, 0, &fullscreenSettings); 
    fullscreenSettings.dmPelsWidth  = fullscreenWidth; 
    fullscreenSettings.dmPelsHeight  = fullscreenHeight; 
    fullscreenSettings.dmBitsPerPel  = colourBits; 
    fullscreenSettings.dmDisplayFrequency = refreshRate; 
    fullscreenSettings.dmFields   = DM_PELSWIDTH | 
              DM_PELSHEIGHT | 
              DM_BITSPERPEL | 
              DM_DISPLAYFREQUENCY; 

    SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST); 
    SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); 
    SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fullscreenWidth, fullscreenHeight, SWP_SHOWWINDOW); 
    isChangeSuccessful = ChangeDisplaySettings(&fullscreenSettings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL; 
    ShowWindow(hwnd, SW_MAXIMIZE); 

    return isChangeSuccessful; 
} 

Lưu ý rằng điều này sẽ thay đổi độ phân giải nếu bạn nói với nó các thiết lập sai. Đây là những gì tôi thường muốn, nhưng nếu bạn không thích điều đó, bạn có thể tìm hiểu độ phân giải của bạn bằng cách sử dụng (trong đó mainWindow được trả về từ một cái gì đó giống như CreateWindow() hoặc CreateWindowEx()):


windowHDC = GetDC(mainWindow); 
fullscreenWidth = GetDeviceCaps(windowHDC, HORZRES); 
fullscreenHeight = GetDeviceCaps(windowHDC, VERTRES); 
colourBits  = GetDeviceCaps(windowHDC, BITSPIXEL); 
refreshRate  = GetDeviceCaps(windowHDC, VREFRESH); 

Khi bạn muốn thoát ra khỏi của toàn màn hình bạn làm điều gì đó như thế này:


bool exitFullscreen(HWND hwnd, int windowW, int windowY, int windowedWidth, int windowedHeight, int windowedPaddingX, int windowedPaddingY) { 
    bool isChangeSuccessful; 

    SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_LEFT); 
    SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE); 
    isChangeSuccessful = ChangeDisplaySettings(NULL, CDS_RESET) == DISP_CHANGE_SUCCESSFUL; 
    SetWindowPos(hwnd, HWND_NOTOPMOST, windowX, windowY, windowedWidth + windowedPaddingX, windowedHeight + windowedPaddingY, SWP_SHOWWINDOW); 
    ShowWindow(hwnd, SW_RESTORE); 

    return isChangeSuccessful; 
} 

tôi đặt mã của tôi để thay đổi giữa độ toàn màn hình và chế độ cửa sổ bằng cách sử dụng phím nóng, và tôi giữ các biến chế độ cửa sổ như toàn cầu, do đó khi chuyển sang cửa sổ chế độ, nó vẫn đặt.

Mã này cũng có lợi thế là chạy tương đương với "chế độ độc quyền" (tôi đang sử dụng XP và chưa thử trên các phiên bản cửa sổ mới hơn), điều đó có nghĩa là nó sẽ nhiều, nhiều nhanh hơn. Hãy cho tôi biết nếu tôi đã thực hiện bất kỳ sai lầm nào từ việc ngưng tụ mã (từ mã lớn hơn của tôi).

+0

Cảm ơn bạn đã trả lời. Tôi nghĩ lý do tại sao nó hoạt động là bạn thay đổi kích thước cửa sổ ít nhất hai lần "SetWindowPos() và ShowWindow()" (Tôi không biết rằng "ChangeDisplaySettings()"). Vấn đề là, điều gì sẽ xảy ra nếu tôi đã ở trong "SW_MAXIMIZE" và những gì để đi toàn màn hình? –

+0

Tôi đọc ở đâu đó có loại "bộ nhớ cache" của trình quản lý cửa sổ. Vì vậy, tôi đã hy vọng có một cách để buộc nó làm mới hoặc nói với nó rằng nó nên sơn lại thanh tác vụ bên dưới. –

+0

Nói cách khác, có vẻ như với tôi rằng "SW_MAXIMIZE" làm điều gì đó ngoài việc thay đổi kích thước và tôi muốn biết những gì ... –

Các vấn đề liên quan