Categories
Archived Sports Uncategorized

Calculating distance and speed manually

I’ve been doing a reasonable amount of training on the road bike lately and given that the weather here in Melbourne is temperemental at best coming into winter I decided to get another indoor wind trainer. Because I didn’t want to break the bank I didn’t buy one that shows you your speed or distance. Apart from the fact that effective training should be based off heart rate and cadence anyway (or power output if you’re REALLY serious) you’re looking at AUD$800+ for that sort of thing, money I’m not prepared to spend on a trainer at the moment.

Anyway, I still wanted to know how far I’d gone and what my average speed was so I set about figuring out how to calculate these figures given the information I do have – cadence, time, wheel size and gear sizes.

Required Info

A bit of research came up with a few different ways of calculating the distance and average speed when you know the following:

  • Wheel circumference
  • Average cadence for the training session
  • Chainring sizes (measured in number of teeth)
  • Sprocket/cassette cog sizes (measured in number of teeth)
  • Training session time

The method I found that worked best for me came from a Wikipedia page entitled Bicycle Gearing. It contains a whole load of useful information, including how to calculate what is referred to as “metres of development” i.e. the distance travelled for a single crank revolution. This, of course, is dependant on which gear you’re in. Another thing to note before carrying on is that it’s often recommended to train for certain intervals at certain levels of intensity and cadence. The only problem I can see with the calculations below is if you change gears a LOT during a trainer session you’d need to know how long you were in each gear for (in order to calculate the metres of development for each gear used). I’m not a doctor either so please be responsible and don’t train before consulting a physician if you’re not sure what you’re doing. However, carrying on …

Categories
Archived Design Non Technical Opinion Uncategorized Wordpress

Pay it forward …

For a few years now I’ve been dabbling in a bit of 3D design here and there. Purely as a hobby though and I’d never even dream of calling myself any good at it.

Anyway, I used to learn from a bunch of talented dudes over http://www.3dcaffeine.com, a site that unfortunately no longer exists (internal problems? I don’t know.) One of the members there was a Romanian guy by the name of Flavius, a very talented 3D designer with a pretty scary level of skill for someone his age, around 20 as I write this I think … no he’s not a Romanian scammer!

He’s in the unfortunate position where web hosting and all the bits that go with it are pretty hard to come by so I decided to do as the title of this post says – pay it forward. To do this I offered to pay for web hosting and domain registration for a website to be created, a site where Flavius could showcase his work, demonstrate his skills and get the word out there so that people know there are talented designers everywhere.

The site’s now live and, while it’s yet to have much content (it’s been live around an hour now but will undergoing plenty of changes over the next little while), is coming along nicely with a decent gallery to get started, backed up by a beautiful WordPress theme by Nick Roach over at Elegant Themes. Go there if you want themes – it’s the site I choose to use for all my WordPress themes.

Flavius’ new site can be found at http://flaviuscristea.com and will have more content added as time goes on. Please feel free to let me know if you find any problems there as I’ll be doing the back-end maintenance of the site even though Flavius will be maintaining the actual content.

Cool. 🙂

Categories
Archived Development Uncategorized

C# Full-screen application – Complete Source

Yesterday I posted a quick update to an article I wrote back in 2007 entitled “How to make a full-screen Windows app using VB.NET”. Aside from 1 or 2 people saying “Oh man why don’t you be a man and write it using C#?” I reckon it’s a good idea to do that anyway. Thanks Scott for the suggestion. 😉 And thanks Phil for pointing me in the right direction with the DLL import stuff. 🙂

So, without any mucking about here’s the exact same complete application example only this time in C#.

Please feel to ask any questions necessary. Thanks!

Form1’s complete source:

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.Runtime.InteropServices;

namespace Play
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        [DllImport ("user32.dll")]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndIntertAfter, int X, int Y, int cx, int cy, int uFlags);
        [DllImport("user32.dll")]
        private static extern int GetSystemMetrics(int Which);

        private const int SM_CXSCREEN = 0;
        private const int SM_CYSCREEN = 1;
        private IntPtr HWND_TOP = IntPtr.Zero;
        private const int SWP_SHOWWINDOW = 64;

        public int ScreenX
        {
            get
            {
                return GetSystemMetrics(SM_CXSCREEN);
            }
        }

        public int ScreenY
        {
            get
            {
                return GetSystemMetrics(SM_CYSCREEN);
            }
        }

        private void FullScreen()
        {
            this.WindowState = FormWindowState.Maximized;
            this.FormBorderStyle = FormBorderStyle.None;
            this.TopMost = true;
            SetWindowPos(this.Handle, HWND_TOP, 0, 0, ScreenX, ScreenY, SWP_SHOWWINDOW);
        }

        private void Restore()
        {
            this.WindowState = FormWindowState.Normal;
            this.FormBorderStyle = FormBorderStyle.SizableToolWindow;
            this.TopMost = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FullScreen();
        }

        private void cmdRestore_Click(object sender, EventArgs e)
        {
            Restore();
        }

        private void cmdExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}
Categories
Archived Development Uncategorized

VB.NET – List active directory users – Re-write

Please note: This is a rewrite of an article I wrote way back in 2007. The original article has been updated with a link to this one.

As per usual I had a situation where I had to do some Active Directory stuff with VB.NET. I had to grab a list of all the users in our AD so that people could select a user and perform functions on them from within a webpage.
Another note: This article is VB.NET-specific. If you’d like to know how to do this using C# please see this post’s “partner” entitled “Follow Up – List active directory users – This time in C#”

Carrying on though, there are a number of ways you can do this but in the .NET Framework they all involve using the System.DirectoryServices namespace. A couple of quick things to be aware of before you try this yourself:

  • Before messing with your Active Directory make sure you know what you’re doing and have the permissions of your AD Administrators (if it’s not you!)
  • If you are going to use any of the following code from a .NET console application you’ll need to add a reference to System.DirectoryServices in addition to importing the namespace. I wrote a post a while ago about this entitled “Developer Dumbness” – it has the steps you need to add a reference to a .NET console application.

Anyway, the code below is a simple function that queries your Active Directory domain and retrieves all the user objects. This particular example filters out any user account whose “DisplayName” attribute meets the following criteria (the requirements for the app I had to write):

  • Has an email address
  • Does not contain the “$” symbol
  • Does not contain the words “Admin” or “admin”
  • Does not contain the words “Test” or “test”
  • Does not contain the words “Service” or “service”
  • Does not contain the word “System” or “system”

The example code below is a complete Windows console application that does all of the above. It’s important to note that if you’re using this in a production environment you’ll need to make sure the application containing the code has access to the Active Directory, usually using .NET impersonation – this is beyond the scope of this post.

List Active Directory Users in VB.NET:

Imports System
Imports System.Collections.Generic
Imports System.DirectoryServices

Module ListAdUsers

    Sub Main(ByVal ParamArray Args() As String)

        Console.Clear()
        Dim userList As List(Of String) = New List(Of String)

        Dim badEntries As Integer = 0
        Dim domainName As String = String.Empty

        If (Args.Length > 0) Then
            domainName = Args(0)
        Else
            Console.Write(String.Format("{0}Please enter your Active Directory domain name: ", vbCrLf))
            domainName = Console.ReadLine()
        End If

        Console.Write(String.Format("{0}Attempting to build user list for {1} ...{0}{0}", vbCrLf, domainName))

        Try
            If Not String.IsNullOrEmpty(domainName) Then
                Dim myDirectoryEntry As DirectoryEntry = New DirectoryEntry(String.Format("LDAP://{0}", domainName))
                Dim mySearcher As DirectorySearcher = New DirectorySearcher(myDirectoryEntry)
                Dim mySort As SortOption = New SortOption("sn", SortDirection.Ascending)
                mySearcher.Filter = ("(objectClass=user)")
                mySearcher.Sort = mySort
                For Each resEnt As SearchResult In mySearcher.FindAll()
                    Try
                        If Not String.IsNullOrEmpty(resEnt.Properties("Mail")(0).ToString()) _
                            AndAlso System.Text.RegularExpressions.Regex.IsMatch(resEnt.Properties("DisplayName")(0).ToString(), " |admin|test|service|system|[$]", System.Text.RegularExpressions.RegexOptions.IgnoreCase) Then
                            Dim space As Integer = resEnt.Properties("DisplayName")(0).ToString().IndexOf(" ")
                            Dim formattedName As String = String.Format("{0}{1}{2}", _
                                                                        resEnt.Properties("DisplayName")(0).ToString().Substring(space).PadRight(25), _
                                                                        resEnt.Properties("DisplayName")(0).ToString().Substring(0, space).PadRight(15), _
                                                                        resEnt.Properties("Mail")(0).ToString() _
                                                                        )
                            userList.Add(formattedName)
                        End If
                    Catch
                        badEntries = badEntries + 1
                    End Try
                Next
                If (userList.Count > 0) Then
                    Console.WriteLine(String.Format("=========== Listing of users in the {0} domain{1}", domainName, vbCrLf))
                    Console.WriteLine(String.Format("{0}{1}{2}{3}", "Surname".PadRight(25), "First Name".PadRight(15), "Email Address", vbCrLf))
                    For i = 0 To userList.Count - 1
                        Console.WriteLine(userList(i).ToString())
                    Next
                    Console.WriteLine(String.Format("{0}=========== {1} users found in the {2} domain", vbCrLf, userList.Count.ToString(), domainName))
                Else
                    Console.WriteLine(String.Format("{0}=========== 0 users found in the {1} domain", vbCrLf, userList.Count.ToString()))
                End If
                Console.WriteLine(String.Format("=========== {0} objects could not be read", badEntries.ToString()))
                Console.WriteLine("=========== End of Listing")
            Else
                Console.WriteLine("Please enter a domain name next time!")
            End If
        Catch ex As Exception
            ' in a production app you wouldn't show the user the exception details
            Console.Write(String.Format("A critical error occurred.{0}Details: {1}", vbCrLf, ex.Message.ToString()))
        End Try
    End Sub

End Module

There are a HEAP of attributes you can use instead of “sn” in the sample above. Personally I use ADSIEDIT.MSC to look at all the possible attributes but you’ll need domain administrative access to run that. Here are a couple of useful ones though …

  • company
  • department
  • description
  • displayName
  • mail
  • manager
  • name
  • givenName
  • sAMAccountName

Hope that helps someone! 🙂

Categories
Archived Development Uncategorized

List active directory users – C#

In this article I’m going to carry on with the follow-ups to posts I wrote in the past about various topics. Today’s topic is still on the subject of using .NET to list the users in Active Directory although this time we’re going to do it in C#. I wrote the first post and sample application using VB.NET back when I (perhaps) didn’t know as much as I know now … hopefully y’all won’t be too harsh on my n00b code from back then. 🙂

So, what’s different? Apart from the language change here is a summary of what’s changed between this version and the original.

  • All references that aren’t needed have been removed.
  • The results are now added to a generic list of strings (the original was just an ArrayList).
  • The domain name can now be passed as a parameter on the command line. If one isn’t provided the user will be prompted.
  • Regular expressions are now used to filter out user accounts that don’t match certain criteria (the original did some horribly repetitive case-sensitive matching).
  • The output is now formatted better (the original was just a plain list).
  • The account’s email address is now shown too.
  • A total count of the accounts that can’t be ‘read’ is shown at the end.
  • The app’s exception handling is a whole heap better (the original, being a sample, didn’t have any).
  • The app won’t run if a domain name isn’t provided at all – an error message is displayed.

Note that this version doesn’t do any validation of the domain name e.g. length, illegal characters etc although you could use regular expressions to validate it.

On the next page is the entire source for the application – it’s a single .cs file.

Categories
Archived Development Uncategorized

C# – Self updating application …

Disclaimer: I wrote this code way back in 2007 and I reckon I’ve learnt a fair bit since then (not being a professional developer).  Go easy on me if you feel like commenting on the code itself.  🙂

This one might be interesting for people who have wondered about how to distribute the latest version of their application without having to tell people when an update is released.

There are built-in options that you can use with the Microsoft .NET platform such as ClickOnce. We use ClickOnce here at Trade Me to deploy some of our in-house applications and it works really well.

Recently, though, I thought “Why not see if I can write my own method of updating my application?” It turned out to be quite an interesting litte project! The application I was working on at the time is written in C# although the learning curve to go from VB.NET to C# or vice-versa isn’t too steep.

Where do we start?

To begin with I decided the update process should have the following steps.

  • Check my website for a text file containing version information.
  • Read the version information text file and compare the version information in it to the version of the application currently running.
  • If the version in the text file is the same or less than the version currently being run, do nothing other than show a message to the user.
  • If the version in the text file is greater than the version currently being run ask the user if they want to update to the later version.
  • Do the actual update.

Components

There are 2 components to this particular solution. The first part is the actual application being updated and the updater application. If you are going to follow along with any of the stuff in this article you’ll need to start a new solution with 2 projects. My main project is called “CountDown” and the updater application is called “AppStart” (for reasons not related to the updating stuff here). For the purposes of this article I’m going to assume you have a single project that needs the update functionality.

The main application

The first thing your main application will need to do is make use of the System.Net namespace by adding the following line to the top of the main namespace file.

Namespaces:

using System.Net;

When the user runs the application they can click a button that runs a method to do most of the steps above. The first thing the method does is try to resolve the IP address of my website (http://www.digitalformula.net resolves to 203.194.159.161).

Resolve IP Address:

try
{
  string RemoteDomain = "http://www.digitalformula.net";
  IPHostEntry inetServer = Dns.GetHostEntry(RemoteDomain.Replace("http://", String.Empty));
}
catch (Exception ex)
{
...
}
Categories
Archived Development Uncategorized

Full-screen Windows app using VB.NET

Recently I had to write a Windows application that required the main form to run in full-screen mode. This means no title bar and with the window appearance above everything else, i.e. Start Button, taskbar, system tray and all other apps.

This requires an API call to the SetWindowPos function which you need to create an alias to before you can call it. The first part of the code, which should be placed in the declarations part of the form, looks like this :

SetWindowsPos alias:

Private Declare Function SetWindowPos Lib "user32.dll" Alias "SetWindowPos" (ByVal hWnd As IntPtr, ByVal hWndIntertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean

You also need an alias to the API function called GetSystemMetrics, like this :

VB.NET – GetSystemMetrics alias:

Private Declare Function GetSystemMetrics Lib "user32.dll" Alias "GetSystemMetrics" (ByVal Which As Integer) As Integer
[/pre]

<p>
Following this you need to declare 4 constants :
</p>

Required constants:

Private Const SM_CXSCREEN As Integer = 0
Private Const SM_CYSCREEN As Integer = 1
Private Shared HWND_TOP As IntPtr = IntPtr.Zero
Private Const SWP_SHOWWINDOW As Integer = 64

Then 2 public properties :

Required property #1:

Public ReadOnly Property ScreenX() As Integer
    Get
        Return GetSystemMetrics(SM_CXSCREEN)
    End Get
End Property

-- and --

Required property #2:

Public ReadOnly Property ScreenY() As Integer
    Get
        Return GetSystemMetrics(SM_CYSCREEN)
    End Get
End Property

After this you need to write a simple sub routine to use the constants you declared above and that calls the SetWindowPos API function. The function's code looks like this :

The FullScreen() method:

Private Sub FullScreen()
    Me.WindowState = FormWindowState.Maximized
    Me.FormBorderStyle = FormBorderStyle.None
    Me.TopMost = True
    SetWindowPos(Me.Handle, HWND_TOP, 0, 0, ScreenX, ScreenY, SWP_SHOWWINDOW)
End Sub

Beyond that it's just a case of calling the FullScreen sub routine whenever you want the application to show in full-screen mode. Easy huh? 🙂