火曜日, 6月 21, 2011

iPad Safari's Arabic/Persian scripts drawing bug

Safari on iPad has a bug -- does not draw Arabic/Persian scripts right when font tag is in between.



It should look like the bottom but looks like the top, the supposed connected form of the letter appear in an independent form.

Firefox either on the Ubuntu platform or the Windows seems to draw it correctly.

水曜日, 6月 08, 2011

DataGridView: 初期値を指定する

DataGridView を使うと、テーブル形式でデータを扱うことができます。

それぞれのコラムで、値を限定し、ドロップダウンリストで選択できるようにすることもできます。

ただし、この場合には、値に制限がつくことになるので、つねに決められた値を設定してやる必要があります。

つまり、新規にデータを追加する場合など、値を空白とすることはできません。

この際には、データを追加するたびに、初期値を設定してやる必要があります。

なぜかDataTableなどではデフォルト値を設定するメソッドがありません。

イベントをフックし、値を設定してやります。

次に示すコードは、それぞれのコラムの値に適応した初期値を新規作成されたデータに設定するやり方を示したものです。

private void dataGridView1_CellFormatting(object sender
                                    , DataGridViewCellFormattingEventArgs e)
        {
            if (e.Value == null)
            {
                switch (e.ColumnIndex)
                {
                    case 0:
                        e.Value=dataGridView1.Rows.Count;
                        break;
                    case 1:
                        break;
                    case 2:
                        e.Value = "Instant";
                        break;
                    case 3:
                        break;
                    case 4:
                        e.Value = "0";
                        break;
                    case 5:
                        e.Value = "0 sec";
                        break;
                }
            }
        }

本来ならば、設定するコラムでそれぞれデフォルト値を設定できるような仕組みになっているべきではあると思います。

The formality problem: Java and C# -- extended class

Small things get in the way.

The way to write extended classes in Java and C# differs slightly.

Just for the record the following cases depicts the differences.


The extended class -- the case with Java:
public class NewClassTest
{
class A
 {
   int i=0;
   A(int i)
     {
        this.i=i;
     }
 }

class B extends A
 {
   B()
     {
        super(1);
     }
 }

public void test()
 {
   System.out.println(new B().i);
 }

public static void main(String args[])
 {
    new NewClassTest().test();
 }
}


The extended class -- the case with C#:
class Class1
    {
        protected string value = "to be overwritten";
        public Class1(string convert)
        {
            value = convert;
        }
    }

    class Class2 : Class1
    {
        public Class2(string additional, string convert)
            : base(convert)
        {
            value = convert + additional;
        }
        public string value { get; set; }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Class2 test = new Class2(" additional text", "original text");
            label1.Text = test.value;
        }
    }

土曜日, 6月 04, 2011

C# プログレスバーの色を変える

C#のライブラリでは、プログレスバーの色を変えるメソッドが用意されていません。

そこで、「メモリ容量がいっぱいになりました」的な状態を示すために、プログレスバーの色を緑から赤に変える方法を紹介します。

using System.Runtime.InteropServices;

const int WM_USER = 0x400;
const int PBM_SETSTATE = WM_USER + 16;
const int PBM_GETSTATE = WM_USER + 17;

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

このように、Win32APIを呼び出す関数を用意して、エラー状態をセットしてやります。

public enum ProgressBarStateEnum : int
        {
            Normal = 1,
            Error = 2,
            Paused = 3,
        }

public static void SetState(ProgressBar pBar, ProgressBarStateEnum state)
        {
            SendMessage(pBar.Handle, PBM_SETSTATE, (IntPtr)state, IntPtr.Zero);
        }

SetState(progressBar1, ProgressBarStateEnum.Error);

もとの緑色に変更するには、ノーマル状態に戻してやります。

SetState(progressBar1, ProgressBarStateEnum.Normal);

追記: ここで注意せねばならないのは、プログレスバーのバグで、エラー状態を設定した時点では値が変更されません。

エラー状態を設定したら、値の変更を再度行う必要があります。

これはWindowsのバグらしいです。

if (progressBar1.Maximum * .9 < len)
       {
           progressBar1.Value = 0;
           SetState(progressBar1, ProgressBarStateEnum.Normal);
           progressBar1.Value = len;
           SetState(progressBar1, ProgressBarStateEnum.Error);
       }
else
       {
           progressBar1.Value = len;
           SetState(progressBar1, ProgressBarStateEnum.Normal);
       }

水曜日, 6月 01, 2011

フォームで、まとめてイベントを管理 AddMessageFilter()

Windows フォームで、まとめてイベントを管理したいとします。

その場でテキストエディターを立ち上げて、文字列を編集するときなど、部品全てについてイベント処理しなければなりません。

テキストエディターで編集して、コンポーネントからフォーカスが外れたとき、イベントを管理する必要があります。

これが意外な難関で、WinProcをオーバーライドしても、このメソッドではイベントが処理されません。個々のコンポーネントで処理しなければなりません。

そこで用意されているのが、ApplicationクラスにあるAddMessageFilter()メソッドです。

Application.AddMessageFilter(new MyMessageFilter())

このような形で、MessageFilter派生クラスを指定してやります。

イベント処理は、MessageFilterクラスのPreFilterMessage()メソッドで行います。

ここで、WM_NCLBUTTONDBLCLK 、WM_NCLBUTTONDOWN はタイトルバーでのイベントで、WM_LBUTTONDOWNはクライアントエリアで発生するイベントを指します。

こんな感じです。


       private const int WM_LBUTTONDOWN = 0x201;
       private const int WM_NCLBUTTONDBLCLK = 0x00A3;
       private const int WM_NCLBUTTONDOWN = 0x00A1;

       public bool PreFilterMessage(ref Message msg)
        {
            switch (msg.Msg)
            {
                case WM_NCLBUTTONDBLCLK:
                case WM_NCLBUTTONDOWN:
                case WM_LBUTTONDOWN:
                    {
                        int lparam = (int)msg.LParam;
                        int x = lparam & 0xffff;
                        int y = lparam >> 16;

                        Simulator simulator = (Simulator)sender;
                        Point pos = simulator.RichTextBox1.PointToClient(new Point(x, y));
                        Rectangle rect = new Rectangle(0, 0, simulator.RichTextBox1.Bounds.Width
                            , simulator.RichTextBox1.Bounds.Height + SystemInformation.HorizontalScrollBarThumbWidth);
                        if (!rect.Contains(pos))
                        {
                            simulator.focusOff();
                        }
                    }
                    break;
            }
            return false;
        }

Qt: 外部プログラムを起動する

  Qt/C++ のアプリは、外部へ直接アクセスできます。これはネットアプリでは不可能な Qt のメリットです。 外部プログラムを起動することもできます。QProcess::startDetached() を使うと独立したプロセスを立ち上げることができます。 この QProces...