08 October 2014

WPF - Use a System.Drawing.Image as ImageSource

I had a System.Drawing.Image thumbnail that I wanted to use as the ImageSource of an Image element in WPF. The following code – compiled with some help – did the trick:
using draw = System.Drawing;
...
draw.Image thumb = Browser.WebView.Capture(false); //The original image.

using (MemoryStream stream = new MemoryStream()) {
  thumb.Save(stream, draw.Imaging.ImageFormat.Bmp);
  stream.Position = 0;
  stream.Seek(0, SeekOrigin.Begin);
  BitmapImage bi = new BitmapImage();
  bi.BeginInit();
  bi.StreamSource = stream;
  bi.CacheOption = BitmapCacheOption.OnLoad;
  bi.EndInit();
  Thumbnail.Source = bi; //The image element.
  thumb.Dispose();
}

06 October 2014

.net - Discretely perform a mouse click

For an application I needed to perform a mouse click on a control in a way the user wouldn't even notice it. This was achieved as follows:

First the following Windows functions need to be imported. I've put these in a static class called "OS".

[StructLayout(LayoutKind.Sequential)]
public struct Win32Point {
  public Int32 X;
  public Int32 Y;
};

[DllImport("user32.dll")]
public static extern bool GetCursorPos(ref Win32Point pt);

[DllImport("user32.dll")]
public static extern bool SetCursorPos(int x, int y);

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);

The control in question is hidden. On it's load event this takes place:

OS.Win32Point pos = new OS.Win32Point();
OS.GetCursorPos(ref pos); //Gets the current mouse position.

int x = ((int)Left + (int)Width) - 220;
int y = ((int)Top + (int)Height) - 35;
OS.SetCursorPos(x, y); //Moves the mouse the where I need my click.

Browser.Visibility = Visibility.Visible; //Makes the control visible.
OS.mouse_event(0x02 | 0x04, 0, 0, 0, 0); //Performs the click.

Task.Run(async delegate { //Introduces a short delay to avoid that the mouse moves back before the click occures.
  await Task.Delay(100); //.net framework 4.5 is needed to delay it like this.
  OS.SetCursorPos(pos.X, pos.Y); //Moves the mouse back to it's original position.
});

23 July 2014

Math - Extract the RGB values from a long color

This is a short little peace of code to extract the RGB components of a color stored in a single long value – like they are in Visual Basic. This code is in Apple's Swift language, but that really doesn't matter. You just need to know it's an extension on the Int type and "self" refers to the variable containing the long color.
extension Int {
  func toColor() -> UIColor {
    let r = self % 256
    let g = ((self - r) % 65536) / 256
    let b = (self - g) / 65536
    return UIColor(red: Float(r), green: Float(g), blue: Float(b), alpha: 1)
  }
}

08 July 2014

C# - Bits to connect to a database

The following are the basic methods to retrieve data from and store data in a database using C#.

The connection string

In a web application, we pick this up in the web.config as follows:
private static string ConnectionString {
  get {
    var cs = ConfigurationManager.ConnectionStrings["ConnStrConsult"];
    if (cs != null)
      return cs.ConnectionString;
    else
      throw new Exception("Connection string not found.");
  }
}

Retrieve data

This method takes an SQL SELECT statement and an optional number of parameters that are used in this statement. Also see LINQ on datatable for further processing of the retrieved data and Retrieve objects to retrieve an IEnumerable of model objects instead.
private static DataTable Retrieve(string query, params object[] parameters) {
  try {
    var data = new DataTable();
    using (var adapter = new OdbcDataAdapter(query, ConnectionString)) {
      SetParameters(adapter.SelectCommand, parameters);
      adapter.Fill(data);
    }
    return data;
  }
  catch (OdbcException ex) {
    if (ex.Message.Contains("database not found"))
      throw new Exception("Could not find database.");
    else
      throw;
  }
}

private static void SetParameters(OdbcCommand command, params object[] parameters) {
  if (command != null && parameters != null && parameters.Length > 0) {
    int i = 0;
    while (i < parameters.Length) {
      command.Parameters.AddWithValue("p" + i, parameters[i] ?? DBNull.Value);
      i++;
    }
  }
}

Execute statements

This one takes an INSERT, UPDATE or DELETE statement with optional parameters and executes it on the database.
private static object Execute(string query, params object[] parameters) {
  using (var connection = new OdbcConnection(ConnectionString))
  using (var command = new OdbcCommand(query, connection)) {
    SetParameters(command, parameters);
    connection.Open();
    return command.ExecuteScalar();
  }
}

02 June 2014

Windows XP - Cannot validate SSL TCP connection

While I was working on my email client in .net, using a TcpClient, I tested it on a computer that ran Windows XP SP2, and it failed to connect to the IMAP servers. It always returned the error The remote certificate is invalid according to the validation procedure. It worked fine on a Windows 7 laptop.

It turned out that the certificate could not be validated on an XP SP2 machine because it doesn't have the updated cryptography API called Cryptography Next Generation or CNG.

The only solution for me was to update to XP SP3. Once installed, I ran the email client again and it all worked perfectly.

22 May 2014

C# - Asynchronious methods with a callback

I thought this one up as a nice alternative to custom events: a method that does it's work asynchroniously and that invokes a callback method when it's done.

The method

public void GetMailBoxes(Action<Exception, List<MailBox>> method) {
  BackgroundWorker worker = new BackgroundWorker();
  worker.DoWork += (object sender, DoWorkEventArgs e) => {
    e.Result = Imap.Instance.GetMailBoxes();
  };
  worker.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs e) => {
    method(e.Error, mMailBoxes);
  };
  worker.RunWorkerAsync();
}

Calling the method

account.GetMailBoxes((Exception ex, List mailBoxes) => {
  if (ex != null) {
    Program.Handle(ex);
  }
  else {
    lstMailBoxes.DataSource = mailBoxes;
  }
});

05 May 2014

IMAP - Retrieving data from a mail box

IMAP is a protocol for a client to manage a mail box on a server. The following .net code connects to a mail server through IMAP and retrieves data from it:

Connect

This opens a secured TCP connection to the server.
StringBuilder result = new StringBuilder();
TcpClient connection = new TcpClient("imap.telenet.be", 993);
SslStream stream = new SslStream(connection.GetStream(), false);
stream.AuthenticateAsClient("imap.telenet.be");
StreamWriter writer = new StreamWriter(stream);
StreamReader reader = new StreamReader(stream);
result.AppendLine(reader.ReadLine());

Login

This logs you in. Always flush the command to actualy send it. All commands are sent in this fashion. Notice how each command starts with a different tag to identify it. These are usually generated with an auto-increment.
writer.WriteLine(@"e001 LOGIN myemail@telenet.be mypassword");
writer.Flush();
CheckResponseOk("Login");

CheckResponseOk

This function retrieves the response on a command and checks whether it is possitive. This is for commands that don't return data, like connect and login. These return "OK" if they succeed.
private void CheckResponseOk(string context) {
  string[] response = GetResponse();
  if (!response.Last().Contains("OK"))
    throw new ApplicationException(context + " failed:\n" + string.Join("\n", response));
}

GetResponse

This function retrieves the response on a command. A response can be multiple lines. The last line always starts with the tag that was sent in the command.
private string[] GetResponse(int logLines = -1) {
  List result = new List();
  string tag = GetTag(false);
  string line = mReader.ReadLine();
  int loggedLines = 0;

  while (!line.StartsWith(tag)) {
    result.Add(line);
    if (logLines < 0 || loggedLines < logLines) {
      mLogWriter.WriteLine(line);
      loggedLines++;
    }
    line = mReader.ReadLine();
  }

  result.Add(line);
  if (logLines < 0 || loggedLines < logLines) {
    mLogWriter.WriteLine(line);
    loggedLines++;
  }
  return result.ToArray();
}

Other commands

  • e002 SELECT INBOX selects the INBOX mail box.
  • e003 SEARCH ALL retrieves all of the mail ID's. It's also possible to pass a query.
  • e004 FETCH 1:10 (RFC822.SIZE ENVELOPE FLAGS) retrieves the size, envelope and flags of mail ID 1 through 10.
  • e005 FETCH 1 BODY[TEXT] retrieves the body of mail ID 1.
  • e006 CLOSE closes the selected mail box.
  • e007 LOGOUT logs you off again.

Disconnect

writer.Close();
reader.Close();
stream.Close();
connection.Close();

10 March 2014

MVC - Resize an image

It turns out there is a helper class in the System.Web namespace for treating images. This class, WebImage, makes things like resizing e.g. a user profile picture when it is uploaded very easy:
public void FormatPicture(HttpPostedFileBase file) {
  WebImage image = new WebImage(file.InputStream);
  if (image.Width > 85 || image.Height > 85) {
    int w = image.Width;
    int h = image.Height;
    if (w > h) {
      w = 85;
      h = image.Height * w / image.Width;
    }
    else {
      h = 85;
      w = image.Width * h / image.Height;
    }
    image.Resize(w, h);
  }
  image.Save(PictureFilepath);
}
The HttpPostedFileBase file comes from the view model and contains the uploaded image from the file control. In this example the image is resized to a maximum of 85 pixels, with the smaller dimension interpolated, and stored.

MVC - Download a file from an action

It is often usefull for files to be downloaded through code, and not directly. In the case of MVC, the download would go via an action. In the following example I download a users profile picture that way, while the actual file is not accessible directly:
[Authorize]
public ActionResult Picture() {
  if (App.GetCurrentUser().HasPicture) { //Finds out if the current user has a picture in App_Data/UserPictures.
    io.FileStream stream = io.File.OpenRead(App.GetCurrentUser().PictureFilepath);
    byte[] data = new byte[stream.Length];
    stream.Read(data, 0, data.Length);
    stream.Close();
    stream.Dispose();
    return File(data, MediaTypeNames.Application.Octet, App.GetCurrentUser() + ".jpg");
  }
  else {
    return null;
  }
}
The file is read into memory and the streamed back as an action result of type File. This principle also allows for files to be generated on the fly without them ever being stored on disc.

06 February 2014

MVC - Multiple submit buttons with distinct actions

In standard MVC, a view (page) can only have one action. You retrieve (GET) the view and submit it (POST). Therefore only one POST-action can be triggered, and if you want multiple buttons in a single view you need to dive into the form values to differentiate between them and use a switch or something inside the POST-action.

It turns out there is a way to have multiple submit buttons that each trigger a distinct action though. You can put an attribute on the two POST-actions that lets MVC pick the right one depending on which button you clicked. It is important to know though that you can't have the standard submit action you would normally have:

[HttpPost]
public ActionResult Index() {
}
Remove this action if you have it. It will cause a conflict between this standard action and the one for the submit button.

The attribute

First you need to create the following attribute class. I called it Submit:
public class SubmitAttribute : ActionNameSelectorAttribute {
  public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
    if (actionName == methodInfo.Name)
      return true;
    else
      return controllerContext.RequestContext.HttpContext.Request[methodInfo.Name] != null;
  }
}

The actions

Second, create the actions for - in this example - two submit buttons:
[Submit]
[HttpPost]
public ActionResult SaveProjectFilter(ProjectModel model) {
}

[Submit]
[HttpPost]
public ActionResult DeleteProjectFilter(ProjectModel model) {
}
Notice I decorated both actions with my Submit attribute.

The buttons

Third, put these two submit buttons in the view:
<input type="submit" name="SaveProjectFilter" value="@Dictionary.Get("Save")" class="icon-save" />
<input type="submit" name="DeleteProjectFilter" value="@Dictionary.Get("Delete")" class="icon-delete" />
Notice how the buttons' names match their respective actions. This is the key to the whole thing!

This is actually it. If you click any of the two buttons the proper action will execute.