anx.framework/Visual Studio/MPF11/Dev11/Src/CSharp/WebPiComponentPickerControl.cs
Konstantin Koch 8287c54432 Included the Visual Studio extension and made the necessary changes to make it run.
Replaced the old VS templates with ones that offer more flexiblity.
Started replacing the Content Project for the samples with our custom project type.
Inlcuded a basic not yet working AssimpImporter.
2015-04-08 14:50:03 +02:00

306 lines
12 KiB
C#

/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
namespace Microsoft.VisualStudio.Project {
[Guid("B7773A32-2EE5-4844-9630-F14768A5D03C")]
partial class WebPiComponentPickerControl : UserControl {
private readonly List<PackageInfo> _packages = new List<PackageInfo>();
private const string _defaultFeeds = "https://www.microsoft.com/web/webpi/4.0/toolsproductlist.xml";
private ListViewSorter _sorter = new ListViewSorter();
public WebPiComponentPickerControl() {
InitializeComponent();
AutoSize = true;
AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
_productsList.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(ProductsListItemSelectionChanged);
_productsList.ListViewItemSorter = _sorter;
_productsList.DoubleClick += new EventHandler(ProductsListDoubleClick);
_productsList.ColumnClick += new ColumnClickEventHandler(ProductsListColumnClick);
}
private void ProductsListColumnClick(object sender, ColumnClickEventArgs e) {
if (e.Column == _sorter.Column) {
if (_sorter.Order == SortOrder.Ascending) {
_sorter.Order = SortOrder.Descending;
} else {
_sorter.Order = SortOrder.Ascending;
}
} else {
_sorter.Column = e.Column;
_sorter.Order = SortOrder.Ascending;
}
_productsList.Sort();
}
private void ProductsListDoubleClick(object sender, EventArgs e) {
NativeMethods.SendMessage(
NativeMethods.GetParent(NativeMethods.GetParent(NativeMethods.GetParent(Handle))),
(uint)VSConstants.CPDN_SELDBLCLICK,
IntPtr.Zero,
Handle
);
}
private void ProductsListItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) {
NativeMethods.SendMessage(
NativeMethods.GetParent(NativeMethods.GetParent(NativeMethods.GetParent(Handle))),
(uint)VSConstants.CPDN_SELCHANGED,
IntPtr.Zero,
Handle
);
}
private void RequestFeeds(object dummy) {
try {
GetFeeds((string)dummy);
} catch (WebException ex) {
MessageBox.Show(String.Format("Unable to get feeds from {0}\r\n\r\n{1}", (string)dummy, ex.Message));
}
}
private void GetFeeds(string feed) {
var doc = new XPathDocument(feed);
XmlNamespaceManager mngr = new XmlNamespaceManager(new NameTable());
mngr.AddNamespace("x", "http://www.w3.org/2005/Atom");
var nav = doc.CreateNavigator();
var nodes = nav.Select("/x:feed/x:entry", mngr);
foreach (XPathNavigator node in nodes) {
var title = node.Select("x:title", mngr);
var updated = node.Select("x:updated", mngr);
var productId = node.Select("x:productId", mngr);
string titleVal = null;
foreach (XPathNavigator titleNode in title) {
titleVal = titleNode.Value;
break;
}
string updatedVal = null;
foreach (XPathNavigator updatedNode in updated) {
updatedVal = updatedNode.Value;
}
string productIdVal = null;
foreach (XPathNavigator productIdNode in productId) {
productIdVal = productIdNode.Value;
}
if (titleVal != null && updatedVal != null && productIdVal != null) {
var newPackage = new PackageInfo(
titleVal,
updatedVal,
productIdVal,
feed
);
_packages.Add(newPackage);
BeginInvoke(new Action<object>(AddPackage), newPackage);
}
}
}
private void AddPackage(object package) {
var pkgInfo = (PackageInfo)package;
var item = new ListViewItem(
new[] {
pkgInfo.Title,
pkgInfo.Updated,
pkgInfo.ProductId,
pkgInfo.Feed
}
);
item.Tag = pkgInfo;
_productsList.Items.Add(item);
}
class PackageInfo {
public readonly string Title;
public readonly string Updated;
public readonly string ProductId;
public readonly string Feed;
public PackageInfo(string title, string updated, string productId, string feed) {
Title = title;
Updated = updated;
ProductId = productId;
Feed = feed;
}
}
class ListViewSorter : IComparer {
public SortOrder Order;
public int Column;
#region IComparer Members
public int Compare(object x, object y) {
ListViewItem itemX = (ListViewItem)x;
ListViewItem itemY = (ListViewItem)y;
int? res = null;
if (Column == 1) {
DateTime dtX, dtY;
if (DateTime.TryParse(itemX.SubItems[1].Text, out dtX) &&
DateTime.TryParse(itemY.SubItems[1].Text, out dtY)) {
res = dtX.CompareTo(dtY);
}
}
if (res == null) {
res = String.Compare(
itemX.SubItems[0].Text,
itemY.SubItems[0].Text,
true
);
}
if (Order == SortOrder.Descending) {
return -res.Value;
}
return res.Value;
}
#endregion
}
private void AddNewFeedClick(object sender, EventArgs e) {
ThreadPool.QueueUserWorkItem(RequestFeeds, _newFeedUrl.Text);
}
protected override void DefWndProc(ref Message m) {
switch (m.Msg) {
case NativeMethods.WM_INITDIALOG:
SetWindowStyleOnStaticHostControl();
goto default;
case VSConstants.CPPM_INITIALIZELIST:
ThreadPool.QueueUserWorkItem(RequestFeeds, _defaultFeeds);
break;
case VSConstants.CPPM_SETMULTISELECT:
_productsList.MultiSelect = (m.WParam != IntPtr.Zero);
break;
case VSConstants.CPPM_CLEARSELECTION:
_productsList.SelectedItems.Clear();
break;
case VSConstants.CPPM_QUERYCANSELECT:
Marshal.WriteInt32(
m.LParam,
(_productsList.SelectedItems.Count > 0) ? 1 : 0
);
break;
case VSConstants.CPPM_GETSELECTION:
var items = new PackageInfo[this._productsList.SelectedItems.Count];
for (int i = 0; i < items.Length; i++) {
items[i] = (PackageInfo)_productsList.SelectedItems[0].Tag;
}
int count = items != null ? items.Length : 0;
Marshal.WriteByte(m.WParam, Convert.ToByte(count));
if (count > 0) {
IntPtr ppItems = Marshal.AllocCoTaskMem(
count * Marshal.SizeOf(typeof(IntPtr)));
for (int i = 0; i < count; i++) {
IntPtr pItem = Marshal.AllocCoTaskMem(
Marshal.SizeOf(typeof(VSCOMPONENTSELECTORDATA)));
Marshal.WriteIntPtr(
ppItems + i * Marshal.SizeOf(typeof(IntPtr)),
pItem);
VSCOMPONENTSELECTORDATA data = new VSCOMPONENTSELECTORDATA() {
dwSize = (uint)Marshal.SizeOf(typeof(VSCOMPONENTSELECTORDATA)),
bstrFile = items[i].Feed,
bstrTitle = items[i].ProductId,
bstrProjRef = items[i].Title,
type = VSCOMPONENTTYPE.VSCOMPONENTTYPE_Custom
};
Marshal.StructureToPtr(data, pItem, false);
}
Marshal.WriteIntPtr(m.LParam, ppItems);
}
break;
case NativeMethods.WM_SIZE:
IntPtr parentHwnd = NativeMethods.GetParent(Handle);
if (parentHwnd != IntPtr.Zero) {
IntPtr grandParentHwnd = NativeMethods.GetParent(parentHwnd);
User32RECT parentClientRect, grandParentClientRect;
if (grandParentHwnd != IntPtr.Zero &&
NativeMethods.GetClientRect(parentHwnd, out parentClientRect) &&
NativeMethods.GetClientRect(grandParentHwnd, out grandParentClientRect)) {
int width = grandParentClientRect.Width;
int height = grandParentClientRect.Height;
if ((parentClientRect.Width != width) || (parentClientRect.Height != height)) {
NativeMethods.MoveWindow(parentHwnd, 0, 0, width, height, true);
this.Width = width;
this.Height = height;
}
this.Refresh();
}
}
break;
default:
base.DefWndProc(ref m);
break;
}
}
private void NewFeedUrlTextChanged(object sender, EventArgs e) {
try {
new Uri(_newFeedUrl.Text);
_addNewFeed.Enabled = true;
} catch (UriFormatException) {
_addNewFeed.Enabled = false;
}
}
/// <summary>
/// VS hosts us in a static control ("This is a static!") but that control doesn't
/// have the WS_EX_CONTROLPARENT style like it should (and like our UserControl properly
/// gets because it's a ContainerControl). This causes an infinite loop when we start
/// trying to loop through the controls if the user navigates away from the control.
///
/// http://support.microsoft.com/kb/149501
///
/// So we go in and muck about with the This is a static! control's window style so that
/// we don't hang VS if the user alt-tabs away.
/// </summary>
private void SetWindowStyleOnStaticHostControl() {
var target = (NativeMethods.GetParent(Handle));
NativeMethods.SetWindowLong(
target,
NativeMethods.GWL_EXSTYLE,
NativeMethods.WS_EX_CONTROLPARENT | NativeMethods.GetWindowLong(target, NativeMethods.GWL_EXSTYLE)
);
}
}
}