10 Replies - 2701 Views - Last Post: 16 August 2009 - 10:09 PM Rate Topic: -----

#1 nova2108   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 01-August 09

Picture Scrolling

Posted 14 August 2009 - 07:46 PM

I've created an Network IM program that can send text and also can set your "display image" for your session. Which will also send this image to the other user connected through a socket. This work perfectly. (I've been working on it for about 2 or 3 days). The problem I have is when the photo is bigger then the screen. (If it not then the program will resize it to the photo's size and display it.) If it is bigger then it will just display the image at the default size. (Which will only show a protion of the photo) I was wondering on how to add scrolling to a PictureBox so that the photo will able to be seen completly. (I don't want to resize the photo)...Can anyone help/Point me in the right direction?

Here is the code for display the photo.
public partial class ImageDialog : Form
	{
		public ImageDialog(Image image)
		{
			InitializeComponent();
			setImage(image);
		}

		/// <summary>
		/// Sets the pictureBox Image to the parameter's Image.
		/// </summary>
		/// <param name="image">Image to be set to.</param>
		private void setImage(Image image)
		{
			pictureBox.Image = image;
			TryResizeDialog();
		}

		private void TryResizeDialog()
		{
			Image displayedImage = pictureBox.Image;
			int imageHeight = displayedImage.Height + 30;
			int imageWidth = displayedImage.Width + 20;
			Rectangle imageRec = new Rectangle(0, 0, imageWidth, imageHeight);
			Rectangle screenRec = Screen.PrimaryScreen.WorkingArea;
			if (screenRec.Contains(imageRec))
			{
				this.Height = imageHeight + 40;
				this.Width = imageWidth;
			}
			else
			{
				//Adds scrolling function because picture is bigger than the screen.
			}
			
		}

		public void CloseDialog()
		{
			this.Close();
		}
	}



Thanks in advance... :)

Is This A Good Question/Topic? 0
  • +

Replies To: Picture Scrolling

#2 RudiVisser   User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1010
  • View blog
  • Posts: 3,566
  • Joined: 05-June 09

Re: Picture Scrolling

Posted 15 August 2009 - 03:37 AM

Do you mean autoscrolling? Or where the user can drag the image around?

The latter will probably be easier.
Was This Post Helpful? 0
  • +
  • -

#3 nova2108   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 01-August 09

Re: Picture Scrolling

Posted 15 August 2009 - 11:26 AM

View PostMageUK, on 15 Aug, 2009 - 03:37 AM, said:

Do you mean autoscrolling? Or where the user can drag the image around?

The latter will probably be easier.


Well the picturebox doesnt have autoscrolling to my knowledge by default. I was thinking of manually adding two scroll bar (as needed) and when the user scrolls it the image will scroll in response. I already have the code to figure out if scrolling would be needed. I also found the components for the scrolling bars also. I just really don't know how to "move" the image in an appropriate response. Also for the scroll bar to know how much is the maximum scroll needed (or some wording like that).
Was This Post Helpful? 0
  • +
  • -

#4 RudiVisser   User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1010
  • View blog
  • Posts: 3,566
  • Joined: 05-June 09

Re: Picture Scrolling

Posted 15 August 2009 - 11:33 AM

Well for scrollbars, the solution is simple :)

Just create a panel that has AutoScroll set, stick in your PictureBox, and have the PictureBox automatically resize to the size of the image, that way, it will do everything for you and the panel will do the scrolling rather than the picturebox itself. That way you don't need to get into nasty coding :)
Was This Post Helpful? 1
  • +
  • -

#5 nova2108   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 01-August 09

Re: Picture Scrolling

Posted 15 August 2009 - 01:12 PM

View PostMageUK, on 15 Aug, 2009 - 11:33 AM, said:

Well for scrollbars, the solution is simple :)

Just create a panel that has AutoScroll set, stick in your PictureBox, and have the PictureBox automatically resize to the size of the image, that way, it will do everything for you and the panel will do the scrolling rather than the picturebox itself. That way you don't need to get into nasty coding :)


Thanks you very much, what you said worked exactly...Scroll bar appear if the image is too big to resize because it larger then the users screen.

This is so far the final code...
public partial class ImageDialog : Form
	{
		public ImageDialog(Image image)
		{
			InitializeComponent();
			setImage(image);
		}

		/// <summary>
		/// Sets the pictureBox Image to the parameter's Image.
		/// </summary>
		/// <param name="image">Image to be set to.</param>
		private void setImage(Image image)
		{
			pictureBox.Image = image;
			TryResizeDialog();
		}

		private void TryResizeDialog()
		{
			Image displayedImage = pictureBox.Image;
			int imageHeight = displayedImage.Height + 30;
			int imageWidth = displayedImage.Width + 20;
			Rectangle imageRec = new Rectangle(0, 0, imageWidth, imageHeight);
			Rectangle screenRec = Screen.PrimaryScreen.WorkingArea;
			if (screenRec.Contains(imageRec))
			{
				this.Height = imageHeight + 40;
				this.Width = imageWidth;
			}
			else
			{
				//Add scrolling function because picture is bigger then the screen.
				this.pictureBox.Width = displayedImage.Width;
				this.pictureBox.Height = displayedImage.Height;
			}
			
		}

		public void CloseDialog()
		{
			this.Close();
		}
	}


Was This Post Helpful? 0
  • +
  • -

#6 RudiVisser   User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1010
  • View blog
  • Posts: 3,566
  • Joined: 05-June 09

Re: Picture Scrolling

Posted 15 August 2009 - 01:15 PM

Glad that you got it sorted :)

Definitely easier than handling the scrollbars yourself, right? ;)
Was This Post Helpful? 0
  • +
  • -

#7 nova2108   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 01-August 09

Re: Picture Scrolling

Posted 15 August 2009 - 01:19 PM

True...I didn't have to add any code for the scrolling...And it displays the whole photo now. Now i can work on other IM features that i can try to include...(making the IM to learn more C#/.Net coding...Personal project of mine.) :)
Was This Post Helpful? 0
  • +
  • -

#8 RudiVisser   User is offline

  • .. does not guess solutions
  • member icon

Reputation: 1010
  • View blog
  • Posts: 3,566
  • Joined: 05-June 09

Re: Picture Scrolling

Posted 15 August 2009 - 01:22 PM

Glad to hear it, well, be sure to release it/show us it here once it's finished :)
Was This Post Helpful? 0
  • +
  • -

#9 nova2108   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 01-August 09

Re: Picture Scrolling

Posted 15 August 2009 - 03:24 PM

This is Version 1.0 of the NovaIM (Both Versions)...Just the .exe files...There an about form/dialog in the menu which will tell you all about how to use the program. The Server version will require you to allow it access to your network before opening the first window. The Client version will request it after you click "Start Connection".
Also the DisplayImage form has a small sizing issue sometimes when the photo is small. (Will fix it in later version.)
Please tell me about any problems you encounter if you try the programs.
(Can be used on the same computer, ***You need to know your computer name of the server computer***.)

signed,
nova2108 B)


Attached File  NovaIM__Server_Version_.zip (41.5K)
Number of downloads: 56
Attached File  NovaIM__Client_Version_.zip (41.77K)
Number of downloads: 69
Was This Post Helpful? 0
  • +
  • -

#10 nova2108   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 01-August 09

Re: Picture Scrolling

Posted 16 August 2009 - 05:05 PM

Im working on cleaning my TcpNetwork classes to be post in this form fully commented. (so they can be easily understood)
Will show them on here when both are done. (Version 1.0 of each)

signed,
nova2108 :)
Was This Post Helpful? 0
  • +
  • -

#11 nova2108   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 17
  • Joined: 01-August 09

Re: Picture Scrolling

Posted 16 August 2009 - 10:09 PM

This is both the Editions of the NovaIM's TcpNetwork classes. (TcpNetworkClient.cs and TcpNetworkServer.cs)
I'd also like to thank/acknowledge ragingben for the idea on how to convert a Image object to a string. I did have to remove the last step (to string part) but that part of my code was based of his tutorial.
ragingben tutorial

Here is the code for the Server. (File called TcpNetworkServer.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Drawing;

namespace NovaIM_Server_
{
	class TcpNetworkServer
	{
		/*
		 * TcpNetworkServer created by nova2108 (www.dreamincode.com username) ***Please if you use a method (or the whole class) Give credit.***
		 * Version 1.0
		 * Performs connection to the assoctiated TcpNetworkClient class.
		 * Allows for Unicoded text to be sent to a client computer.
		 * Allows for a display image to be set and sent to the client computer.
		 * Allows for a display image to be received from the client computer.
		 * Allows for any username (not including ones that start with "System" or "system") to be set.
		 * ^ The above is really controlled by the Form1 class.
		 * Allows for a safe disconnection from the server computer. (Tells the server to disconnect to. Prevent Errors)
		 * 
		 */

		//Private variable.
		private TcpListener server;
		private TextBox messageBox = null;
		private TcpClient clientConnection = null;
		private NetworkStream stream = null;
		private bool serverConnected = false;
		private bool isConnecting = false;
		private bool isListening = false;
		private static int bufferSize = 5000;
		private byte[] readBuffer = new byte[5000];
		private byte[] tempPictureData = new byte[1000];
		private delegate void SetTextCallback(String message);
		private int portUsed = 80;
		private Image imageDisplay = null;
		private Image clientDisplayImage = null;
		//End of Private Variables.

		//Network Commands.
		private static String closeCommand = "System: Close Connection";
		private static String pictureCommand = "System: Picture Change";

		//End of Network Commands.

		//Command Variables.
		private bool pictureData = false;
		//End Command Variables.


		/// <summary>
		/// Creates a new server listening on the default (80) port. Perferred constructor to be used.
		/// </summary>
		/// <param name="messBox">TextBox to be used to write message to.</param>
		public TcpNetworkServer(ref TextBox messBox)
		{
			server = new TcpListener(IPAddress.Any,portUsed);
			this.messageBox = messBox;
		}

		/// <summary>
		/// Creates a new server listening on a certain port.
		/// </summary>
		/// <param name="port">Port to listen on.</param>
		/// <param name="messBox">TextBox that messages will be written to.</param>
		public TcpNetworkServer(int port,ref TextBox messBox)
		{
			this.portUsed = port;
			server = new TcpListener(IPAddress.Any,portUsed);
			this.messageBox = messBox;
			try
			{
				server.Start(1);
				isListening = true;
			}
			catch (SocketException err)
			{
				MessageBox.Show("Socket Exception has Occurred! : " + err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		/// <summary>
		/// Send a message across the stream.
		/// </summary>
		/// <param name="message">Message to be sent.</param>
		public void SendMessage(String message)
		{
			byte[] buffer = Encoding.Unicode.GetBytes(message); //Convert a message to a Unicoded byte array.
			stream.Write(buffer, 0, buffer.Length); //Send it and wait till its done sending.
		}

		/// <summary>
		/// Converts an Image to a byte array holding its data.
		/// </summary>
		/// <param name="image">Image to be converted to a String.</param>
		/// <returns>String containing the Image data.</returns>
		public static byte[] imageToData(Image image)
		{
			System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
			//Create a BinaryStream to deseralize the data.
			System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter =
				new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
			//Creates and returns the Image.
			formatter.Serialize(memoryStream,image);
			return memoryStream.ToArray();
		}

		/// <summary>
		/// Converts byte array of data to an Image
		/// </summary>
		/// <param name="stringData">String variable holding Image data.</param>
		/// <returns>Return the Image from the String.</returns>
		public static Image dataToImage(byte[] data)
		{
		   //Create a MemoryStream for the data.
		   System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(data);
		   //Create a BinaryStream to deseralize the data.
		   System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = 
			   new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
		   //Creates and returns the Image.
		   Image image = (Image)formatter.Deserialize(memoryStream);
		   return image;
		}

		/// <summary>
		/// Start connecting to a Client connection.
		/// </summary>
		public void Connect()
		{
			isConnecting = true; //Set isConnecting to true.
			object state = ""; // Needed for the method below.
			if (isListening == true) //If isListening already on. Just Begain accepting Tcp Client.
			{
				server.BeginAcceptTcpClient(new AsyncCallback(connected), state); //Start Accepting Tcp Client.
			}
			else
			{
				server.Start(1); //Starts listening first.
				isListening = true; //Set isListening to true.
				server.BeginAcceptTcpClient(new AsyncCallback(connected), state); //Start Accepting Tcp Client.
			}
			addMessageToLog("System: Starting Listening For Connections!"); //Tell the user that is starting listening for client connection.
		}

		/// <summary>
		/// Close the connection.
		/// </summary>
		/// <param name="sendCommandB">bool for if a command is to be sent to the other computer. (***Always True if not from inside this class unless only listening still***)</param>
		public void CloseConnection(bool sendCommandB)
		{
			if (clientConnection != null && clientConnection.Client.Connected)
			{
				if (sendCommandB) //Check if sendCommandB is true or not.
				{
					sendCommand(closeCommand); //Send the command to the other computer.
				}
				else
				{
					addMessageToLog("System: Connection closed by other side!"); //Tell the user that the other computer closed there connection.
				}
				//Start Closing Operations.
				clientConnection.Client.Shutdown(SocketShutdown.Both); 
				stream.Close(500);
				server.Stop();
				serverConnected = false; //Set serverConnected to false.
				isListening = false; //Set isListening to false.
				//End Closing Operations.
			}
			else if (isListening == true && server != null) //The server is only listening still; no connection yet.
			{
				server.Stop(); //Stop listening for connections.
				addMessageToLog("System: Stopped Listening for Connections"); //Tell the user.
				isListening = false; //Set isListening to false.
			}
		}


		#region asynchronous_Section
		//Everything in this region is automatically run when it suppose to.

		/// <summary>
		/// Automatically runs when connection to client computer is establised.
		/// </summary>
		/// <param name="e"></param>
		private void connected(IAsyncResult e)
		{
			if (e.IsCompleted) //Check to make sure e.IsCompleted is true.
			{
				isConnecting = true; //Sets isConnecting to true.
				try
				{
					clientConnection = server.EndAcceptTcpClient(e); //Safely tries to get the TcpClient.
				}
				catch (ObjectDisposedException)
				{
					isConnecting = false; //probally Close method was run so server was disposed of.
					return; //Return.
				}
				stream = clientConnection.GetStream(); //Get the stream associated with socket.
				serverConnected = true; //Sets serverConnected to true.
				isConnecting = false; //Sets isConnecting to false.
				addMessageToLog("System: Connection Made!"); //Tell the user that a connection was established.
				stream.BeginRead(readBuffer, 0, readBuffer.Length, new AsyncCallback(receivedMessage), "done_read"); //Begain reading from the stream asynchronously.
				if (imageDisplay != null) //if imageDisplay was set. Send it.
				{
					if (serverConnected == true) //Make sure a connection was made. (For error proofing)
					{
						sendCommand(pictureCommand); //Tells the client that the next data sent will be picture data.
						byte[] data = imageToData(imageDisplay); //Converts the image to a byte array.
						stream.Write(data, 0, data.Length); //Sends it.
						addMessageToLog("System: Auto-Sent Your Display Photo"); //Tell the user.
					}
				}
			}
		}

		/// <summary>
		/// Receives the message from the Network Stream.
		/// </summary>
		/// <param name="e"></param>
		private void receivedMessage(IAsyncResult e)
		{
			try
			{
				stream.EndRead(e); //End read for now.
			}
			catch (System.IO.IOException)
			{
				addMessageToLog("System: Connection Has Been Closed!"); //Tell the user.
				CloseConnection(false); //Close connection on this end.
				return; //Return.
			}
			catch (System.ObjectDisposedException)
			{
				addMessageToLog("System: Connection Has Been Closed!"); //Tell the user.
				CloseConnection(false); //Close connection on this end.
				return; //Return.
			}

			if (pictureData == false) //If received data is not suppose to be pictureData. 
			{
				String message = Encoding.Unicode.GetString(readBuffer); //Get String from readBuffer.

				if (checkForCommand(message))//Check for a command.
				{
					performCommand(message); //Perform command.
					//return;
				}
				else
				{
					addMessageToLog(message);//String has not command so add it to the messageLog.
				}
				readBuffer = new byte[bufferSize]; //Reset readBuffer.
			}
			else
			{
				//Perform Image Conversion and Set properties.
				pictureData = false; //Reset pictureData to false so that the next message will be interpeted as text.
				//1024 bytes = 1 kilobyte. //1 Megabyte = 1048576 Bytes
				Image image = dataToImage(tempPictureData); //Get the image from tempPictureData.
				SetClientDisplayImage(image); //Set to Client's Display Image.
				tempPictureData = new byte[20]; ////Set to small value to save computer memory.
			}

			//Restart read operation.
			try
			{
				if (pictureData == false) //If picture data is not expected. 
				{
					stream.BeginRead(readBuffer, 0, readBuffer.Length, new AsyncCallback(receivedMessage), "done_read"); //Begain reading with normal buffer.
				}
				else
				{
					stream.BeginRead(tempPictureData, 0, tempPictureData.Length, new AsyncCallback(receivedMessage), "done_read"); //Begain reading with picture buffer.
				}
			}
			catch (System.IO.IOException err)
			{
				if (err.ToString().Contains("Unable to read data from the transport connection: An established connection was aborted by the software in your host machine."))
				{
					addMessageToLog("System: Connection Has Been Closed!"); //Tell User.
					CloseConnection(false); //Close connection on this end.
					return;
				}
			}
			catch (ObjectDisposedException)
			{
				addMessageToLog("System: Connection Has Been Closed!"); //Tell User.
				CloseConnection(false); //Close connection on this end.
				return;
			}
		}
		
		/// <summary>
		/// Do not use this method directly! Use "addMessageToLog" instead.
		/// </summary>
		/// <param name="text">Text to be added</param>
		private void addMessage(String text)
		{
			if (text.Contains("\n"))
			{
				this.messageBox.AppendText(text); //Append text.
			}
			else
			{
				this.messageBox.AppendText(text + "\n"); //Append text and add a linebreak.
			}
		}

		#endregion

		/// <summary>
		/// Safely adds a message to the TextBox.
		/// </summary>
		/// <param name="text">Text to be added</param>
		private void addMessageToLog(String text)
		{
			if (this.messageBox.InvokeRequired)
			{
				// It's on a different thread, so use Invoke.
				SetTextCallback d = new SetTextCallback(addMessage);
				this.messageBox.Invoke(d, new object[] { text });

			}
			else
			{
				// It's on the same thread, no need for Invoke
				addMessage(text);
			}
		}

		/// <summary>
		/// Send a command to the other computer.
		/// </summary>
		/// <param name="command">Command to be sent.</param>
		private void sendCommand(String command)
		{
			byte[] buffer = Encoding.Unicode.GetBytes(command);
			try
			{
				stream.Write(buffer, 0, buffer.Length);
			}
			catch (Exception)
			{
				addMessageToLog("Could Not Send Command");
			}
		}

		/// <summary>
		/// Checks a String for a valid command.
		/// </summary>
		/// <param name="message">Message that might contain a command.</param>
		/// <returns>Returns if a command was found or not.</returns>
		private bool checkForCommand(String message)
		{
			String mess = message.Trim().Replace("\0", "").Replace("\r", "").Replace("\n", "");
			if (mess.Equals(closeCommand))
			{
				return true;
			}else if(mess.Equals(pictureCommand))
			{
				return true;
			}

			return false;
		}

		/// <summary>
		/// Performs the action associated with a command.
		/// </summary>
		/// <param name="com">The command to perform.</param>
		private void performCommand(String com)
		{
			String command = com.Trim().Replace("\0", "").Replace("\r", "").Replace("\n", "");
			if (command.Equals(closeCommand))
			{

				CloseConnection(false);
				return;
			}
			else if (command.Equals(pictureCommand))
			{
				pictureData = true;
				tempPictureData = new byte[2097152]; //2 megabyte.
				return;
			}
		}

		/// <summary>
		/// Sets the imageDisplay. Also if server is connected will send it to the client's connection also.
		/// </summary>
		/// <param name="image">The imageDisplay to be set to.</param>
		public void SetDisplayImage(Image image)
		{
			imageDisplay = image;
			if (serverConnected == true)
			{
				sendCommand(pictureCommand); //Tells the client that the next data sent will be picture data.
				byte[] data = imageToData(image);
				stream.Write(data, 0, data.Length); //Sends it.
			}
		}

		/// <summary>
		/// Sets the client/(other computer's) display image.
		/// </summary>
		/// <param name="clientImage">Image to be set to.</param>
		private void SetClientDisplayImage(Image clientImage)
		{
			clientDisplayImage = clientImage;
			addMessageToLog("System: Client Has Changed there Display Image!");
		}

		/// <summary>
		/// Get the Client's Display Image (may return null if non set yet)
		/// </summary>
		/// <returns>Client's Display Image</returns>
		public Image GetClientDisplayImage()
		{
			return clientDisplayImage;
		}

		/// <summary>
		/// Return the imageDisplay used for user display.
		/// </summary>
		/// <returns>imageDisplay</returns>
		public Image GetDisplayImage()
		{
			return imageDisplay;
		}

		/// <summary>
		/// Is there any pending connections.
		/// </summary>
		/// <returns>Returns true or false.</returns>
		public bool IsPendingConnections()
		{
			return server.Pending();
		}

		/// <summary>
		/// Checks to see if a connection is trying to be established.
		/// </summary>
		/// <returns>Returns the bool if connection is trying to be established.</returns>
		public bool IsConnecting()
		{
			return isConnecting;
		}

		/// <summary>
		/// Checks to see if the server is listening for connections.
		/// </summary>
		/// <returns>Returns the bool if listening for connections.</returns>
		public bool IsListening()
		{
			return isListening;
		}

		/// <summary>
		/// Checks to see if the socket is connected.
		/// </summary>
		/// <returns>Returns the bool if a connection is established.</returns>
		public bool IsConnected()
		{
			return serverConnected;
		}
	}
}



If you use any part of this code (method or the whole class), please give me credit for my work. Other then that it free for anyone to use (obviously since it on the internet now :) ).

If you have any idea on how to improve my class (im think of making so you can send a video or some other data that can be sent across the socket.) Please let me know. Also if you find any errors also let me know but i have tested this code some so i hope i got alot of it already. I will post the client class soon. Thanks Everyone!

This post has been edited by nova2108: 16 August 2009 - 10:29 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1