Jun
24
2008

C#: Finding Hours/Minutes from a Click Position



Posted in Programming

This took a while to get working, but I got there eventually. It's used in OnTime to calculate the number of hours and minutes a user has clicked on. I have rows of horizontal lines which show hours. It's easy to extract a time from a click position, but generally people don't need that much precision and unless the grid is quite large (bigger than 1440 pixels), you won't have 1px per minute anyway.

This snippet will find the nearsest 30 minute interval, so if a user clicks ⅓ of the way between the 4th and 5th division, this would round to 4 hours and 30 minutes.

  double clickPosition = ((double)e.Y + -this.AutoScrollPosition.Y) / heightPerHour;
  int hours = (int)clickPosition;
  int mins = (int)((clickPosition - (double)hours) * 60);
  int roundedMinutes = (int)Math.Round((double)mins / 30, 0) * 30;
  double fractionalHours = hours + (double)(roundedMinutes / 60.0);

This is designed for a control which autoscrolls, so the actual position of the click is determined first. heightPerHour is the height of each row (each hour).

Jun
9
2008

Twitter status in your PHPBB profile



Posted in Programming

I thought it would be nifty to show my last Twitter update as a profile field next to all of my posts in the Lime49 forums. It took a bit longer than expected, but eventually I got it working. These instructions are specific to Dreamhost, but you could change the slightly to work on other hosts.

  1. You need to change your PHPBB template to include the status next to post matching a certain criteria. I'm the only administrator on the forum, so I set a template flag which is set for administrators, but no-one else.

  2. Open viewtopic.php and add the template switch will determine whether the field will be shown. I used my User ID so it wouldn’t be shown for anyone else, but you could use another variable from PHPBB.

    Find the section:

      'S_CUSTOM_FIELDS' => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false,
      'S_TOPIC_POSTER'  => ($topic_data['topic_poster'] == $poster_id) ? true : false,
     
      'S_IGNORE_POST'   => ($row['hide_post']) ? true : false,
      'L_IGNORE_POST'   => ($row['hide_post']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), '<a href="' . $viewtopic_url . "&amp;p={$row['post_id']}&amp;view=show#p{$row['post_id']}" . '">', '</a>') : '',

    And at the end add:

      'POSTER_ADMIN'  =>  ($poster_id == 2),
  3. Now open stylename\template\viewtopic_body.html and add the following to the top:

      <!-- PHP -->
      $twitterStatus = file_get_contents('/home/hjennerway/lime49.com/forums/twitter.php');
      <!-- ENDPHP -->
  4. Still in viewtopic_body.html, add this to the profile section (where the status message will be shown).:

      <!-- IF postrow.POSTER_ADMIN -->
        <br />
        <dd><strong>Currently:</strong> 
          <span class="twitter"><!-- PHP -->echo $twitterStatus;<!-- ENDPHP --></span>
        </dd>
      <!-- ENDIF -->
  5. Log in to the admin panel and purge the cache.

  6. By default, PHP is not enabled in templates. You can enable it in the Security Settings section on the General tab.

  7. Now you need a cronjob to connect to twitter, parse your last update and write it to a file. Create a new php file and modify this script to point to your PHPBB installation. Save it as twittercron.php

  8. Add a line to crontab to run the script every six hours (or more, depending on how often you update your status). You'll need to change the path to the location where PHP is installed, which you can using which php.

      * */6 * * * php5.cgi /path/to/twittercron.php 1>&2 &>/dev/null

This code saves your twitter status to a file every six hours. Them stores the contents of the file in a variable, which is shown in the template.

May
30
2008

C#: Centering a ToolStripLabel



Posted in Programming

If you have a toolstrip for navigation, you might want to have buttons on the left and the right, and a label in the centre. There’s no way to stretch the label automatically, but this snippet will resize the label to fill the rest of the ToolStrip. The only requirement is that all of the buttons are the same width.

private void CenteredLabel_Resize() {
    int remainingWidth = 144 + btnPrevSkip.Bounds.Left + 2;
    lblCenteredLabel.Width = toolStrip1.ClientSize.Width - remainingWidth;
}

You need to replace 144 with the total width of all of the other items on the ToolStrip.

May
17
2008

Repeated MouseHover events in C#



Posted in Programming

Due to a quirk in the way Windows handles events, once a mouse hover event has been triggered on a windows form control, another event cannot be triggered until the mouse leaves and re-enters the control. Sometimes you might need to process more than one MouseHover event, for example if you have a user control which has draws shapes on itself. As long as you have a record of where the shapes are (by storing them in a collection), you can use the method below as a workaround.

I used this to display a tooltip, so to prevent the MouseHover event being spammed, action is only taken when my tooltip is not visible.

private const uint TME_HOVER = 0x00000001;
private const uint TME_LEAVE = 0x00000002;
private const uint HOVER_DEFAULT = 0xFFFFFFFF;
 
[DllImport("user32.dll")]
public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);
 
public struct TRACKMOUSEEVENT {
    public uint cbSize;
    public uint dwFlags;
    public IntPtr hwndTrack;
    public uint dwHoverTime;
}
 
ToolTip toolTip = new ToolTip();
toolTip.Location = new System.Drawing.Point(290, 80);
 
Rectangle currentActiveShape = new Rectangle(); // the currently active shape (over which the mouse is hovering)
 
this.MouseMove += delegate(object sender, MouseEventArgs e) {
    foreach(Rectangle rect in myShapeCollection) {
        if(rect.Contains(e.Location)) {
            if(currentActiveDay != day.Bounds) {
                toolTip.Hide();
                Console.WriteLine("Hide tooltip");
            }
            currentActiveShape = rect;
            // Set location here
            Console.WriteLine("Entered " + rect.ToString());
        }
    }
};
this.MouseHover += delegate(object sender, EventArgs e) {
    TRACKMOUSEEVENT trackMouseEvent = new TRACKMOUSEEVENT();
    trackMouseEvent.hwndTrack = ((Control)sender).Handle;
    trackMouseEvent.dwFlags = TME_HOVER;
    trackMouseEvent.dwHoverTime = HOVER_DEFAULT;
    trackMouseEvent.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(trackMouseEvent);
    TrackMouseEvent(ref trackMouseEvent);
 
    if(!toolTip.Active) {
        toolTip.Show();
        Console.WriteLine("Show tooltip");
    }
};

As the mouse moves around the control, the location of the tooltip changes, but it’s not shown until the MouseHover event is triggerd.

Due to a quirk in the way Windows handles events, once a mouse hover event has been triggered on a windows form control, another event cannot be triggered until the mouse leaves and re-enters the control. Sometimes you might need to process more than one MouseHover event, for example if you have a user control which has draws shapes on itself. As long as you have a record of where the shapes are (by storing them in a collection), you can use the method below as a workaround.

May
8
2008

Java: JTextField Background Image



Posted in Programming

This snippet will create a JTextBox and draw an image on the right hand side. It also sets the margin accordingly to prevent the user typing into that area.

JTextField myTextField = new JTextField(20) {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
	try {
            URL url = this.getClass().getResource("image.png");
            final java.awt.image.BufferedImage image = javax.imageio.ImageIO.read(url);
            Border border = UIManager.getBorder("TextField.border");
            JTextField defaultField = new JTextField();
            final int x = getWidth() - border.getBorderInsets(defaultField).right - image.getWidth();
            setMargin(new Insets(2, 2, 2, getWidth() - x));
            int y = (getHeight() - image.getHeight())/2;
            g.drawImage(image, x, y, this);
        } catch(Exception ignore) {}
    }
};
Apr
21
2008

Creating Good Looking 16×16 Icons



Posted in Programming

If you’re creating an icon for an application or a website, getting it to look good at 16×16 can be difficult. I spent a few hours getting it right yesterday, so here’s a guide to get you started.

Good Looking 16×16 Icons

Mar
26
2008

Priority Queue in C#



Posted in Programming

A priority queue is like a standard queue, but instead of dequeuing items on a first-in-first-out basis, items are instead served by priority. There are lots of implementations of a priority queue, but none I could find which let the user re-order items. The following class functions just like a regular queue, but can also change the order of items in the queue by their index.

The queue is designed to be used with a ListView set to details mode, but could be adapted for use elsewhere. Using it with a ListView makes sense since the first item in the queue (the next to be executed) is always at index 0, and the indexing for a ListView also starts at 0.

Read more »

Mar
23
2008

Retrieving Shell Icons in C#



Posted in Programming

Ever needed to retrieve the shell icon for a particular file type in C#? This class will retrieve the Icon associated with a file from just the extension.

using System;
using System.Runtime.InteropServices;
using System.Drawing;
 
namespace Lime49.Utils {
    /// <summary>
    /// Retrievs shell info associated with a file or filetype
    /// </summary>
    /// <summary>
    /// Get a 32x32 or 16x16 System.Drawing.Icon depending on which function you call
    /// either GetSmallIcon(string fileName) or GetLargeIcon(string fileName)
    /// </summary>
    public class ShellIcon {
        [StructLayout(LayoutKind.Sequential)]
        public struct SHFILEINFO {
            public IntPtr hIcon;
            public IntPtr iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        };
        class Win32 {
            public const uint SHGFI_ICON = 0x100;
            public const uint SHGFI_LARGEICON = 0x0; // Large icon
            public const uint SHGFI_SMALLICON = 0x1; // Small icon
            public const uint USEFILEATTRIBUTES = 0x000000010; // when the full path isn't available
            [DllImport("shell32.dll")]
            public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
            [DllImport("User32.dll")]
            public static extern int DestroyIcon(IntPtr hIcon);
        }
	...

Read more »

Feb
15
2008

Java: Word Wrap for JLabels



Posted in Programming

Why couldn't Sun have made JLabels automatically wrap when they're too wide to fit the container they're in? I'd been trying to get a custom component to automatically wrap for hours, then someone suggested a JTextPane in IRC. You can style the pane to look like a JLabel, and it automatically wraps.

JTextPane txtMyTextPane= new JTextPane();
            txtMyTextPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas aliquam sem et nunc vulputate aliquet. Duis sollicitudin. Vestibulum sit amet lacus a risus egestas nonummy. Donec eu odio id felis auctor lobortis. Cras id nisl vitae pede lacinia elementum. Suspendisse convallis leo. Donec elit. Quisque id mi tincidunt quam tristique posuere.");
            txtMyTextPane.setBackground(null);
            txtMyTextPane.setEditable(false);
            txtMyTextPane.setBorder(null);
Feb
8
2008

Java: Close a JFrame with Escape



Posted in Programming

This will close a JFrame when the escape key is pressed. The actionPerformed method can do be used to call another method or to close the frame which called it.

KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
Action escapeAction = new AbstractAction() {
    // close the frame when the user presses escape
    public void actionPerformed(ActionEvent e) {
        myFrame.dispose();
    }
}; 
myFrame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "ESCAPE");
myFrame.getRootPane().getActionMap().put("ESCAPE", escapeAction);


Page 4 of 29« First...«23456»1020...Last »