Feeds:
Записи
Комментарии

Archive for the ‘GUI’ Category

Иногда хочется  использовать иконки из dll или exe. Это сделать довольно просто,для этого потребуется функция ExtractIconEx. Объявление этой функции можно посмотреть на сайте pInvoke .

$code = @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace System
{
	public class IconExtractor
	{

	    public static Icon Extract(string file, int number, bool largeIcon)
	    {
	        IntPtr large;
	        IntPtr small;
	        ExtractIconEx(file, number, out large, out small, 1);
	        try
	        {
	            return Icon.FromHandle(largeIcon ? large : small);
	        }
	        catch
	        {
	            return null;
	        }

	    }
	    [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
	    private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);

	}
}
"@

Add-Type -TypeDefinition $code -ReferencedAssemblies System.Drawing

Самый простой способ получения индекса иконки из файла — это в свойствах ярлыка нажать на «Change Icon».

Теперь приведу пример использования для нашей формы.

$form = New-Object System.Windows.Forms.Form
$form.Icon = [System.IconExtractor]::Extract("notepad.exe", 0, $true)
$form.ShowDialog()

$form = New-Object System.Windows.Forms.Form
$form.Icon = [System.IconExtractor]::Extract("shell32.dll", 15, $true)
$form.ShowDialog()

Если индекс указан неверно,то будет использована стандартная иконка.

Реклама

Read Full Post »

Для отображение elevated иконки на нашей форме ,придется задействовать WinAPi функции,так как каких либо методов для достижения результата с использование .NET ,у нас нет.Для C++ существует несколько методов  Button_SetElevationRequiredStateBCM_SETSHIELD.  Button_SetElevationRequiredState — является макросом ,поэтому можно посмотреть ,что он делает в заголовочном фале Commctrl.h.

	Header  Commctrl.h
	#define BCM_FIRST               0x1600      // Button control messages
	#if _WIN32_WINNT >= 0x0600
	// Macro to use on a button or command link to display an elevated icon
	#define BCM_SETSHIELD            (BCM_FIRST + 0x000C)
	#define Button_SetElevationRequiredState(hwnd, fRequired) \
	    (LRESULT)SNDMSG((hwnd), BCM_SETSHIELD, 0, (LPARAM)fRequired)
	#endif /* _WIN32_WINNT >= 0x0600 */

Этот метод вызывает функцию SendMessage,которой мы и воспользуемся.Как объявлять функцию
SendMessage для .Net,можно посмотреть — http://www.pinvoke.net/default.aspx/user32.sendmessage
Приведу простой пример формы с одной кнопкой,для запуска процесса PowerShell c повышенными привилегиями.

#обычная кнопка
$BCM_FIRST = 0x1600
#кнопка со щитом
$BCM_SETSHIELD  = $BCM_FIRST + 0x000C

#входит ли пользователь в группу администраторы
function isAdmin {
	$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
  	$principal = new-object System.Security.Principal.WindowsPrincipal($identity)
  	$principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

#поднимаем уровень привилегий
function RunElevated
{
    try {
    (Start-Process powershell -Verb RunAs -ErrorAction Stop -PassThru).WaitForExit()
    }
    catch {[System.Windows.Forms.MessageBox]::Show("Failed to elevate process.")}
}

#отображаем кнопку со щитом
function DisplayIcon
{
	$signature = @"
	 [DllImport("User32.DLL")]
    public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
"@
	$type = Add-Type -MemberDefinition $signature `
	-Name Win32 -Namespace SendMessage `
	-PassThru
	$type::SendMessage($($button1.handle),$BCM_SETSHIELD,0,1)
}

[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null

$form1 = New-Object System.Windows.Forms.Form
$button1 = New-Object System.Windows.Forms.Button

$form1.Text = "Shield Form"
$form1.ClientSize = New-Object System.Drawing.Size(202,81)
$form1.FormBorderStyle = "FixedDialog"
$form1.MaximizeBox = $false
$form1.MinimizeBox = $false

$button1.TabIndex = 0
$button1.Size =  New-Object System.Drawing.Size(75,23)
$button1.Text = "Elevate"
$button1.UseVisualStyleBackColor = $true
$button1.Location = New-Object System.Drawing.Point(63,21)
$button1.add_Click({RunElevated})

$form1.Controls.Add($button1)
$form1.Add_Load({
	#проверяем входит ли пользователь в группу администраторы,если нет,то отображаем кнопку со щитом
	if (!$(isAdmin)) {
	$button1.FlatStyle = [System.Windows.Forms.FlatStyle]::System
	DisplayIcon
	}
})
[System.Windows.Forms.Application]::EnableVisualStyles()
[System.Windows.Forms.Application]::Run($form1)

Uploaded with ImageShack.us

Read Full Post »

Определить простой операционной системы,на основе последнего события ввода пользователя.Для этого используем функцию GetLastInputInfo.Для создания форм,использовался Primal Forms.

$code = @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Idle
{
   public static class Timer
   {
      [DllImport("user32.dll", SetLastError=false)]
      private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

      [StructLayout(LayoutKind.Sequential)]
      private struct LASTINPUTINFO
      {
         public uint cbSize;
         public int dwTime;
      }

      public static DateTime LastInput
      {
         get
         {
            LASTINPUTINFO lii = new LASTINPUTINFO();
            lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
            GetLastInputInfo(ref lii);
            DateTime bootTime = DateTime.Now.AddMilliseconds(-Environment.TickCount);
            DateTime lastInput = bootTime.AddMilliseconds(lii.dwTime);
            return lastInput;
         }
      }
      public static TimeSpan IdleTime
      {
         get
         {
         return DateTime.Now.Subtract(LastInput);
         }
      }
   }
}
'@

Add-Type $code
Function UpdateLabel
{
   $label3.Text = [Idle.Timer]::IdleTime
   $label4.Text = [Idle.Timer]::LastInput.ToString()
}

[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null

$form1 = New-Object System.Windows.Forms.Form
$label4 = New-Object System.Windows.Forms.Label
$label3 = New-Object System.Windows.Forms.Label
$label2 = New-Object System.Windows.Forms.Label
$label1 = New-Object System.Windows.Forms.Label
$timer =  New-Object System.Windows.Forms.Timer

$timer.Interval=1000
$timer.Start()
$timer.add_Tick({Updatelabel})

$form1.Text = "Idle Timer"
$form1.FormBorderStyle  = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$form1.ClientSize = New-Object System.Drawing.Size(249,79)

$label4.Size = New-Object System.Drawing.Size(153,23)
$label4.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0)
$label4.Location = New-Object System.Drawing.Point(77,44)
$label4.Text = [Idle.Timer]::LastInput.ToString()

$form1.Controls.Add($label4)

$label3.Size = New-Object System.Drawing.Size(153,23)
$label3.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0)
$label3.Location = New-Object System.Drawing.Point(77,17)
$label3.DataBindings.DefaultDataSourceUpdateMode = 0
$label3.Text = [Idle.Timer]::IdleTime
$form1.Controls.Add($label3)

$label2.Size = New-Object System.Drawing.Size(81,23)
$label2.Text = "Last Input:"
$label2.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,0,3,0)
$label2.Location = New-Object System.Drawing.Point(13,44)

$form1.Controls.Add($label2)

$label1.Size =  New-Object System.Drawing.Size(81,19)
$label1.Text = "Idle Time:"
$label1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,0,3,0)
$label1.Location = New-Object System.Drawing.Point(13,17)
$label1.Name = "label1"
$form1.Controls.Add($label1)

$form1.ShowDialog()

Read Full Post »