Я не могу ручаться за производительность, но вот трюк, вдохновленный ограничениями 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 , так что, например,
Если вы сделаете это правильно, сравнение строк двух чисел должно дать то же самое «max», что и числовое сравнение двух чисел, и легко конвертировать обратно в исходное число, используя функцию подстроки (которая доступна в той или иной форме практически везде).
Вы можете сделать это с помощью 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
Вы можете создать приложение с полным экраном и сделать его самым верхним окном.
Затем запустите свое приложение с окнами.
Другой подход - создать отдельный рабочий стол и показать его. У него не будет значков.
Вы делаете это неправильно. То, что вы действительно пытаетесь сделать, это заменить оболочку. Windows обеспечивает это, поэтому вы должны просто воспользоваться им. Напишите свою собственную оболочку для замены проводника.
Вы можете сделать это в 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
Существует официальный API для подобных действий, он называется API-интерфейсом оболочки. Это должно быть предпочтительнее, чем манипулирование реестром и подход FindWindow
/ SendMessage
, как очень хрупкие «решения», которые имеют тенденцию ломаться с будущими версиями Windows (для последних это уже подтвердили комментаторы).
Шаги:
IFolderView2
рабочего стола (поддерживается с Windows Vista). 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;
}