как скрыть значки рабочего стола без перезагрузки компьютера [дубликат]

Я не могу ручаться за производительность, но вот трюк, вдохновленный ограничениями Microsoft Excel. У него есть некоторые хорошие функции

GOOD STUFF

  • Он должен принудительно вернуть только одну «максимальную запись», даже если есть галстук (иногда полезный)
  • Он не требует соединения

ПОДХОД

Это немного уродливо и требует, чтобы вы знали что-то о диапазоне допустимых значений rev . Предположим, что мы знаем, что столбец rev - это число от 0,00 до 999, включая десятичные числа, но что только две цифры справа от десятичной точки (например, 34.17 будет действительным значением) .

Суть заключается в том, что вы создаете единый синтетический столбец путем конкатенации / упаковки первичного поля сравнения вместе с данными, которые вы хотите. Таким образом, вы можете заставить агрегированную функцию SQL MAX () возвращать все данные (поскольку она была упакована в один столбец). Затем вам нужно распаковать данные.

Вот как это выглядит с помощью приведенного выше примера, написанного на SQL

SELECT id, 
       CAST(SUBSTRING(max(packed_col) FROM 2 FOR 6) AS float) as max_rev,
       SUBSTRING(max(packed_col) FROM 11) AS content_for_max_rev 
FROM  (SELECT id, 
       CAST(1000 + rev + .001 as CHAR) || '---' || CAST(content AS char) AS packed_col
       FROM yourtable
      ) 
GROUP BY id

Насыщение начинается с принудительного rev , чтобы быть числом известной длины символа, независимо от значения rev , так что, например,

  • 3.2 становится 1003.201
  • 57 становится 1057,001
  • 923.88 становится 1923.881

Если вы сделаете это правильно, сравнение строк двух чисел должно дать то же самое «max», что и числовое сравнение двух чисел, и легко конвертировать обратно в исходное число, используя функцию подстроки (которая доступна в той или иной форме практически везде).

9
задан Tibi 19 June 2011 в 15:08
поделиться

6 ответов

Вы можете сделать это с помощью Windows API. Вот пример кода на C #, который будет переключать значки на рабочем столе.

    [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll", SetLastError = true)] static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
    enum GetWindow_Cmd : uint
    {
        GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_ENABLEDPOPUP = 6
    }
    [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    private const int WM_COMMAND = 0x111;

    static void ToggleDesktopIcons()
    {
        var toggleDesktopCommand = new IntPtr(0x7402);
        IntPtr hWnd = GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD);
        SendMessage(hWnd, WM_COMMAND, toggleDesktopCommand, IntPtr.Zero);
    }

Отправляет сообщение в дочернее окно SHELLDLL_DefView Progman, которое сообщает ему переключать видимость (путем добавления или удаления стиля WS_VISIBLE) это только ребенок, «FolderView». «FolderView» - это фактическое окно, содержащее значки.

Чтобы проверить, видны ли значки или нет, вы можете запросить стиль WS_VISIBLE с помощью функции GetWindowInfo, показанной ниже:

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        private int _Left;
        private int _Top;
        private int _Right;
        private int _Bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct WINDOWINFO
    {
        public uint cbSize;
        public RECT rcWindow;
        public RECT rcClient;
        public uint dwStyle;
        public uint dwExStyle;
        public uint dwWindowStatus;
        public uint cxWindowBorders;
        public uint cyWindowBorders;
        public ushort atomWindowType;
        public ushort wCreatorVersion;

        public WINDOWINFO(Boolean? filler)
            : this()   // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
        {
            cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
        }

    }

Вот функция, вызывающая вышеуказанный код и возвращающая значение true, если окно видимо, false, если нет.

    static bool IsVisible()
    {
        IntPtr hWnd = GetWindow(GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD), GetWindow_Cmd.GW_CHILD);
        WINDOWINFO info = new WINDOWINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        GetWindowInfo(hWnd, ref info);
        return (info.dwStyle & 0x10000000) == 0x10000000;
    }

Код API Windows, а также дополнительная информация о стилях окна можно найти здесь: http://www.pinvoke.net/default.aspx/user32/GetWindowInfo.html

19
ответ дан Ondrej Balas 5 September 2018 в 09:36
поделиться

Вы можете создать приложение с полным экраном и сделать его самым верхним окном.

Затем запустите свое приложение с окнами.

1
ответ дан Amila Silva 5 September 2018 в 09:36
поделиться

Другой подход - создать отдельный рабочий стол и показать его. У него не будет значков.

Запуск приложения на отдельном рабочем столе

2
ответ дан Community 5 September 2018 в 09:36
поделиться

Вы делаете это неправильно. То, что вы действительно пытаетесь сделать, это заменить оболочку. Windows обеспечивает это, поэтому вы должны просто воспользоваться им. Напишите свою собственную оболочку для замены проводника.

0
ответ дан David Heffernan 5 September 2018 в 09:36
поделиться

Вы можете сделать это в RegEdit HKEY_CURRENT_USER \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Advanced изменить HideIcons на 1

    static void HideIcons()
    {
        RegistryKey myKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", true);
        if (myKey != null)
        {
            myKey.SetValue("HideIcons", 1);
            myKey.Close();
        }
    }

Использовать класс реестра, как описано здесь.

http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.aspx

1
ответ дан Jan-Fokke 5 September 2018 в 09:36
поделиться

Существует официальный API для подобных действий, он называется API-интерфейсом оболочки. Это должно быть предпочтительнее, чем манипулирование реестром и подход FindWindow / SendMessage, как очень хрупкие «решения», которые имеют тенденцию ломаться с будущими версиями Windows (для последних это уже подтвердили комментаторы).

Шаги:

  1. Получите интерфейс IFolderView2 рабочего стола (поддерживается с Windows Vista).
  2. Вызовите IFolderView2::SetCurrentFolderFlags() с помощью FWF_NOICONS для параметров dwMask и dwFlags.

Эффект флага видно сразу. Нет необходимости перезагружать компьютер или «explorer.exe». Флаг также сохраняется после выхода из системы или перезагрузки.

Сложная вещь - шаг 1). Raymond Chen показывает код C ++ для этой статьи в статье «Манипулирование положениями значков рабочего стола» , особенно в его функции FindDesktopFolderView().

Вот полный пример C ++ в форме консольное приложение. Он основан на коде Raymond Chen. Программа переключает видимость значков рабочего стола при каждом запуске.

Код был протестирован в Windows 10 Build 17134.

#include <ShlObj.h>     // Shell API
#include <atlcomcli.h>  // CComPtr & Co.
#include <string> 
#include <iostream> 
#include <system_error>

// Throw a std::system_error if the HRESULT indicates failure.
template< typename T >
void ThrowIfFailed( HRESULT hr, T&& msg )
{
    if( FAILED( hr ) )
        throw std::system_error{ hr, std::system_category(), std::forward<T>( msg ) };
}

// RAII wrapper to initialize/uninitialize COM
struct CComInit
{
    CComInit() { ThrowIfFailed( ::CoInitialize( nullptr ), "CoInitialize failed" ); }
    ~CComInit() { ::CoUninitialize(); }
};

// Query an interface from the desktop shell view.
void FindDesktopFolderView( REFIID riid, void **ppv, std::string const& interfaceName )
{
    CComPtr<IShellWindows> spShellWindows;
    ThrowIfFailed( 
        spShellWindows.CoCreateInstance( CLSID_ShellWindows ),
        "Failed to create IShellWindows instance" );

    CComVariant vtLoc( CSIDL_DESKTOP );
    CComVariant vtEmpty;
    long lhwnd;
    CComPtr<IDispatch> spdisp;
    ThrowIfFailed( 
        spShellWindows->FindWindowSW(
            &vtLoc, &vtEmpty, SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp ),
        "Failed to find desktop window" );

    CComQIPtr<IServiceProvider> spProv( spdisp );
    if( ! spProv )
        ThrowIfFailed( E_NOINTERFACE, "Failed to get IServiceProvider interface for desktop" );

    CComPtr<IShellBrowser> spBrowser;
    ThrowIfFailed( 
        spProv->QueryService( SID_STopLevelBrowser, IID_PPV_ARGS( &spBrowser ) ),
        "Failed to get IShellBrowser for desktop" );

    CComPtr<IShellView> spView;
    ThrowIfFailed( 
        spBrowser->QueryActiveShellView( &spView ),
        "Failed to query IShellView for desktop" );

    ThrowIfFailed( 
        spView->QueryInterface( riid, ppv ),
        "Could not query desktop IShellView for interface " + interfaceName );
}

void ToggleDesktopIcons()
{
    CComPtr<IFolderView2> spView;
    FindDesktopFolderView( IID_PPV_ARGS(&spView), "IFolderView2" );

    DWORD flags = 0;
    ThrowIfFailed( 
        spView->GetCurrentFolderFlags( &flags ), 
        "GetCurrentFolderFlags failed" );
    ThrowIfFailed( 
        spView->SetCurrentFolderFlags( FWF_NOICONS, flags ^ FWF_NOICONS ),
        "SetCurrentFolderFlags failed" );
}

int wmain(int argc, wchar_t **argv)
{
    try
    {
        CComInit init;

        ToggleDesktopIcons();

        std::cout << "Desktop icons have been toggled.\n";
    }
    catch( std::system_error const& e )
    {
        std::cout << "ERROR: " << e.what() << ", error code: " << e.code() << "\n";
        return 1;
    }

    return 0;
}
1
ответ дан zett42 5 September 2018 в 09:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: