36

私は窓を持っています。SetWindowPos(window, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);

画面全体をカバーしますが、タスクバーもカバーするのに時間がかかります (0.5 秒)。

すぐにタスクバーに来る方法はありますか? 設定HWND_TOPMOSTするとすぐにそれが行われることがわかりましたが、アプリを切り替えても、他のすべてのウィンドウの上にとどまります-これは私が望んでいないことです. また、最初にウィンドウを非表示にしてから表示すると、ウィンドウが強制的に再描画され、すぐにタスクバーが覆われますが、ちらつきます(非表示のため)。別の方法はありますか?

4

6 に答える 6

49

2を編集します。フルスクリーンを行うためのより良い方法、クロムの方法、ここから取得したソースがあります:

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

void FullscreenHandler::SetFullscreenImpl(bool fullscreen, bool for_metro) {
  ScopedFullscreenVisibility visibility(hwnd_);

  // Save current window state if not already fullscreen.
  if (!fullscreen_) {
    // Save current window information.  We force the window into restored mode
    // before going fullscreen because Windows doesn't seem to hide the
    // taskbar if the window is in the maximized state.
    saved_window_info_.maximized = !!::IsZoomed(hwnd_);
    if (saved_window_info_.maximized)
      ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_RESTORE, 0);
    saved_window_info_.style = GetWindowLong(hwnd_, GWL_STYLE);
    saved_window_info_.ex_style = GetWindowLong(hwnd_, GWL_EXSTYLE);
    GetWindowRect(hwnd_, &saved_window_info_.window_rect);
  }

  fullscreen_ = fullscreen;

  if (fullscreen_) {
    // Set new window style and size.
    SetWindowLong(hwnd_, GWL_STYLE,
                  saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME));
    SetWindowLong(hwnd_, GWL_EXSTYLE,
                  saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME |
                  WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));

    // On expand, if we're given a window_rect, grow to it, otherwise do
    // not resize.
    if (!for_metro) {
      MONITORINFO monitor_info;
      monitor_info.cbSize = sizeof(monitor_info);
      GetMonitorInfo(MonitorFromWindow(hwnd_, MONITOR_DEFAULTTONEAREST),
                     &monitor_info);
      gfx::Rect window_rect(monitor_info.rcMonitor);
      SetWindowPos(hwnd_, NULL, window_rect.x(), window_rect.y(),
                   window_rect.width(), window_rect.height(),
                   SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
    }
  } else {
    // Reset original window style and size.  The multiple window size/moves
    // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be
    // repainted.  Better-looking methods welcome.
    SetWindowLong(hwnd_, GWL_STYLE, saved_window_info_.style);
    SetWindowLong(hwnd_, GWL_EXSTYLE, saved_window_info_.ex_style);

    if (!for_metro) {
      // On restore, resize to the previous saved rect size.
      gfx::Rect new_rect(saved_window_info_.window_rect);
      SetWindowPos(hwnd_, NULL, new_rect.x(), new_rect.y(),
                   new_rect.width(), new_rect.height(),
                   SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
    }
    if (saved_window_info_.maximized)
      ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  }
}

編集します。BrendanMcK がこの回答へのコメントで指摘したように、フルスクリーン ウィンドウを作成することをお勧めします。次のリンクを参照してください (「フルスクリーン ウィンドウでタスク バーを覆うにはどうすればよいですか?」)

上記のリンクを使用した新しいコードは次のようになります。

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);
}

以下の古い回答-使用しないでください。これを行う方法についての記録のためだけにとどまります。

すぐに全画面表示するには、タスクバーとメニューバーを非表示にする必要があります。

コードは次のとおりです (WTL を使用)。SetFullScreen(true) を呼び出して全画面表示モードにします。

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);
        }       
    }
};

また、WM_CLOSE メッセージにいくつかのコードを追加する必要があります。

case WM_CLOSE:
    ShowTaskBar(true);

このソリューションには注意点が 1 つあります。アプリケーションがクラッシュしたり、タスク マネージャーによって強制終了されたりすると、ユーザーはシステムのタスクバーを永久に失います。(アプリケーションを再度実行し、全画面表示にして終了しない限り、タスクバーが再び表示されます)。

以前の回答で「atlwince.h」を指摘しましたが、その機能は Windows CE でのみ機能し、上に貼り付けた機能は XP、Vista、および 7 で正常に機能します。

于 2011-03-14T14:10:14.343 に答える
19

うん、HWND_TOPMOST私のためにそれをします。これは、フルスクリーンをうまく(そして素早く)機能させるコードのセクションです。


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;
}

間違った設定をすると、解像度が変更されることに注意してください。これは私が通常望んでいることですが、それが気に入らない場合は、次を使用して解決策を見つけることができます ( whereはormainWindowのようなものから返されます):CreateWindow()CreateWindowEx()


windowHDC = GetDC(mainWindow);
fullscreenWidth  = GetDeviceCaps(windowHDC, DESKTOPHORZRES);
fullscreenHeight = GetDeviceCaps(windowHDC, DESKTOPVERTRES);
colourBits       = GetDeviceCaps(windowHDC, BITSPIXEL);
refreshRate      = GetDeviceCaps(windowHDC, VREFRESH);

全画面表示から抜け出したい場合は、次のようにします。


bool exitFullscreen(HWND hwnd, int windowX, 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;
}

ホットキーを使用してフルスクリーン モードとウィンドウ モードを切り替えるようにコードを設定し、ウィンドウ モード変数をグローバルとして保持することで、ウィンドウ モードに変更しても変数がそのまま残るようにします。

このコードには、「排他モード」と同等で実行できるという利点もあります (私は XP を使用しており、Windows の新しいバージョンでは試していません)。つまり、はるかに高速になります。(私のはるかに大きなコードから) コードを要約することで間違いを犯した場合はお知らせください。

于 2010-03-10T11:56:52.480 に答える
10

Raymond Chen は、彼のブログでこれを行う「正しい」方法について説明しています。

https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353

タスク バー ウィンドウを明示的にいじることは、推奨される動作ではありません。

于 2012-03-13T11:53:42.673 に答える
1

シェルフックが「失礼なアプリ」について通知すると、タスクバーが邪魔にならなくなると思いますが、これには少し時間がかかる場合があります。

ウィンドウ HWND_TOPMOST から始めて、1 秒後に一番上にならないようにするとどうなるでしょうか?

于 2010-03-06T16:56:32.537 に答える
-5
  1. タスクバーを右クリック
  2. プロパティを選択
  3. 「タスクバーを他のウィンドウの手前に表示する」というチェックボックスをオフにします。

タスクバーはユーザーに属します。アプリが全画面表示になったときに、自動的に非表示になるまでに 1/2 秒かかるかどうかはユーザー次第です。彼らがその行動を変えたいのなら、彼らはそれを変えることができます。

組み込みシステムで作業している場合、タスクバーを非表示にする正当な理由がある場合があります。しかし、その場合、タスク バーが常に最前面に表示されないように単純に構成しない理由はありません。SystemParametersInfoコードでこれらの設定の一部を変更する場合は、 を参照することもできます。

于 2010-03-06T01:06:53.893 に答える