mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-23 20:36:33 +01:00
178 lines
7.4 KiB
C#
178 lines
7.4 KiB
C#
/* Copyright (c) Cloud Software Group, Inc.
|
|
*
|
|
* Redistribution and use in source and binary forms,
|
|
* with or without modification, are permitted provided
|
|
* that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer in the documentation and/or other
|
|
* materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Windows.Forms;
|
|
using System.Runtime.InteropServices;
|
|
using XenCenterLib;
|
|
|
|
|
|
namespace XenAdmin.Dialogs
|
|
{
|
|
/*
|
|
* This code is based on the page:
|
|
* http://www.codeproject.com/csharp/GetSaveFileName.asp?df=100&forumid=96342&exp=0&select=962159
|
|
*
|
|
* It uses win32 to extend a save file dialog.
|
|
*/
|
|
public class ExportVMDialog
|
|
{
|
|
public string DefaultExt = "";
|
|
public string Filter = "";
|
|
public string FileName = Messages.BACKUP_NAME;
|
|
public string Title = "";
|
|
public bool Verify = true;
|
|
|
|
private IntPtr ComboHandle = IntPtr.Zero;
|
|
private IWin32Window Owner;
|
|
|
|
private IntPtr HookProc(IntPtr hdlg, int msg, IntPtr wParam, IntPtr lParam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case Win32.WM_INITDIALOG:
|
|
// Center the dialog on its owner
|
|
Win32.RECT sr = new Win32.RECT();
|
|
Win32.RECT cr = new Win32.RECT();
|
|
IntPtr parent = Win32.GetParent(hdlg);
|
|
Win32.GetWindowRect(parent, ref cr);
|
|
|
|
Win32.GetWindowRect(Owner.Handle, ref sr);
|
|
|
|
int x = (sr.Right + sr.Left - (cr.Right - cr.Left)) / 2;
|
|
int y = (sr.Bottom + sr.Top - (cr.Bottom - cr.Top)) / 2;
|
|
|
|
Win32.SetWindowPos(parent, IntPtr.Zero, x, y, cr.Right - cr.Left, cr.Bottom - cr.Top + 32, Win32.SWP_NOZORDER);
|
|
|
|
IntPtr fileTypeWindow = Win32.GetDlgItem(parent, 0x441);
|
|
IntPtr fontHandle = Win32.SendMessage(fileTypeWindow, Win32.WM_GETFONT, IntPtr.Zero, IntPtr.Zero);
|
|
|
|
//we now need to find the combo-box to position the new tick box under
|
|
|
|
IntPtr fileComboWindow = Win32.GetDlgItem(parent, 0x470);
|
|
Win32.RECT aboveRect = new Win32.RECT();
|
|
Win32.GetWindowRect(fileComboWindow, ref aboveRect);
|
|
|
|
Win32.POINT point = new Win32.POINT();
|
|
point.X = aboveRect.Left;
|
|
point.Y = aboveRect.Bottom;
|
|
Win32.ScreenToClient(parent, ref point);
|
|
|
|
Win32.POINT rightPoint = new Win32.POINT();
|
|
rightPoint.X = aboveRect.Right;
|
|
rightPoint.Y = aboveRect.Top;
|
|
|
|
Win32.ScreenToClient(parent, ref rightPoint);
|
|
|
|
//we create the new combobox
|
|
|
|
IntPtr comboHandle = Win32.CreateWindowEx(0, "BUTTON", "", Win32.WS_VISIBLE | Win32.WS_CHILD | Win32.WS_TABSTOP | Win32.BS_AUTOCHECKBOX, point.X, point.Y + 8, rightPoint.X - point.X, 16, parent, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
|
fontHandle = Win32.SendMessage(fileTypeWindow, Win32.WM_GETFONT, IntPtr.Zero, IntPtr.Zero);
|
|
|
|
Win32.SendMessage(comboHandle, Win32.WM_SETFONT, fontHandle, IntPtr.Zero);
|
|
Win32.SendMessage(comboHandle, Win32.WM_SETTEXT, IntPtr.Zero, Messages.EXPORT_VM_VERIFY_POST_INSTALL);
|
|
Win32.SendMessage(comboHandle, Win32.BM_SETCHECK, (IntPtr)(Verify ? Win32.BST_CHECKED : Win32.BST_UNCHECKED), IntPtr.Zero);
|
|
|
|
//remember the handles of the controls we have created so we can destroy them after
|
|
ComboHandle = comboHandle;
|
|
break;
|
|
|
|
case Win32.WM_DESTROY:
|
|
//destroy the handles we have created
|
|
if (ComboHandle != IntPtr.Zero)
|
|
{
|
|
Win32.DestroyWindow(ComboHandle);
|
|
}
|
|
break;
|
|
|
|
case Win32.WM_NOTIFY:
|
|
|
|
//we need to intercept the CDN_FILEOK message
|
|
//which is sent when the user selects a filename
|
|
|
|
Win32.NMHDR nmhdr = (Win32.NMHDR)Marshal.PtrToStructure(lParam, typeof(Win32.NMHDR));
|
|
|
|
if (nmhdr.code == Win32.CDN_FILEOK)
|
|
{
|
|
Verify = Win32.SendMessage(ComboHandle, Win32.BM_GETCHECK, IntPtr.Zero, IntPtr.Zero) == (IntPtr)Win32.BST_CHECKED;
|
|
}
|
|
break;
|
|
}
|
|
return IntPtr.Zero;
|
|
}
|
|
|
|
public DialogResult ShowDialog(IWin32Window owner)
|
|
{
|
|
//set up the struct and populate it
|
|
|
|
Win32.OPENFILENAME ofn = new Win32.OPENFILENAME();
|
|
|
|
ofn.lStructSize = Marshal.SizeOf(ofn);
|
|
ofn.lpstrFilter = Filter.Replace('|', '\0') + '\0';
|
|
|
|
ofn.lpstrFile = FileName+ new string(' ', 512);
|
|
ofn.lpTemplateName = FileName;
|
|
ofn.nMaxFile = ofn.lpstrFile.Length;
|
|
ofn.lpstrFileTitle = System.IO.Path.GetFileName(FileName) + new string(' ', 512);
|
|
ofn.nMaxFileTitle = ofn.lpstrFileTitle.Length;
|
|
ofn.lpstrTitle = Title;
|
|
ofn.lpstrDefExt = DefaultExt;
|
|
|
|
//position the dialog above the active window
|
|
Owner = owner;
|
|
ofn.hwndOwner = owner.Handle;
|
|
|
|
//set up some sensible flags
|
|
ofn.Flags = Win32.OFN_EXPLORER | Win32.OFN_PATHMUSTEXIST | Win32.OFN_NOTESTFILECREATE | Win32.OFN_ENABLEHOOK | Win32.OFN_HIDEREADONLY | Win32.OFN_OVERWRITEPROMPT | Win32.OFN_SHOWHELP;
|
|
|
|
//this is where the hook is set. Note that we can use a C# delegate in place of a C function pointer
|
|
ofn.lpfnHook = new Win32.OFNHookProcDelegate(HookProc);
|
|
|
|
//show the dialog
|
|
|
|
if (!Win32.GetSaveFileName(ref ofn))
|
|
{
|
|
int ret = Win32.CommDlgExtendedError();
|
|
|
|
if (ret != 0)
|
|
{
|
|
throw new ApplicationException(string.Format(Messages.EXPORTVM_COULD_NOT_SHOW, ret.ToString()));
|
|
}
|
|
|
|
return DialogResult.Cancel;
|
|
}
|
|
|
|
FileName = ofn.lpstrFile;
|
|
|
|
return DialogResult.OK;
|
|
}
|
|
}
|
|
}
|