Playing sound parallelly with System.Media.SoundPlayer.PlaySync() and AxWindowsMediaPlayer - winforms

I have created a WinForm application which contains an AxWMPLib.AxMediaPlayer in which I play some videos. I also have to play some other custom sounds in a different thread. For this I used System.Media.SoundPlayer.PlaySync(). This thread plays couple of sound files sequentially in a loop. The problem is when I pause/stop the video the button event sounds are played fine. But when the video is running, sometimes some of the sound files are skipped. And it happens randomly.
Could anyone give some explanation about the problem and how to over come it. I mean how could I play the both sounds and video in parallel.
The video is playing in the UI thread and the other sounds are playing from different thread.Please check out the code bellow:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using ElectroQ;
using ElectroQServer1.Entities;
using WMPLib;
using System.Media;
using System.Windows.Media;
namespace ElectroQServer1
{
public partial class Form1 : Form
{
Thread dbListenerThread;
IWMPPlaylist playlist;
//string[] tokenNumber = { "A001", "B002", "C003", "D004","E005", "F006", "G007","HAMB" };
//string[] counterNumber = { "01", "02", "03", "04", "05", "06", "07", "MB" };
public Form1()
{
InitializeComponent();
//ResizeRedraw = true;
this.SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true);
this.WindowState = FormWindowState.Maximized;
//this.FormBorderStyle = FormBorderStyle.None;
//this.TopMost = true;
dbListenerThread = new Thread(RefreshQueueBoard);
dbListenerThread.Start();
}
/// <summary>
/// This method is used to prevent the flickering of the window.
/// </summary>
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
public void RefreshQueueBoard()
{
//Thread.Sleep(000);
while (true)
{
List<QueueData> lstQData = DA.GetAllQueueData(" where service_status_id = 2 ");
printToken(lstQData);
printCounter(lstQData);
playSound(lstQData);
Thread.Sleep(1000);
}
}
public void playSound(List<QueueData> lstQData)
{
foreach (QueueData qData in lstQData)
{
if (!qData.SoundPlayed)
{
string strSoundFile;
PlaySoundFIle(#"Sounds/TN.WAV");
foreach (char c in qData.ServiceQueueSerial)
{
strSoundFile = string.Format(#"Sounds/{0}.WAV", c);
PlaySoundFIle(strSoundFile);
}
PlaySoundFIle(#"Sounds/CN.WAV");
foreach (char c in qData.ServiceCounterID)
{
strSoundFile = string.Format(#"Sounds/{0}.WAV", c);
PlaySoundFIle(strSoundFile);
}
string strUpdateQuery = string.Format("UPDATE electro_queue SET sound_played = 1 WHERE service_queue_serial = '{0}'", qData.ServiceQueueSerial);
DA.UpdateQueueData(strUpdateQuery);
}
}
}
public void PlaySoundFIle(string strFile)
{
//string[] files = new string[4] { #"Sounds/TN.WAV", #"Sounds/CN.WAV", #"Sounds/TN.WAV", #"Sounds/CN.WAV"};
//WaveIO wa = new WaveIO();
//wa.Merge(files, #"tempfile.wav");
//MediaPlayer wowSound = new MediaPlayer(); //Initialize a new instance of MediaPlayer of name wowSound
//wowSound.Open(new Uri(#"tempfile.wav", UriKind.Relative)); //Open the file for a media playback
//wowSound.Play();
using (var soundPlayer = new SoundPlayer(strFile))
{
soundPlayer.PlaySync(); // can also use soundPlayer.Play() but it misses some sound file.
}
}
private void printToken(List<QueueData> lstQData)
{
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
pnlQStat.Controls.Clear();
string dir;
//int xpos = 55;
//int ypos = 207;
int xpos = 10;
int ypos = 00;
//int k=0;
for (int i = 0; i < lstQData.Count; i++)
{
/* if (i == 4 || i == 8)
{
ypos = ypos - 360;
xpos = 675;
}*/
foreach (char c in lstQData[i].ServiceQueueSerial)
{
if (i == 0)
{
dir = "Resources/_" + c + ".bmp";
}
else
{
dir = "Resources/" + c + ".bmp";
}
createPicBox(dir, "pBox" + i, xpos, ypos);
xpos = xpos + 43;
}
ypos = ypos + 50;
xpos = 10;
}
}));
return;
}
}
private void printCounter(List<QueueData> lstQData)
{
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate
{
//int xpos = 415;
//int ypos = 207;
//int xpos = 292;
int xpos = 220;
int ypos = 00;
//int k=0;
for (int i = 0; i < lstQData.Count; i++)
{
/*if (i == 4 || i == 8)
{
ypos = ypos - 360;
xpos = 1035;
}
*/
foreach (char c in lstQData[i].ServiceCounterID)
{
string dir;
if (i == 0)
{
dir = "Resources/_" + c + ".bmp";
}
else
{
dir = "Resources/" + c + ".bmp";
}
//string dir = "Resources/" + c + ".bmp";
createPicBox(dir, "pBox" + i, xpos, ypos);
xpos = xpos + 63;
}
ypos = ypos + 50;
xpos = xpos - 63;
}
}));
return;
}
}
private void createPicBox(string directory, string name, int xposition, int yposition)
{
PictureBox picBox = new System.Windows.Forms.PictureBox();
picBox.Name = name;
picBox.Location = new System.Drawing.Point(xposition, yposition);
picBox.Size = new System.Drawing.Size(40, 50);
picBox.BackgroundImage = Image.FromFile(directory);
picBox.BackgroundImageLayout = ImageLayout.Stretch;
pnlQStat.Controls.Add(picBox);
}
private void Form1_Load(object sender, EventArgs e)
{
createPlayList();
//dbListenerThread.Abort(); // this line of code should be placed in onClosing Event.
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
dbListenerThread.Abort();
player.playlistCollection.remove(playlist);
}
private void createPlayList()
{
playlist = player.playlistCollection.newPlaylist("mpl");
playlist.appendItem(player.newMedia(#"E:\SONGS\teri-meri-promo-Muskurahat.Com.wmv"));
playlist.appendItem(player.newMedia(#"E:\MOVZZZ\English\The Kid\THE KID FILM_1_0001.avi"));
player.currentPlaylist = playlist;
}
private void btnPlay_Click(object sender, EventArgs e)
{
// player.URL = #"E:\MOVZZZ\English\The Kid\THE KID FILM_1_0001.avi";
player.Ctlcontrols.play();
}
private void btnStop_Click(object sender, EventArgs e)
{
player.Ctlcontrols.stop();
}
}
}
My objective is to play the looped sound files sequentially with the video playing in parallel.

You should not use SoundPlayer for this purpose; SoundPlayer is a lightweight, convenience class for playing occasional incidental sounds in an application. It will occasionally skip sounds if other things are going on in the audio subsystem (like a video playing). Here is a good sample that shows how to use the low-level waveOutOpen API for playing sounds.

Related

unity array having 50 gameobjects but displays only 10 object

i have build a level menu with levels, i also created and empty array (GameObject[ ] lvlBut; )to store the level icons instantiated, but only 10 level icons are displayed on the screen where as i have 50 levels. for some reason its only taking 10 levels and i don’t t know where i have gone wrong. any suggestions?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.UI;
using TMPro;
public class LevelSelector : MonoBehaviour{
public GameObject levelHolder;
public GameObject levelIcon;
public GameObject thisCanvas;
public int numberOfLevels = 50;
public Vector2 iconSpacing;
private Rect panelDimensions;
private Rect iconDimensions;
private int amountPerPage;
private int currentLevelCount;
int levelsUnlocked;
GameObject[] lvlBut;
void Start()
{
panelDimensions = levelHolder.GetComponent<RectTransform>().rect;
iconDimensions = levelIcon.GetComponent<RectTransform>().rect;
int maxInARow = Mathf.FloorToInt((panelDimensions.width + iconSpacing.x) / (iconDimensions.width + iconSpacing.x));
int maxInACol = Mathf.FloorToInt((panelDimensions.height + iconSpacing.y) / (iconDimensions.height + iconSpacing.y));
amountPerPage = maxInARow * maxInACol;
int totalPages = Mathf.CeilToInt((float)numberOfLevels / amountPerPage);
LoadPanels(totalPages);
}
void LoadPanels(int numberOfPanels)
{
GameObject panelClone = Instantiate(levelHolder) as GameObject;
PageSwiper swiper = levelHolder.AddComponent<PageSwiper>();
swiper.totalPages = numberOfPanels;
for (int i = 1; i <= numberOfPanels; i++)
{
GameObject panel = Instantiate(panelClone) as GameObject;
panel.transform.SetParent(thisCanvas.transform, false);
panel.transform.SetParent(levelHolder.transform);
panel.name = "Page-" + i;
panel.GetComponent<RectTransform>().localPosition = new Vector2(panelDimensions.width * (i - 1), 0);
SetUpGrid(panel);
int numberOfIcons = i == numberOfPanels ? numberOfLevels - currentLevelCount : amountPerPage;
LoadIcons(numberOfIcons, panel);
}
Destroy(panelClone);
}
void SetUpGrid(GameObject panel)
{
GridLayoutGroup grid = panel.AddComponent<GridLayoutGroup>();
grid.cellSize = new Vector2(iconDimensions.width, iconDimensions.height);
grid.childAlignment = TextAnchor.MiddleCenter;
grid.spacing = iconSpacing;
}
void LoadIcons(int numberOfIcons, GameObject parentObject)
{
for (int i = 1; i <= numberOfIcons; i++)
{
currentLevelCount++;
GameObject icon = Instantiate(levelIcon) as GameObject;
icon.transform.SetParent(thisCanvas.transform, false);
icon.transform.SetParent(parentObject.transform);
icon.name = "Level " + i;
icon.GetComponentInChildren<TextMeshProUGUI>().SetText(currentLevelCount.ToString());
}
lvlBut = GameObject.FindGameObjectsWithTag("LevelButton");
levelsUnlocked = PlayerPrefs.GetInt("levelsUnlocked", 1);
for (int i = 0; i < lvlBut.Length; i++)
{
lvlBut[i].GetComponentInChildren<Button>().interactable = false;
}
for (int i = 0; i < levelsUnlocked; i++)
{
lvlBut[i].GetComponentInChildren<Button>().interactable = true;
}
}
}

Why does this image rendering benchmark crash on IOS but not in the simulator?

I tried to get a grasp of image rendering performance and created some code which draws full screen images using mutable images and PNGs.
The code runs fine in the simulator but on an iPhone SE it crashes after 50 seconds or short before a million images.
Is it a bug or is there another explanation since it doesn't crash in the simulator and I cannot see a memory leak in jvisualvm?
Here is the code:
public class FormMeasureImage extends Form implements Painter {
abstract class Wallpaper implements Painter {
private Component componentParent;
public Wallpaper(Component aComponentParent) {
componentParent = aComponentParent;
}
public void paint(Graphics aGraphics, Rectangle aRectangle) {
aGraphics.drawImage(
getImage(new Dimension(componentParent.getWidth(), componentParent.getHeight())),
0,
0);
}
public abstract Image getImage(Dimension aDimension);
}
class WallpaperTiledIcons extends Wallpaper {
private Image image;
private Dimension dimension;
public WallpaperTiledIcons(Component aComponentParent) {
super(aComponentParent);
}
public Image getImage(Dimension aDimension) {
if ((null == image || !dimension.equals(aDimension)) && null != aDimension) {
dimension = new Dimension(aDimension);
Label labelPattern = new Label("1234567890");
Style styleLabelPattern = labelPattern.getAllStyles();
styleLabelPattern.setBorder(Border.createEmpty());
styleLabelPattern.setMargin(0, 0, 0, 0);
// byte[] bytes = new byte[4];
// Arrays.fill(bytes, Style.UNIT_TYPE_PIXELS);
// styleLabelPattern.setPaddingUnit(bytes);
styleLabelPattern.setPadding(0, 0, 0, 1);
Dimension preferredSizeLabelPattern = labelPattern.getPreferredSize();
labelPattern.setSize(preferredSizeLabelPattern);
Image imagePattern = Image.createImage(
preferredSizeLabelPattern.getWidth(),
preferredSizeLabelPattern.getHeight(),
0x00000000);
Graphics graphicsImagePattern = imagePattern.getGraphics();
graphicsImagePattern.setAlpha(255);
labelPattern.paint(graphicsImagePattern);
image = Image.createImage(
aDimension.getWidth(),
aDimension.getHeight(),
0xff606060);
Graphics graphics = image.getGraphics();
if (graphics.isAntiAliasingSupported()) {
graphics.setAntiAliased(true);
}
int canvasWidth = preferredSizeLabelPattern.getWidth(), canvasHeight = preferredSizeLabelPattern.getHeight();
int[] clip = graphics.getClip();
Rectangle rectangleClip = new Rectangle(clip[0], clip[1], clip[2], clip[3]);
int columns = (rectangleClip.getX() + rectangleClip.getWidth()) / canvasWidth + 1;
int rows = (rectangleClip.getY() + rectangleClip.getHeight()) / canvasHeight + 1;
for (int row = 0; row < rows; row++) {
for (int column = 0; column < columns; column++) {
int x = canvasWidth * column;
int y = canvasHeight * row;
Rectangle rectangle = new Rectangle(x, y, canvasWidth, canvasHeight);
if (!rectangleClip.intersects(rectangle)) {
continue;
}
graphics.drawImage(imagePattern, x, y);
}
}
}
return image;
}
}
abstract class Stage {
long millisTotal;
long tally;
TextArea textArea;
public Stage(String aName) {
textArea = new TextArea();
textArea.setEditable(false);
getContentPane().add(textArea);
stages.add(this);
}
abstract void perform();
abstract boolean isPainted();
}
private Wallpaper wallpaper;
private List<Stage> stages = new ArrayList<>();
private Iterator<Stage> iteratorStages;
private Image imageEncoded;
public FormMeasureImage() {
super("FormMeasureImage", new BoxLayout(BoxLayout.Y_AXIS));
setScrollableX(false);
setScrollableY(true);
Style styleForm = getAllStyles();
styleForm.setBgTransparency(255);
styleForm.setBgPainter(this);
TextArea textArea = new TextArea();
textArea.setEditable(false);
textArea.setText("Measuring image throughput.");
add(textArea);
}
#Override
public void paint(Graphics aGraphics, Rectangle aRectangle) {
if (null == iteratorStages) {
new Stage("create") {
void perform() {
long millisBefore = System.currentTimeMillis();
wallpaper = new WallpaperTiledIcons(FormMeasureImage.this);
wallpaper.getImage(aRectangle.getSize());
millisTotal += System.currentTimeMillis() - millisBefore;
tally++;
textArea.setText("create: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return false;
}
};
new Stage("mutable") {
void perform() {
long millisBefore = System.currentTimeMillis();
for (int index = 0; index < 1000; index++) {
wallpaper.paint(aGraphics, aRectangle);
tally++;
}
millisTotal += System.currentTimeMillis() - millisBefore;
textArea.setText("mutable: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return true;
}
};
new Stage("encoding") {
void perform() {
long millisBefore = System.currentTimeMillis();
try {
millisBefore = System.currentTimeMillis();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.getImageIO().save(wallpaper.getImage(null), byteArrayOutputStream, ImageIO.FORMAT_PNG, 1);
byteArrayOutputStream.close();
imageEncoded = Image.createImage(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
tally++;
millisTotal += System.currentTimeMillis() - millisBefore;
textArea.setText("encoding: " + millisTotal + " / " + tally);
} catch (IOException e) {
throw new RuntimeException(e.toString());
}
millisTotal += System.currentTimeMillis() - millisBefore;
tally++;
textArea.setText("encoding: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return false;
}
};
new Stage("encoded") {
void perform() {
long millisBefore = System.currentTimeMillis();
for (int index = 0; index < 1000; index++) {
aGraphics.drawImage(
imageEncoded,
0,
0);
tally++;
}
millisTotal += System.currentTimeMillis() - millisBefore;
textArea.setText("encoded: " + millisTotal + " / " + tally);
}
boolean isPainted() {
return true;
}
};
iteratorStages = stages.iterator();
}
while (!perform().isPainted()) {;}
}
private Stage perform() {
if (!iteratorStages.hasNext()) {
iteratorStages = stages.iterator();
}
Stage stage = iteratorStages.next();
stage.perform();
return stage;
}
}
It seems that the test case included an EDT violation of decoding off the EDT. This can work for some cases but because of the heavy usage it crashes.
Making UI code threadsafe is a difficult task which is doubly so cross platforms.

WPF 3D POINT DRAWING

I need to draw a point in 3D using WPF. I am using class ScreenSpaceLines3D to draw a line in 3D, but I'm not able to draw point in 3D (while model zooming). Can anybody help me? Some example code would be appreciated. Thanks
Use PointsVisual3D class from helixtoolkit, with it you can add points on viewport with color, size. Even you can apply transforms, too.
A point can't be seen, because it has no surface area. WPF 3d is not a ray tracing engine, unfortunately.
However, someone built a pretty nice ray-tracing starter library. This project is a good starting point if you want to do ray-tracing with WPF: http://raytracer.codeplex.com/.
It is not so complicated task.
Download the Helix3D Library
Find the sphere mesh code in samples
Attach the scphere's radius to zooming realization.
i can create a PointVisual3d Own Class. The code of PointVisual3D is below i think this one is helpful for you...
public class PointVisual3D:ModelVisual3D
{
private readonly GeometryModel3D _model;
private readonly MeshGeometry3D _mesh;
private Matrix3D _visualToScreen;
private Matrix3D _screenToVisual;
public PointVisual3D()
{
_mesh = new MeshGeometry3D();
_model = new GeometryModel3D();
_model.Geometry = _mesh;
SetColor(this.Color);
this.Content = _model;
this.Points = new Point3DCollection();
CompositionTarget.Rendering += OnRender;
}
private void OnRender(object sender, EventArgs e)
{
if (Points.Count == 0 && _mesh.Positions.Count == 0)
{
return;
}
if (UpdateTransforms() && MainWindow.mousedown==false)
{
RebuildGeometry();
}
}
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(PointVisual3D), new PropertyMetadata(Colors.White, OnColorChanged));
private static void OnColorChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
((PointVisual3D)sender).SetColor((Color)args.NewValue);
}
private void SetColor(Color color)
{
MaterialGroup unlitMaterial = new MaterialGroup();
unlitMaterial.Children.Add(new DiffuseMaterial(new SolidColorBrush(Colors.Black)));
unlitMaterial.Children.Add(new EmissiveMaterial(new SolidColorBrush(color)));
unlitMaterial.Freeze();
_model.Material = unlitMaterial;
_model.BackMaterial = unlitMaterial;
}
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
//public static readonly DependencyProperty ThicknessProperty = DependencyProperty.Register("Thickness", typeof(double), typeof(PointVisual3D), new PropertyMetadata(1.0, OnThicknessChanged));
//private static void OnThicknessChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
//{
// ((PointVisual3D)sender).GeometryDirty();
//}
//public double Thickness
//{
// get { return (double)GetValue(ThicknessProperty); }
// set { SetValue(ThicknessProperty, value); }
//}
public static readonly DependencyProperty PointsProperty = DependencyProperty.Register("Points", typeof(Point3DCollection), typeof(PointVisual3D), new PropertyMetadata(null, OnPointsChanged));
private static void OnPointsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
((PointVisual3D)sender).GeometryDirty();
}
public Point3DCollection Points
{
get { return (Point3DCollection)GetValue(PointsProperty); }
set { SetValue(PointsProperty, value); }
}
private void GeometryDirty()
{
_visualToScreen = MathUtils.ZeroMatrix;
}
private void RebuildGeometry()
{
//double halfThickness = Thickness / 2.0;
//int numLines = Points.Count / 2;
//Point3DCollection positions = new Point3DCollection(numLines * 4);
//for (int i = 0; i < numLines; i++)
//{
// int startIndex = i * 2;
// Point3D startPoint = Points[startIndex];
// Point3D endPoint = Points[startIndex + 1];
// AddSegment(positions, startPoint, endPoint, halfThickness);
//}
//positions.Freeze();
//_mesh.Positions = positions;
Int32Collection indices = new Int32Collection(Points.Count * 6);
for (int i = 0; i < Points.Count; i++)
{
indices.Add(i * 4 + 2);
indices.Add(i * 4 + 1);
indices.Add(i * 4 + 0);
indices.Add(i * 4 + 2);
indices.Add(i * 4 + 3);
indices.Add(i * 4 + 1);
}
indices.Freeze();
_mesh.TriangleIndices = indices;
_mesh.Positions = CreatePositions(this.Points, this.Size, 0.0);
}
public Point3DCollection CreatePositions(IList<Point3D> points, double size = 1.0, double depthOffset = 0.0)
{
double halfSize = size / 2.0;
int numPoints = points.Count;
var outline = new[]
{
new Vector(-halfSize, halfSize), new Vector(-halfSize, -halfSize), new Vector(halfSize, halfSize),
new Vector(halfSize, -halfSize)
};
var positions = new Point3DCollection(numPoints * 4);
for (int i = 0; i < numPoints; i++)
{
var screenPoint = (Point4D)points[i] * this._visualToScreen;
double spx = screenPoint.X;
double spy = screenPoint.Y;
double spz = screenPoint.Z;
double spw = screenPoint.W;
if (!depthOffset.Equals(0))
{
spz -= depthOffset * spw;
}
var p0 = new Point4D(spx, spy, spz, spw) * this._screenToVisual;
double pwinverse = 1 / p0.W;
foreach (var v in outline)
{
var p = new Point4D(spx + v.X * spw, spy + v.Y * spw, spz, spw) * this._screenToVisual;
positions.Add(new Point3D(p.X * pwinverse, p.Y * pwinverse, p.Z * pwinverse));
}
}
positions.Freeze();
return positions;
}
/// <summary>
/// Identifies the <see cref="Size"/> dependency property.
/// </summary>
public static readonly DependencyProperty SizeProperty = DependencyProperty.Register(
"Size", typeof(double), typeof(PointVisual3D), new UIPropertyMetadata(1.0, GeometryChanged));
protected static void GeometryChanged(object sender, DependencyPropertyChangedEventArgs e)
{
((PointVisual3D)sender).GeometryDirty();
}
public double Size
{
get
{
return (double)this.GetValue(SizeProperty);
}
set
{
this.SetValue(SizeProperty, value);
}
}
//private void AddSegment(Point3DCollection positions, Point3D startPoint, Point3D endPoint, double halfThickness)
//{
// Vector3D lineDirection = endPoint * _visualToScreen - startPoint * _visualToScreen;
// lineDirection.Z = 0;
// lineDirection.Normalize();
// Vector delta = new Vector(-lineDirection.Y, lineDirection.X);
// delta *= halfThickness;
// Point3D pOut1, pOut2;
// Widen(startPoint, delta, out pOut1, out pOut2);
// positions.Add(pOut1);
// positions.Add(pOut2);
// Widen(endPoint, delta, out pOut1, out pOut2);
// positions.Add(pOut1);
// positions.Add(pOut2);
//}
//private void Widen(Point3D pIn, Vector delta, out Point3D pOut1, out Point3D pOut2)
//{
// Point4D pIn4 = (Point4D)pIn;
// Point4D pOut41 = pIn4 * _visualToScreen;
// Point4D pOut42 = pOut41;
// pOut41.X += delta.X * pOut41.W;
// pOut41.Y += delta.Y * pOut41.W;
// pOut42.X -= delta.X * pOut42.W;
// pOut42.Y -= delta.Y * pOut42.W;
// pOut41 *= _screenToVisual;
// pOut42 *= _screenToVisual;
// pOut1 = new Point3D(pOut41.X / pOut41.W, pOut41.Y / pOut41.W, pOut41.Z / pOut41.W);
// pOut2 = new Point3D(pOut42.X / pOut42.W, pOut42.Y / pOut42.W, pOut42.Z / pOut42.W);
//}
private bool UpdateTransforms()
{
Viewport3DVisual viewport;
bool success;
Matrix3D visualToScreen = MathUtils.TryTransformTo2DAncestor(this, out viewport, out success);
if (!success || !visualToScreen.HasInverse)
{
_mesh.Positions = null;
return false;
}
if (visualToScreen == _visualToScreen)
{
return false;
}
_visualToScreen = _screenToVisual = visualToScreen;
_screenToVisual.Invert();
return true;
}
}

Program to generate Tables, trouble using Events

I am doing a program in C# for kids with which kids can test their knowledge of Multiplication tables.
I cannot get the value of 'i' in the Result_Leave() function to track which value of the text box array is incorrect.
For Example:
5 X 1 = [ ] <---- an array of textboxes with name Result[i]"
the user enters the value of 5*1 in the text box and my program instantly checks if the entered value is correct or not, using the "Leave" event for the text box.
I have used an array of text boxes...
So I cannot track which Result[i] contains the incorrect value...
I have fired the function "Result_Leave" for each of the text boxes "Result[i]"
Here is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Tables
{
public partial class FormMain : Form
{
private System.Windows.Forms.Label[] labelNumber;
private System.Windows.Forms.Label[] labelCross;
private System.Windows.Forms.Label[] labelTableOf;
private System.Windows.Forms.Label[] labelEquals;
/*"Result" is an array of textboxes which takes the result of the multiplication from the user*/
private System.Windows.Forms.TextBox[] Result; //declaration
public FormMain()
{
InitializeComponent();
WindowState = FormWindowState.Maximized;
buttonCheckAnswers.Enabled = false;
}
private void buttonGo_Click(object sender, EventArgs e)
{
if (textBoxInput.Text == "")
{
errorProvider1.SetError(textBoxInput, "Hey! Enter a number please");
}
else
{
textBoxInput.Enabled = false;
buttonCheckAnswers.Enabled = true;
labelNumber = new System.Windows.Forms.Label[10];
labelCross = new System.Windows.Forms.Label[10];
labelTableOf = new System.Windows.Forms.Label[10];
labelEquals = new System.Windows.Forms.Label[10];
Result = new System.Windows.Forms.TextBox[10];
for (int i = 0; i < 10; i++)
{
// this snippet generates code for adding controls at runtime viz. textboxes and labels
labelNumber[i] = new Label();
this.labelNumber[i].AutoSize = true;
this.labelNumber[i].Location = new System.Drawing.Point(200, 163 + 55 * i);
this.labelNumber[i].Name = "labelNumber";
this.labelNumber[i].Size = new System.Drawing.Size(35, 13);
this.labelNumber[i].Text = (i + 1).ToString();
this.labelNumber[i].Font = new System.Drawing.Font("Comic Sans MS", 17F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelNumber[i].ForeColor = System.Drawing.Color.Khaki;
this.Controls.AddRange(new System.Windows.Forms.Control[] { labelNumber[i] });
labelCross[i] = new Label();
this.labelCross[i].AutoSize = true;
this.labelCross[i].Location = new System.Drawing.Point(150, 163 + 55 * i);
this.labelCross[i].Name = "labelCross";
this.labelCross[i].Size = new System.Drawing.Size(35, 13);
this.labelCross[i].Text = "X";
this.labelCross[i].Font = new System.Drawing.Font("Comic Sans MS", 17F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelCross[i].ForeColor = System.Drawing.Color.Khaki;
this.Controls.AddRange(new System.Windows.Forms.Control[] { labelCross[i] });
labelTableOf[i] = new Label();
this.labelTableOf[i].AutoSize = true;
this.labelTableOf[i].Location = new System.Drawing.Point(100, 163 + 55 * i);
this.labelTableOf[i].Name = "labelTableOf";
this.labelTableOf[i].Size = new System.Drawing.Size(35, 13);
this.labelTableOf[i].Text = textBoxInput.Text;
this.labelTableOf[i].Font = new System.Drawing.Font("Comic Sans MS", 17F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelTableOf[i].ForeColor = System.Drawing.Color.Khaki;
this.Controls.AddRange(new System.Windows.Forms.Control[] { labelTableOf[i] });
labelEquals[i] = new Label();
this.labelEquals[i].AutoSize = true;
this.labelEquals[i].Location = new System.Drawing.Point(250, 163 + 55 * i);
this.labelEquals[i].Name = "labelTableOf";
this.labelEquals[i].Size = new System.Drawing.Size(35, 13);
this.labelEquals[i].Text = "=";
this.labelEquals[i].Font = new System.Drawing.Font("Comic Sans MS", 17F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelEquals[i].ForeColor = System.Drawing.Color.Khaki;
this.Controls.AddRange(new System.Windows.Forms.Control[] { labelEquals[i] });
/*"Result" is an array of textboxes which takes the result of the multiplication from the user*/
Result[i] = new TextBox();
this.Result[i].BackColor = System.Drawing.Color.BlueViolet;
this.Result[i].Font = new System.Drawing.Font("Comic Sans MS", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Result[i].ForeColor = System.Drawing.SystemColors.Info;
this.Result[i].Location = new System.Drawing.Point(300, 163 + 55 * i);
this.Result[i].Name = "Result" + i;
this.Result[i].Size = new System.Drawing.Size(57, 37);
this.Result[i].TabIndex = i;
/*this is where the problem arises...*/
this.Result[i].Leave += new System.EventHandler(this.Result_Leave);// how do I send the value of 'i' to Result_Leave() function
/*Note - Result_Leave() is FIRED when the cursor moves away from the "Result" textbox*/
this.Controls.AddRange(new System.Windows.Forms.Control[] { Result[i] });
}
}
}
private void textBoxInput_TextChanged(object sender, EventArgs e)
{
errorProvider1.Clear();
}
private void radioButtonInstantChecking_CheckedChanged(object sender, EventArgs e)
{
if (radioButtonCheckAtLast.Checked == true && textBoxInput.Text!="")
{
buttonCheckAnswers.Enabled = true;
}
else buttonCheckAnswers.Enabled = false;
}
private void Result_Leave(object sender, EventArgs e)
{
/*Code for checking multiplication goes here*/
/*If multiplication result entered by the user is
*correct change the background colour of the corresponding textbox "Result[i] to GREEN else BLUE"
*as in buttonCheckAnswers_Click() function...
*/
}
private void textBoxInput_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
{
e.Handled = true;
}
// only allow one decimal point
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -2)
e.Handled = true;
}
private void buttonCheckAnswers_Click(object sender, EventArgs e)
{
int score=0;
bool flag=false;
for (int i = 0; i < 10; i++)
{
if (Result[i].Text == "")
{
flag = true;
break;
}
else if ((Convert.ToInt32(Result[i].Text)) != ((Convert.ToInt32(labelNumber[i].Text) * (Convert.ToInt32(labelTableOf[i].Text)))))
{
Result[i].BackColor = System.Drawing.Color.Red;
}
else
{
Result[i].BackColor = System.Drawing.Color.Green;
score += 1;
}
}
if (score == 10)
labelComments.Text = "Well done kid! Full Marks!\nYou know your table of\n"+textBoxInput.Text+" very well"+"\nScore = "+score;
else if(flag)
labelComments.Text = "Oops! \nComplete your table kid!";
else
labelComments.Text = "Oops! \nThere are errors. \nPlease revise your tables!" + "\nYour score is : " + score;
}
}
}
One quick-and-dirty way to do this is to set a value in each TextBox's Tag property. In the for loop inside buttonGo_Click, you could set Result[i].Tag = i;, then in Result_Leave you could do:
int number = (int)((sender as TextBox).Tag);

how to get the visible area of canvas in wpf

I am creating an application just like a paint in WPF, and I want to add zoom functionality to it. I am taking canvas as a parent and writable bitmap on it as child on which I draw. When the size of the canvas is small, I am drawing on writable bitmap smoothly, but when the size of the canvas is large, and zoom it, canvas size will be large, problem occur to draw on this large area. So I want to find the visible region of the canvas so that I can draw on it smoothly.
Please give me a source code to find the visible region of the canvas.
I have create this application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Interop;
namespace MapDesigner.Controls
{
class MapCanvas : Canvas
{
#region Routed Events
public static readonly RoutedEvent SelectedColorChangeEvent = EventManager.RegisterRoutedEvent(
"SelectedColorChange", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ucToolBox));
public event RoutedEventHandler SelectedColorChange
{
add { AddHandler(SelectedColorChangeEvent, value); }
remove { RemoveHandler(SelectedColorChangeEvent, value); }
}
#endregion
#region Enums
public enum Tool
{
Pencil,
FloodFill,
Eraser,
RectSelect,
Brush,
Part
}
#endregion
WriteableBitmap _wBMP;
Image _dispImg = new Image();
ScaleTransform st = new ScaleTransform();
int canvasHeight, canvasWidth;
double zoomLevel = 1;
Border brdGrid = new Border();
Color cellColor = Colors.Black;
Tool currentTool = Tool.Pencil;
int[,] array;
bool drawing = false;
bool showGrids = true;
public TextBlock tbPos;
public Tool CurrentTool
{
get
{
return currentTool;
}
set
{
currentTool = value;
}
}
public Color CellColor
{
get
{
return cellColor;
}
set
{
cellColor = value;
}
}
public bool GridsVisible
{
get
{
return showGrids;
}
set
{
showGrids = value;
}
}
public MapCanvas()
{
this.Children.Clear();
this.Children.Add(_dispImg);
//st.ScaleX = 1;
//st.ScaleY = 1;
// this.LayoutTransform = st;
}
void Refresh()
{
//canvas = new MapCanvas();
this.Children.Clear();
this.Children.Add(_dispImg);
st.ScaleX = 1;
st.ScaleY = 1;
this.Height = 0;
this.Width = 0;
zoomLevel = 1;
drawing = false;
}
public void LoadBMP(Uri bmpUri)
{
Refresh();
BitmapImage bmi = new BitmapImage(bmpUri);
_wBMP = new WriteableBitmap(bmi);
_dispImg.Source = _wBMP;
this.Height = bmi.Height;
this.Width = bmi.Width;
ShowGrids();
}
public void CreateBMP(int width, int height)
{
Refresh();
_wBMP = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
this.Height = height;
this.Width = width;
ShowGrids();
}
public void CreateNewDesign(Size mapSize)
{
Refresh();
_wBMP = new WriteableBitmap((int)mapSize.Width, (int)mapSize.Width, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
array = new int[(_wBMP.PixelHeight + 1), (_wBMP.PixelWidth + 1)];
canvasWidth = (int)mapSize.Width;
canvasHeight = (int)mapSize.Height;
this.Height = mapSize.Height;
this.Width = mapSize.Width;
ShowGrids();
}
void ShowGrids()
{
return;
double width = 1;// _tileWidth + _tileMargin;
double height = 1;// _tileHeight + _tileMargin;
double numTileToAccumulate = 16;
Polyline gridCell = new Polyline();
gridCell.Margin = new Thickness(.5);
gridCell.Stroke = Brushes.LightBlue;
gridCell.StrokeThickness = 0.1;
gridCell.Points = new PointCollection(new Point[] { new Point(0, height-0.1),
new Point(width-0.1, height-0.1), new Point(width-0.1, 0) });
VisualBrush gridLines = new VisualBrush(gridCell);
gridLines.TileMode = TileMode.Tile;
gridLines.Viewport = new Rect(0, 0, 1.0 / numTileToAccumulate, 1.0 / numTileToAccumulate);
gridLines.AlignmentX = AlignmentX.Center;
gridLines.AlignmentY = AlignmentY.Center;
VisualBrush outerVB = new VisualBrush();
Rectangle outerRect = new Rectangle();
outerRect.Width = 10.0; //can be any size
outerRect.Height = 10.0;
outerRect.Fill = gridLines;
outerVB.Visual = outerRect;
outerVB.Viewport = new Rect(0, 0,
width * numTileToAccumulate, height * numTileToAccumulate);
outerVB.ViewportUnits = BrushMappingMode.Absolute;
outerVB.TileMode = TileMode.Tile;
this.Children.Remove(brdGrid);
brdGrid = new Border();
brdGrid.Height = this.Height;
brdGrid.Width = this.Width;
brdGrid.Background = outerVB;
this.Children.Add(brdGrid);
}
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
{
base.OnMouseMove(e);
tbPos.Text = (_wBMP.PixelWidth / zoomLevel).ToString() + "," + (_wBMP.PixelHeight / zoomLevel).ToString() + " | " + Math.Ceiling((((Point)e.GetPosition(this)).X) / zoomLevel).ToString() + "," + Math.Ceiling((((Point)e.GetPosition(this)).Y / zoomLevel)).ToString();
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
int xDraw = (int)Math.Ceiling(pos.X);
int yDraw = (int)Math.Ceiling(pos.Y);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//for (int i = 0; i < zoomLevel; i++)
//{
// for (int j = 0; j < zoomLevel; j++)
// {
// _wBMP.setPixel(xDraw, yDraw, cellColor);
// _dispImg.Source = _wBMP;
// }
//}
//_wBMP.setPixel(xPos, yPos, cellColor);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void SetPixelsFromArray(int ZoomLevel)
{
for (int i = 1; i < _wBMP.PixelWidth / ZoomLevel; i++)
{
for (int j = 1; j < _wBMP.PixelHeight / ZoomLevel; j++)
{
if (array[i, j] == 1)
{
for (int k = 0; k < ZoomLevel; k++)
{
for (int l = 0; l < ZoomLevel; l++)
{
_wBMP.setPixel((int)(i * ZoomLevel + k), (int)(j * ZoomLevel + l), cellColor);
_dispImg.Source = _wBMP;
}
}
}
}
}
}
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
{
//double d= this.ActualHeight;
//Double t =(double) this.GetValue(Canvas.TopProperty);
//double i = Convert.ToDouble(top);
getScreenRect();
if (e.ChangedButton == System.Windows.Input.MouseButton.Right)
{
if (cellColor == Colors.Black)
{
cellColor = Colors.Red;
}
else
{
cellColor = Colors.Black;
}
}
else if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void getScreenRect()
{
Visual _rootVisual = HwndSource.FromVisual(this).RootVisual;
GeneralTransform transformToRoot = this.TransformToAncestor(_rootVisual);
Rect screenRect = new Rect(transformToRoot.Transform(new Point(0, 0)), transformToRoot.Transform(new Point(this.ActualWidth, this.ActualHeight)));
DependencyObject parent = VisualTreeHelper.GetParent(this);
while (parent != null)
{
Visual visual = parent as Visual;
System.Windows.Controls.Control control = parent as System.Windows.Controls.Control;
if (visual != null && control != null)
{
transformToRoot = visual.TransformToAncestor(_rootVisual);
Point pointAncestorTopLeft = transformToRoot.Transform(new Point(0, 0));
Point pointAncestorBottomRight = transformToRoot.Transform(new Point(control.ActualWidth, control.ActualHeight));
Rect ancestorRect = new Rect(pointAncestorTopLeft, pointAncestorBottomRight);
screenRect.Intersect(ancestorRect);
}
parent = VisualTreeHelper.GetParent(parent);
//}
// at this point screenRect is the bounding rectangle for the visible portion of "this" element
}
// return screenRect;
}
protected override void OnMouseWheel(System.Windows.Input.MouseWheelEventArgs e)
{
base.OnMouseWheel(e);
if (e.Delta > 0)
{
zoomLevel *= 2;
}
else
{
zoomLevel /= 2;
}
if (zoomLevel > 8)
{
zoomLevel = 8;
}
if (zoomLevel <= 1)
{
zoomLevel = 1;
// brdGrid.Visibility = Visibility.Collapsed;
}
else
{
//brdGrid.Visibility = Visibility.Visible;
}
_wBMP = new WriteableBitmap((int)zoomLevel * canvasWidth, (int)zoomLevel * canvasHeight, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
this.Width = zoomLevel * canvasWidth;
this.Height = zoomLevel * canvasHeight;
if (drawing == true)
{
SetPixelsFromArray((int)zoomLevel);
}
//this.InvalidateVisual();
}
internal bool SaveAsBMP(string fileName)
{
return true;
}
}
public static class bitmapextensions
{
public static void setPixel(this WriteableBitmap wbm, Color c)
{
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
int x = 0;
int y = 0;
for (x = 0; x < wbm.PixelWidth; x++)
{
for (y = 0; y < wbm.PixelHeight; y++)
{
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
}
}
wbm.AddDirtyRect(new Int32Rect(0, 0, x, y));
wbm.Unlock();
}
public static void setPixel(this WriteableBitmap wbm, int x, int y, Color c)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return;
if (y < 0 || x < 0)
return;
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
wbm.AddDirtyRect(new Int32Rect(x, y, 1, 1));
wbm.Unlock();
}
public static Color getPixel(this WriteableBitmap wbm, int x, int y)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return Color.FromArgb(0, 0, 0, 0);
if (y < 0 || x < 0)
return Color.FromArgb(0, 0, 0, 0);
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return Color.FromArgb(0, 0, 0, 0);
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
Color c;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
c = Color.FromArgb(pbuff[loc + 3], pbuff[loc + 2], pbuff[loc + 1], pbuff[loc]);
}
return c;
}
}
}
You should implement IScrollInfo on your canvas (or actually, create a custom Panel that inherits from Canvas and implements IScrollInfo).
That interface holds all that is relevant to your situation:
http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.iscrollinfo.aspx
http://blogs.msdn.com/b/jgoldb/archive/2008/03/08/performant-virtualized-wpf-canvas.aspx

Resources