Настройка разрешений
117Silverlight 5 --- Настройка разрешений
Приложения с повышенной доверительностью — это специальный тип приложений, выполняющихся вне браузера. От обычных они отличаются тем, что имеют впечатляющий набор дополнительных привилегий. Эти привилегии не совпадают с разрешениями традиционных настольных приложений, но они делают возможным ряд потенциально опасных действий, например активизацию сторонних программ и непосредственный доступ к файловой системе.
По этой причине приложения с повышенной доверительностью рекомендуется использовать только в жестко контролируемой среде, такой как корпоративная сеть, в которой пользователи хорошо знают свои приложения и доверяют разработчикам.
Во многих случаях пользователи очень неохотно предоставляют дополнительные привилегии, необходимые приложениям с повышенной доверительностью. Иногда они вообще отказываются устанавливать их. К тому же системный администратор может сконфигурировать компьютеры таким образом, чтобы предотвратить установку или выполнение приложений вне браузера, требующих повышенной доверительности.
Прежде чем приступить к разработке приложения Silverlight с повышенной доверительностью, проанализируйте, не подойдет ли для решения данной задачи полнофункциональное настольное приложение WPF. Платформа WPF полностью поддерживает инфраструктуру .NET Framework. Как и в Silverlight, приложения WPF можно устанавливать из Интернета, но, в отличие от Silverlight, приложения WPF работают только в приложениях Windows.
Установка приложения с повышенной доверительностью
Чтобы указать, что приложение должно требовать повышенной доверительности, откройте окно Out-of-Browser Settings и установите флажок Require elevated trust (Требует повышенной доверительности):
Для запуска процесса установки откройте контекстное меню Silverlight или вызовите метод Application.Install(). На экране появится окно с сообщением системы безопасности. Щелкните на кнопке Установить.
Можете подписать приложение цифровым сертификатом X.509. Тогда в окне системы безопасности предупреждение будет менее грозным, восклицательный знак будет заменен вопросительным и будет отображено имя издателя.
Возможности приложений с повышенной доверительностью
Что может приложение с повышенной доверительностью делать такое, что не по силам обычному приложению Silverlight? Давайте рассмотрим подробнее:
Доступ к файловой системе компьютера. Приложение с повышенной доверительностью может работать с теми же частями файловой системы, что и текущий пользователь. Эта возможность особенно полезна, когда нужно читать и записывать файлы в папке документов текущего пользователя. Можно также добавить файлы на рабочий стол или создать собственную структуру папок.
Неограниченная поддержка полноэкранного режима. При переключении приложения с повышенной доверительностью в полноэкранный режим извещение "Нажмите Esc для выхода из полноэкранного режима" не появляется. Нажатие клавиши <Esc> не приводит к выходу из полноэкранного режима. Но важнее всего то, что приложение в полноэкранном режиме продолжает принимать нажатия клавиш.
Нет ограничений кроссдоменного доступа. Приложению с повышенной доверительностью разрешено загружать содержимое с любого веб-сайта, вызывать веб-службы на любом сайте, открывать сокетные соединения с любым сервером, т.е. выполнять все операции, доступные для настольных приложений.
Меньше операций, на которые необходимо разрешение пользователя. Существует много ситуаций, в которых обычное приложение Silverlight вынуждено спрашивать разрешение у пользователя, например, для доступа к буферу обмена, сохранения файла в изолированном хранилище, конфигурирования полноэкранного режима при потере фокуса и т.п.
В приложениях с повышенной доверительностью эти ограничения отменены (за исключением доступа к устройствам записи звука и видео). Кроме того, в обычном приложении есть много операций, которые могут быть выполнены только в качестве реакции на действие пользователя (переключение в полноэкранный режим, использование буфера обмена, манипулирование главным окном и т.п.). В приложении с повышенной доверительностью эти операции можно выполнять в любой момент без участия пользователя.
Настройка окна. Если вам не нравятся стандартная рамка и элементы управления окном, предоставляемые операционной системой, удалите их из приложения с повышенной доверительностью и нарисуйте собственные с помощью стандартных элементов Silverlight.
Дочерние окна. Приложение с повышенной доверительностью может в любой момент создавать дочерние окна.
Межзадачное взаимодействие с компонентами СОМ. В приложении с повышенной доверительностью можно использовать библиотеки функций, предоставляемые операционной системой Windows посредством СОМ. Например, можно взаимодействовать с приложениями Outlook и Office, а также со встроенными компонентами Windows, такими как Script Host и WMI.
Вызовы P/Invoke. Приложение с повышенной доверительностью может выполнять коды системных библиотек DLL на компьютерах Windows и обращаться к функциям Windows API посредством платформенных вызовов Р/Invoke.
Прежде чем воспользоваться любым из этих средств, не забудьте присвоить свойству Application.HasElevatedPermissions значение true. В противном случае приложение будет работать в обычном режиме низкой доверительности.
Настройка окна
Обычное приложение, выполняющееся вне браузера, отображает стандартный фрейм окна, предоставляемый операционной системой. Он оснащен хорошо знакомыми всем кнопками свертывания, развертывания и закрытия окна. Цвет, стиль, затенение и прозрачность рамки контролируются операционной системой. Такая модель вполне подходит для большинства случаев, однако, если хотите чтобы ваше приложение выглядело стильно и профессионально, можете настроить внешний вид фрейма окна и оснастить его кнопками, созданными вручную.
Настройка фрейма окна выполняется в два этапа. Первый — полное удаление стандартного фрейма. Для этого в проводнике решений дважды щелкните на узле Properties (Свойства). Откройте вкладку Silverlight и щелкните на кнопке Out-of-Browser Settings (Параметры приложений вне браузера). Выберите один из пунктов списка Window Style (Стиль окна).
Если выбрать значение Default, отобразится стандартный фрейм окна. При выборе второго значения, No Border, будет удален стандартный фрейм окна и оставлен стандартный плавающий прямоугольник с содержимым пользовательского элемента управления. При значении Borderless Round Corners будет удален стандартный фрейм окна и скруглены углы окна приложения. Разница между вторым и третьим вариантами чисто "косметическая", в любом из этих случаев стандартный фрейм окна удаляется. На рисунке ниже показан пример:
Второй этап настройки фрейма окна — прорисовка нового фрейма и добавление базовых элементов управления для закрытия, изменения размеров, изменения состояния и перетаскивания окна. Для обеспечения кроссплатформенности, Silverlight не позволяет программисту модифицировать стандартный фрейм окна операционной системы. Он должен самостоятельно нарисовать фрейм окна с помощью подходящих рисунков или элементов управления Silverlight.
Например, можно поместить основное содержимое в одноячеечный контейнер Grid и наложить на него другой элемент Silverlight (Rectangle или Image). Можно также заключить в оболочку Border корневой пользовательский элемент управления следующим образом:
<Border x:Name="windowFrame" BorderBrush="LimeGreen" BorderThickness="5" CornerRadius="2" Margin="0,0,1,1">
<Grid x:Name="LayoutRoot" Background="#555">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontSize="16"
Text="Окно без рамки"/>
</Grid>
</Border>
В данном примере в параметрах проекта установлено значение Borderless Round Corners. Внешнее поле (Margin) шириной 1 пиксель справа и снизу обеспечивает вывод фрейма в правильной позиции. Значение CornerRadius, равное 2, выравнивает угол с областью окна:
Платформа Silverlight не поддерживает задание произвольной фигуры в качестве рамки окна. Поэтому в качестве фрейма, определяющего главное окно, можно применить только прямоугольник или скругленный прямоугольник. Важно то, что Silverlight предоставляет вам этот прямоугольник, и вам остается лишь заполнить его содержимым. Кроме того, в Silverlight нельзя создать прозрачную или частично прозрачную область, которая позволила бы видеть содержимое экрана сквозь окно приложения.
Конечно, добавление рамки Border улучшает внешний вид окна, но остается одна важная проблема. Без фрейма, предоставленного операционной системой, пользователь не может изменить размеры окна, переместить его, свернуть, развернуть или закрыть. Если нужно, чтобы пользователь имел возможность выполнять эти операции, нужно запрограммировать их в коде настройки главного окна. К счастью, средства, встроенные в класс Window, существенно облегчают эту задачу.
Первый этап — создание строки заголовка окна. Строка заголовка играет три роли: содержит текст заголовка, служит местом, уцепившись за которое пользователь может перетаскивать окно, и, наконец, содержит кнопки свертывания, развертывания и закрытия окна. В приведенном ниже примере разметка создает базовую строку заголовка. Фигуры кнопок свертывания, развертывания и закрытия прорисовываются с помощью элементов Path и Rectangle.
Второй этап - добавление способа изменения размеров окна путем перетаскивания его краев. Легче всего реализовать его, заключив все окно в оболочку контейнера Grid, в котором используется невидимый элемент Rectangle. Вам понадобятся восемь элементов Rectangle: по одному на каждую сторону и на каждый угол:
Ниже демонстрируется разметка и код окна с добавлением этих средств:
<UserControl x:Class="Silverlight.CustomWindow"
...>
<Border Background="#AAA" CornerRadius="2" Margin="0,0,1,1"
x:Name="windowBorder">
<Grid x:Name="resizeContainer">
<!-- Отступы по 5 пикселей для добавления прозрачных прямоугольников -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="5"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="5"></RowDefinition>
</Grid.RowDefinitions>
<!-- Прямоугольники (имитирующие контуры окна)
для изменения размеров окна -->
<Rectangle x:Name="rect_TopLeftCorner" Grid.Row="0" Grid.Column="0"
Cursor="SizeNWSE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<Rectangle x:Name="rect_TopEdge" Grid.Row="0" Grid.Column="1"
Cursor="SizeNS" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<Rectangle x:Name="rect_TopRightCorner" Grid.Row="0" Grid.Column="2"
Cursor="SizeNESW" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<Rectangle x:Name="rect_LeftEdge" Grid.Row="1" Grid.Column="0"
Cursor="SizeWE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<Rectangle x:Name="rect_RightEdge" Grid.Row="1" Grid.Column="2"
Cursor="SizeWE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<Rectangle x:Name="rect_BottomLeftCorner" Grid.Row="2" Grid.Column="0"
Cursor="SizeNESW" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<Rectangle x:Name="rect_BottomEdge" Grid.Row="2" Grid.Column="1"
Cursor="SizeNS" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<Rectangle x:Name="rect_BottomRightCorner" Grid.Row="2" Grid.Column="2"
Cursor="SizeNWSE" Fill="Transparent" MouseLeftButtonDown="rect_Resize" />
<!-- Содержимое окна -->
<Grid Grid.Row="1" Grid.Column="1" Background="#555">
<Grid.RowDefinitions>
<RowDefinition Height="28"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<!-- Заголовок окна с кнопками-->
<Border Background="#222" MouseLeftButtonDown="titleBar_MouseLeftButtonDown" x:Name="titleBar">
<Grid>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="20"/>
<Setter Property="Margin" Value="0,0,3,0"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Margin="5" Foreground="White">Текст заголовка</TextBlock>
<Button Grid.Column="1" x:Name="cmdMinimize" Click="cmdMinimize_Click">
<Path Stroke="White" StrokeThickness="2" Data="M 1,14 L 13,14"/>
</Button>
<Button Grid.Column="2" x:Name="cmdMaximize" Click="cmdMaximize_Click">
<Rectangle Stroke="White" StrokeThickness="2" Height="12" Width="12"/>
</Button>
<Button Grid.Column="3" x:Name="cmdClose" Click="cmdClose_Click">
<Path Stroke="White" StrokeThickness="2" Data="M 2,2 L 14,14 M 14,2 L 2,14"/>
</Button>
</Grid>
</Border>
<!-- Контент -->
<Grid x:Name="LayoutRoot" Margin="5" Grid.Row="1">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap"
FontSize="16" FontWeight="Bold" Foreground="White">Содержимое видоизмененного окна.</TextBlock>
</Grid>
</Grid>
</Grid>
</Border>
</UserControl>
public partial class CustomWindow : UserControl
{
public CustomWindow()
{
InitializeComponent();
}
// Ссылка на окно
private Window CurrentWindow
{
get { return Application.Current.MainWindow; }
}
// Перетаскивание окна
private void titleBar_MouseLeftButtonDown(object sender,
System.Windows.Input.MouseButtonEventArgs e)
{
CurrentWindow.DragMove();
}
// Изменение размеров окна с помощью кнопок
private void cmdMinimize_Click(object sender, System.Windows.RoutedEventArgs e)
{
CurrentWindow.WindowState = WindowState.Minimized;
}
private void cmdMaximize_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (CurrentWindow.WindowState == WindowState.Normal)
{
CurrentWindow.WindowState = WindowState.Maximized;
}
else
{
CurrentWindow.WindowState = WindowState.Normal;
}
}
// Закрытие окна
private void cmdClose_Click(object sender, System.Windows.RoutedEventArgs e)
{
CurrentWindow.Close();
}
// Изменение размеров окна с помощью курсора мыши
private void rect_Resize(System.Object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (sender == rect_TopLeftCorner)
{
CurrentWindow.DragResize(WindowResizeEdge.TopLeft);
}
else if (sender == rect_TopEdge)
{
CurrentWindow.DragResize(WindowResizeEdge.Top);
}
else if (sender == rect_TopRightCorner)
{
CurrentWindow.DragResize(WindowResizeEdge.TopRight);
}
else if (sender == rect_LeftEdge)
{
CurrentWindow.DragResize(WindowResizeEdge.Left);
}
else if (sender == rect_RightEdge)
{
CurrentWindow.DragResize(WindowResizeEdge.Right);
}
else if (sender == rect_BottomLeftCorner)
{
CurrentWindow.DragResize(WindowResizeEdge.BottomLeft);
}
else if (sender == rect_BottomEdge)
{
CurrentWindow.DragResize(WindowResizeEdge.Bottom);
}
else if (sender == rect_BottomRightCorner)
{
CurrentWindow.DragResize(WindowResizeEdge.BottomRight);
}
}
}
Выше описана вся инфраструктура, необходимая для создания пользовательского окна. Установив все компоненты (строку заголовка, кнопки окна, средства изменения размеров и перетаскивания), можно начать настройку внешнего вида окна с помощью изображений и элементов Silverlight для получения требуемого эффекта.