Layered form don't show - winforms

I got a problem with my layered form. I made it to show an PNG image with blur in form background. Everything works great in Windows 7 but when i run it at Windows XP my form don't show.
There is my Code:
public class LayeredForm : Form
{
public LayeredForm()
{
FormBorderStyle = FormBorderStyle.None;
ShowInTaskbar = false;
StartPosition = FormStartPosition.Manual;
Width = 0;
Height = 0;
DoubleBuffered = true;
}
public void SetBitmap(Bitmap bitmap)
{
IntPtr screenDc = Win32Helper.GetDC(IntPtr.Zero);
IntPtr compatibleMemoryDc = Win32Helper.CreateCompatibleDC(screenDc);
IntPtr hgdiBitmap = IntPtr.Zero;
IntPtr hgdiOldBitmap = IntPtr.Zero;
try
{
hgdiBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
hgdiOldBitmap = Win32Helper.SelectObject(compatibleMemoryDc, hgdiBitmap);
Win32Helper.SizeStruct size = new Win32Helper.SizeStruct()
{
X = bitmap.Width,
Y = bitmap.Height
};
Win32Helper.PointStruct sourcePoint = new Win32Helper.PointStruct();
Win32Helper.PointStruct topPoint = new Win32Helper.PointStruct()
{
X = Left,
Y = Top
};
Win32Helper.BlendFunctionStruct blend = new Win32Helper.BlendFunctionStruct()
{
BlendOp = 255 /* opacity */,
BlendFlags = 0x00 /* AC_SRC_OVER */,
AlphaFormat = 0x01 /* AC_SRC_ALPHA */,
SourceConstantAlpha = byte.MaxValue
};
Win32Helper.UpdateLayeredWindow(this.Handle, screenDc, ref topPoint, ref size, compatibleMemoryDc,
ref sourcePoint, 0, ref blend, 2 /* ULW_ALPHA */);
}
finally
{
if (screenDc != IntPtr.Zero)
{
Win32Helper.ReleaseDC(IntPtr.Zero, screenDc);
}
if (hgdiBitmap != IntPtr.Zero)
{
Win32Helper.SelectObject(compatibleMemoryDc, hgdiOldBitmap);
Win32Helper.DeleteObject(hgdiBitmap);
}
Win32Helper.DeleteDC(compatibleMemoryDc);
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00080000; // Turn on WS_EX_LAYERED
return cp;
}
}
}
I use it in my other form by extend and set my image with SetBitmap() function. My form is empty border less form and this is not a child window (the WS_EX_LAYERED does not work for a child window for older windows than Windows 8).

Related

Is there a way to force a Win32 Timer to execute when not idle?

Win32 Timers created with SetTimer normally only execute when the message queue is empty. Is there any way to manually force an execution in the case the GUI thread is very busy and thus not empty?
(Edit)
As discussed below, in particular this is about having low priority messages (in this case indirectly to show a tool tip) continue to work when saturating the UI thread (but not blocking it). Here's some code:
using System;
using System.Threading;
using System.Windows.Forms;
namespace ToolTipTesting
{
public partial class Form1 : Form
{
Thread _thread = null;
bool _run = false;
bool _exit = false;
public Form1()
{
var tsbStart = new ToolStripButton();
tsbStart.Text = "Start";
tsbStart.Click += (s,e) => _run = true;
var tsbStop = new ToolStripButton();
tsbStop.Text = "Stop";
tsbStop.Click += (s,e) => _run = false;
var tslValue = new ToolStripLabel();
var ts = new ToolStrip();
ts.Items.Add(tsbStart);
ts.Items.Add(tsbStop);
ts.Items.Add(tslValue);
Controls.Add(ts);
_thread = new Thread(() =>
{
int i = 0;
while (!_exit)
{
if(_run)
{
var result = BeginInvoke(new Action(() => { tslValue.Text = (i++).ToString(); ts.Update(); } ));
while(!_exit && !result.IsCompleted)
result.AsyncWaitHandle.WaitOne(10);
}
else
{
Thread.Sleep(100);
}
}
});
FormClosing += (s,e) =>
{
_exit = true;
_thread.Join();
};
_thread.Start();
}
}
}
If this is "the wrong way to do it"...happy to hear the "right way to do it."
Success! As Raymond Chen suggests above, the solution is to use PeekMessage. Here is the completed code:
using System;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ToolTipTesting
{
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
public partial class Form1 : Form
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PeekMessage(ref NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
const int QS_TIMER = 0x0010;
const int WM_TIMER = 0x0113;
Thread _thread = null;
bool _run = false;
bool _exit = false;
public Form1()
{
var tsbStart = new ToolStripButton();
tsbStart.Text = "Start";
tsbStart.Click += (s,e) => _run = true;
var tsbStop = new ToolStripButton();
tsbStop.Text = "Stop";
tsbStop.Click += (s,e) => _run = false;
var tslValue = new ToolStripLabel();
var ts = new ToolStrip();
ts.Items.Add(tsbStart);
ts.Items.Add(tsbStop);
ts.Items.Add(tslValue);
Controls.Add(ts);
_thread = new Thread(() =>
{
int i = 0;
NativeMessage nativeMessage = new NativeMessage();
while (!_exit)
{
if(_run)
{
var result =
BeginInvoke
(
new Action
(
() =>
{
tslValue.Text = (i++).ToString();
PeekMessage
(
ref nativeMessage,
IntPtr.Zero,
WM_TIMER,
WM_TIMER,
QS_TIMER << 16
);
ts.Update();
}
)
);
while(!_exit && !result.IsCompleted)
result.AsyncWaitHandle.WaitOne(10);
}
else
{
Thread.Sleep(100);
}
}
});
FormClosing += (s,e) =>
{
_exit = true;
_thread.Join();
};
_thread.Start();
}
}
}

Issues with adding custom control to winforms tabcontrol

I am having trouble adding a custom zoom-able an pan-able picture box control to a tabcontrol.tabpage dynamically at runtime. I have tried a lot and was wondering if any of you smart fellas might have some advice for a poor noob like myself... here is some code...
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace TAQTv4
{
public class ZoomPanPicBox : ScrollableControl
{
private Image _image;
//Double buffer the control
public ZoomPanPicBox()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
this.AutoScroll = true;
this.Image = null;
this.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
this.Zoom = 1f;
}
//New
[Category("Appearance"), Description("The image to be displayed")]
public Image Image
{
get { return _image; }
set
{
_image = value;
UpdateScaleFactor();
Invalidate();
}
}
private float _zoom = 1f;
[Category("Appearance"), Description("The zoom factor. Less than 1 to reduce. More than 1 to magnify.")]
public float Zoom
{
get { return _zoom; }
set
{
if (value < 0 || value < 1E-05)
{
value = 1E-05f;
}
_zoom = value;
UpdateScaleFactor();
Invalidate();
}
}
private void UpdateScaleFactor()
{
if (_image == null)
{
this.AutoScrollMargin = this.Size;
}
else
{
this.AutoScrollMinSize = new Size(Convert.ToInt32(this._image.Width * _zoom + 0.5f), Convert.ToInt32(this._image.Height * _zoom + 0.5f));
}
}
//UpdateScaleFactor
private InterpolationMode _interpolationMode = InterpolationMode.High;
[Category("Appearance"), Description("The interpolation mode used to smooth the drawing")]
public InterpolationMode InterpolationMode
{
get { return _interpolationMode; }
set { _interpolationMode = value; }
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
}
//OnPaintBackground
protected override void OnPaint(PaintEventArgs e)
{
//if no image, don't bother. I tried check for IsNothing(_image) but this test wasn't detecting a no-image.
if (_image == null)
{
base.OnPaintBackground(e);
return;
}
//Added because the first test sometimes failed
try
{
int H = _image.Height;
//Throws an exception if image is nothing.
}
catch (Exception ex)
{
base.OnPaintBackground(e);
return;
}
//Set up a zoom matrix
Matrix mx = new Matrix(_zoom, 0, 0, _zoom, 0, 0);
mx.Translate(this.AutoScrollPosition.X / _zoom, this.AutoScrollPosition.Y / _zoom);
e.Graphics.Transform = mx;
e.Graphics.InterpolationMode = _interpolationMode;
e.Graphics.DrawImage(_image, new Rectangle(0, 0, this._image.Width, this._image.Height), 0, 0, _image.Width, _image.Height, GraphicsUnit.Pixel);
base.OnPaint(e);
}
//OnPaint
}
}
//ZoomPicBox
Now this seems to work fine while using the designer... but when trying to add images and controls at runtime the tabs instantiate fine but the zoomPicBox control does nothing so it would seem... This is how I am using it....
public void loadImagesToTabControl()
{
int i = 0;
foreach (Bitmap bitmap in intDwg.getBitmaps())
{
//ToDo add pic boxes and tabs and bitmaps to tabcontrol1
TAQTv4.ZoomPanPicBox picBox = new TAQTv4.ZoomPanPicBox();
picBox.Image = bitmap;
picBox.Anchor = AnchorStyles.Top;
picBox.Anchor = AnchorStyles.Bottom;
picBox.Anchor = AnchorStyles.Left;
picBox.Anchor = AnchorStyles.Right;
picBox.AutoScroll = true;
picBox.CausesValidation = true;
picBox.Visible = true;
picBox.Zoom = 1;
picBox.BackgroundImageLayout = ImageLayout.Tile;
picBox.Location = new System.Drawing.Point(0, 0);
picBox.TabStop = true;
picBox.Enabled = true;
picBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
picBox.CreateControl();
string title = "Pg " + (tabControl1.TabCount + 1).ToString();
TabPage myTabPage = new TabPage(title);
tabControl1.TabPages.Add(myTabPage);
tabControl1.TabPages[i].Controls.Add(picBox);
i++;
/* Possible pictureBox Implementation...
string title = "Pg " + (tabControl1.TabCount + 1).ToString();
TabPage myTabPage = new TabPage(title);
tabControl1.TabPages.Add(myTabPage);
PictureBox picbox = new PictureBox();
picbox.Anchor = AnchorStyles.Top;
picbox.Anchor = AnchorStyles.Bottom;
picbox.Anchor = AnchorStyles.Left;
picbox.Anchor = AnchorStyles.Right;
picbox.Image = bitmap;
picbox.Height = 800;
picbox.Width = 1300;
tabControl1.TabPages[i].Controls.Add(picbox);
i++;
*/
}
}
}
And as a last note... the pictureBox implementation worked fine as well so I know I am pulling my images from disk fine in the deserialization method of my intDwg class. Any thoughts would be much appreciated! Thanks in advance!
UPDATE:
I got the control to load pictures by setting backgroundimage to bitmap instead of picBox.Image.... FRUSTRATING .... but it seems that the way I have it set up the image is not anchored correctly ... trying to improve this and work it out now... any tips and tricks would be just awesome! Thanks!
UPDATE:
A Screen shot... as you can see the tab pages load correctly and one for each bitmap in my collection, yet the custom zoomPanPicBox control does not seem to want to display! See Bellow:
ahh .... seems I don't have rep to post pics.... ... alright how about...
https://www.dropbox.com/s/ogj5jlcce831n3p/scrst.png?v=0mcns
...
UPDATE AGAIN GOT IT THANKS All was missing setting the size as you had mentioned using the following: picBox.SetBounds(0, 0, 300, 300);
:D:D:D:D:D:D:)
Also, instead of using a counter:
TabPage myTabPage = new TabPage(title);
tabControl1.TabPages.Add(myTabPage);
tabControl1.TabPages[i].Controls.Add(picBox);
i++;
Just use your "myTabPage" reference:
TabPage myTabPage = new TabPage(title);
myTabPage.Controls.Add(picBox);
tabControl1.TabPages.Add(myTabPage);

Is a dashed border around a selected text/image element possible in Silverlight?

I have an image editor I'm developing in silverlight which has multiple text and image elements on one canvas, that are draggable etc. I need feedback for the user to highlight the selected element when it is clicked on by the user and highlight a different element instead if another is clicked. I think I should do this with a dashed border around the element, but I don't know if it's possible.
Below is my code relating to the elements -
Project.cs
namespace ImageEditor.Client.BLL
{
public class Project : INotifyPropertyChanged
{
private int numberOfElements;
#region Properties
private ObservableCollection<FrameworkElement> elements;
public ObservableCollection<FrameworkElement> Elements
{
get { return elements; }
set
{
elements = value;
NotifyPropertyChanged("Elements");
}
}
private FrameworkElement selectedElement;
public FrameworkElement SelectedElement
{
get { return selectedElement; }
set
{
selectedElement = value;
NotifyPropertyChanged("SelectedElement");
}
}
private TextBlock selectedTextElement;
public TextBlock SelectedTextElement
{
get { return selectedTextElement; }
set
{
selectedTextElement = value;
NotifyPropertyChanged("SelectedTextElement");
}
}
private Image selectedImageElement;
public Image SelectedImageElement
{
get { return selectedImageElement; }
set
{
selectedImageElement = value;
NotifyPropertyChanged("SelectedImageElement");
}
}
#endregion
#region Methods
private void AddTextElement(object param)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = "New Text";
textBlock.Foreground = new SolidColorBrush(Colors.Gray);
textBlock.FontSize = 25;
textBlock.FontFamily = new FontFamily("Arial");
textBlock.Cursor = Cursors.Hand;
textBlock.Tag = null;
AddDraggingBehavior(textBlock);
textBlock.MouseLeftButtonUp += element_MouseLeftButtonUp;
this.Elements.Add(textBlock);
numberOfElements++;
this.SelectedElement = textBlock;
this.selectedTextElement = textBlock;
}
private BitmapImage GetImageFromLocalMachine(out bool? success, out string fileName)
{
OpenFileDialog dialog = new OpenFileDialog()
{
Filter = "Image Files (*.bmp;*.jpg;*.gif;*.png;)|*.bmp;*.jpg;*.gif;*.png;",
Multiselect = false
};
success = dialog.ShowDialog();
if (success == true)
{
fileName = dialog.File.Name;
FileStream stream = dialog.File.OpenRead();
byte[] data;
BitmapImage imageSource = new BitmapImage();
using (FileStream fileStream = stream)
{
imageSource.SetSource(fileStream);
data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
fileStream.Flush();
fileStream.Close();
}
return imageSource;
}
else
{
fileName = string.Empty;
return new BitmapImage();
}
}
private void AddImageElement(object param)
{
bool? gotImage;
string fileName;
BitmapImage imageSource = GetImageFromLocalMachine(out gotImage, out fileName);
if (gotImage == true)
{
Image image = new Image();
image.Name = fileName;
image.Source = imageSource;
image.Height = imageSource.PixelHeight;
image.Width = imageSource.PixelWidth;
image.MaxHeight = imageSource.PixelHeight;
image.MaxWidth = imageSource.PixelWidth;
image.Cursor = Cursors.Hand;
image.Tag = null;
AddDraggingBehavior(image);
image.MouseLeftButtonUp += element_MouseLeftButtonUp;
this.Elements.Add(image);
numberOfElements++;
this.SelectedElement = image;
this.SelectedImageElement = image;
}
}
private void OrderElements()
{
var elList = (from element in this.Elements
orderby element.GetValue(Canvas.ZIndexProperty)
select element).ToList<FrameworkElement>();
for (int i = 0; i < elList.Count; i++)
{
FrameworkElement fe = elList[i];
fe.SetValue(Canvas.ZIndexProperty, i);
}
this.Elements = new ObservableCollection<FrameworkElement>(elList);
}
public void element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.SelectedElement = sender as FrameworkElement;
if (sender is TextBlock)
{
this.SelectedTextElement = sender as TextBlock;
FadeOut(this.SelectedTextElement);
}
else if (sender is Image)
{
this.SelectedImageElement = sender as Image;
FadeOut(this.SelectedImageElement);
}
}
#endregion
More than needed there but you get a good idea of how it all works from that. How might I go about it? I'm still pretty new to silverlight
Edit:
This is my start attempt at a DashBorder Method, wherein I'm trying to make a rectangle the same dimensions as the selected element which will go around the element
public static void DashBorder(FrameworkElement element)
{
Rectangle rect = new Rectangle();
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.Width=element.Width;
rect.Height=element.Height;
rect.StrokeDashArray = new DoubleCollection() { 2, 2 };
}
It appears to do nothing and isn't what I want to do anyway. Is there no way to make a dash border on a FrameworkElement directly?
I don't know how, but google does.
You can use the StrokeDashArray to achieve the desired effect,
example:
<Rectangle Canvas.Left="10" Canvas.Top="10" Width="100" Height="100"
Stroke="Black" StrokeDashArray="10, 2"/>
The first number in StrokeDashArray is the length of the dash, the
second number is the length of the gap. You can repeat the dash gap
pairs to generate different patterns.
Edit:
To do this in code create a rectangle and set it's StrokeDashArray property like this (code untested):
Rectangle rect = new Rectangle();
rect.StrokeThickness = 1;
double[] dashArray = new double[2];
dashArray[0] = 2;
dashArray[1] = 4;
rect.StrokeDashArray = dashArray;

Windows phone 7.1 can I change font size on a shell tile?

I'm trying to display a tweet on the backside of a live tile, when I set it as BackContent it's way too big.... Is there any way to lower the font size?
EDIT:
Claus, Now i'm having trouble getting the tile to display and I can't get any info on why it's not working due to the nature of your ImageOpened call, I can't step through it with the debugger....
In my TileGenerator class, this works:
public static void GenerateTestTile(string strTweet, string strScreenName, string tileTitle)
{
// Define the tile's address. This is where you navigate, when the tile is clicked.
var address = "/MainPage.xaml?TileID=6";
// Check if a tile with the same address already exists
//var tile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString() == address);
var tile = ShellTile.ActiveTiles.First();
// Define our tile data.
var tileData = new StandardTileData
{
BackTitle = strScreenName,
BackContent = strTweet
};
// If the file already exists, update it.
if (tile != null)
{
tile.Update(tileData);
}
else
{
// Otherwise, create a new tile.
ShellTile.Create(new Uri(address, UriKind.Relative), tileData);
}
}
But this doesn't (exact method taken from your example), it doesn't do anything to the tile at all...
public static void GenerateExampleTile(string timeOfDay, string temperature, Uri cloudImagePath, string tileTitle)
{
// Setup the font style for our tile.
var fontFamily = new FontFamily("Segoe WP");
var fontForeground = new SolidColorBrush(Colors.White);
var tileSize = new Size(173, 173);
// Create a background rectagle for a custom colour background.
var backgroundRectangle = new Rectangle();
backgroundRectangle.Width = tileSize.Width;
backgroundRectangle.Height = tileSize.Height;
backgroundRectangle.Fill = new SolidColorBrush(Colors.Blue);
// Load our 'cloud' image.
var source = new BitmapImage(cloudImagePath);
source.CreateOptions = BitmapCreateOptions.None;
source.ImageOpened += (sender, e) => // This is important. The image can't be rendered before it's loaded.
{
// Create our image as a control, so it can be rendered to the WriteableBitmap.
var cloudImage = new Image();
cloudImage.Source = source;
cloudImage.Width = 100;
cloudImage.Height = 64;
// TextBlock for the time of the day.
TextBlock timeOfDayTextBlock = new TextBlock();
timeOfDayTextBlock.Text = timeOfDay;
timeOfDayTextBlock.FontSize = 20;
timeOfDayTextBlock.Foreground = fontForeground;
timeOfDayTextBlock.FontFamily = fontFamily;
// Temperature TextBlock.
TextBlock temperatureTextBlock = new TextBlock();
temperatureTextBlock.Text = temperature + '°';
temperatureTextBlock.FontSize = 30;
temperatureTextBlock.Foreground = fontForeground;
temperatureTextBlock.FontFamily = fontFamily;
// Define the filename for our tile. Take note that a tile image *must* be saved in /Shared/ShellContent
// or otherwise it won't display.
var tileImage = string.Format("/Shared/ShellContent/{0}.jpg", timeOfDay);
// Define the path to the isolatedstorage, so we can load our generated tile from there.
var isoStoreTileImage = string.Format("isostore:{0}", tileImage);
// Open the ISF store,
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
// Create our bitmap, in our selected dimension.
var bitmap = new WriteableBitmap((int)tileSize.Width, (int)tileSize.Height);
// Render our background. Remember the renders are in the same order as XAML,
// so whatever is rendered first, is rendered behind the next element.
bitmap.Render(backgroundRectangle, new TranslateTransform());
// Render our cloud image
bitmap.Render(cloudImage, new TranslateTransform()
{
X = 8, // Left margin offset.
Y = 54 // Top margin offset.
});
// Render the temperature text.
bitmap.Render(temperatureTextBlock, new TranslateTransform()
{
X = 124,
Y = 63
});
// Render the time of the day text.
bitmap.Render(timeOfDayTextBlock, new TranslateTransform()
{
X = 12,
Y = 6
});
// Create a stream to store our file in.
var stream = store.CreateFile(tileImage);
// Invalidate the bitmap to make it actually render.
bitmap.Invalidate();
// Save it to our stream.
bitmap.SaveJpeg(stream, 173, 173, 0, 100);
// Close the stream, and by that saving the file to the ISF.
stream.Close();
}
// Define the tile's address. This is where you navigate, when the tile is clicked.
var address = "/MainPage.xaml?TileID=" + timeOfDay;
// Check if a tile with the same address already exists
var tile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString() == address);
// Define our tile data.
var tileData = new StandardTileData
{
BackgroundImage = new Uri(isoStoreTileImage, UriKind.Absolute),
Title = tileTitle,
};
// If the file already exists, update it.
if (tile != null)
{
tile.Update(tileData);
}
else
{
// Otherwise, create a new tile.
ShellTile.Create(new Uri(address, UriKind.Relative), tileData);
}
};
}
Both methods are being called in this way....
public class ScheduledAgent : ScheduledTaskAgent
{
...
/// <summary>
/// Agent that runs a scheduled task
/// </summary>
/// <param name="task">
/// The invoked task
/// </param>
/// <remarks>
/// This method is called when a periodic or resource intensive task is invoked
/// </remarks>
protected override void OnInvoke(ScheduledTask task)
{
LoadWatchList();
}
//WATCH LIST
private void LoadWatchList()
{
if (HasConnectivity)
{
GetWatchListTweetsFromTwitter(CurrentWatchListID);
}
}
public void GetWatchListTweetsFromTwitter(int list_id)
{
WebClient wcWatchListTimeline = new WebClient();
wcWatchListTimeline.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wcWatchListTimeline_DownloadStringCompleted);
wcWatchListTimeline.DownloadStringAsync(new System.Uri("https://api.twitter.com/1/lists/statuses.xml?per_page=1&list_id=" + list_id));
}
void wcWatchListTimeline_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
String strTweet = "content";
String strScreenName = "title";
if (e.Error != null)
{
strScreenName = "error";
strTweet = e.Error.Message;
}
else
{
XElement tweet = XElement.Parse(e.Result);
Tweet thisTweet = GetTweet(tweet);
if (thisTweet != null)
{
strTweet = thisTweet.text;
strScreenName = thisTweet.screen_name;
}
}
// TAKEN FROM EXAMPLE FOR TESTING - NOT WORKING
string timeOfday = "morning";
string temperature = "99";
string location = "San Antonio";
Uri cloudImagePath = new Uri("Images/tweetEmpty.png", UriKind.Relative);
Deployment.Current.Dispatcher.BeginInvoke(() => TileGenerator.GenerateExampleTile(timeOfday, temperature, cloudImagePath, "mainTile"));
//WORKING
//Deployment.Current.Dispatcher.BeginInvoke(() => TileGenerator.GenerateTile(strTweet, strScreenName, "mainTile"));
NotifyComplete();
}
protected Tweet GetTweet(XElement Xdata)
{
List<Tweet> listTweets = (from tweet in Xdata.Descendants("status")
select new Tweet
{
screen_name = tweet.Element("user").Element("screen_name").Value,
text = tweet.Element("text").Value
}).ToList<Tweet>();
if (listTweets.Count > 0)
{
return listTweets[0];
}
else
{
return null;
}
}
}
Only by creating a custom image, and using that as the background for the tile.
Updated: How To: Live Tile with Scheduled Agent

How to log name/path of clicked control in WPF?

I use the following code to log every click in our WinForms application. In essence it looks up a control from its HWND and then prints the types and names of the control and all of its parents. Something like MainForm"myWindow">TabPanel"mainTab">Button"save"
internal class ClickLogger : IMessageFilter
{
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_LBUTTONDBLCLK = 0x0203;
private const int WM_RBUTTONDOWN = 0x0204;
private const int MaxRecurseDepth = 30;
private readonly ILogger _log;
public ClickLogger(ILogger logger)
{
_log = logger;
}
[DebuggerStepThrough]
public bool PreFilterMessage(ref Message message)
{
if (message.Msg == WM_LBUTTONDOWN
|| message.Msg == WM_RBUTTONDOWN
|| message.Msg == WM_LBUTTONDBLCLK)
{
string path = "Unknown";
Control ctl = Control.FromHandle(message.HWnd);
if (ctl != null)
{
path = PathFromControl(ctl, MaxRecurseDepth).ToString();
}
string logEntry = string.Format("{0} Click on {1}",
WndMsgToClickName(message.Msg), path);
if (_log.IsInfoEnabled)
{
_log.Info(logEntry);
}
}
return false;
}
private StringBuilder PathFromControl(Control control, int maxDepth)
{
if(maxDepth == 0)
{
_log.Warn("Max recursion {0} reached whilst resolving path of control", MaxRecurseDepth);
return new StringBuilder("ERR");
}
string name = control.GetType().Name;
if (control.Name.IsNotBlank())
{
name = name + "\"" + control.Name + "\"";
}
if (control.Parent != null && control.Parent != control)
{
return PathFromControl(control.Parent, maxDepth - 1).Append(">").Append(name);
}
return new StringBuilder(name);
}
public void Initialize()
{
Application.AddMessageFilter(this);
}
private static string WndMsgToClickName(int msgId)
{
switch (msgId)
{
case WM_LBUTTONDOWN:
return "Left";
case WM_LBUTTONDBLCLK:
return "Double";
case WM_RBUTTONDOWN:
return "Right";
default:
return "0x" + Convert.ToString(msgId, 16);
}
}
}
Recently we've started to mix WPF and WinForms and the above click logger simply prints "Unknown" for any click on a WPF control.
Is there a way I can perform a similar trick for WPF controls? A method that would work across technologies would be great.
well, it doesn't exactly work across technologies but for wpf you can use a combination of this to get the clicks and any of the helpers in this question to cycle through the parents to get the path.

Resources