Archive for May, 2009

How to: Disable Buttons in a Button Column in the Windows Forms DataGridView Control

Friday, May 29th, 2009

http://msdn.microsoft.com/ru-ru/library/ms171619(en-us,VS.80).aspx

 using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

class Form1 : Form
{
    private DataGridView dataGridView1 = new DataGridView();

    [STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }

    public Form1()
    {
        this.AutoSize = true;
        this.Load += new EventHandler(Form1_Load);
    }

    public void Form1_Load(object sender, EventArgs e)
    {
        DataGridViewCheckBoxColumn column0 =
            new DataGridViewCheckBoxColumn();
        DataGridViewDisableButtonColumn column1 =
            new DataGridViewDisableButtonColumn();
        column0.Name = “CheckBoxes”;
        column1.Name = “Buttons”;
        dataGridView1.Columns.Add(column0);
        dataGridView1.Columns.Add(column1);
        dataGridView1.RowCount = 8;
        dataGridView1.AutoSize = true;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.ColumnHeadersDefaultCellStyle.Alignment =
            DataGridViewContentAlignment.MiddleCenter;

        // Set the text for each button.
        for (int i = 0; i < dataGridView1.RowCount; i++)
        {
            dataGridView1.Rows[i].Cells["Buttons"].Value =
                “Button ” + i.ToString();
        }

        dataGridView1.CellValueChanged +=
            new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
        dataGridView1.CurrentCellDirtyStateChanged +=
            new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
        dataGridView1.CellClick +=
            new DataGridViewCellEventHandler(dataGridView1_CellClick);

        this.Controls.Add(dataGridView1);
    }

    // This event handler manually raises the CellValueChanged event
    // by calling the CommitEdit method.
    void dataGridView1_CurrentCellDirtyStateChanged(object sender,
        EventArgs e)
    {
        if (dataGridView1.IsCurrentCellDirty)
        {
            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }

    // If a check box cell is clicked, this event handler disables 
    // or enables the button in the same row as the clicked cell.
    public void dataGridView1_CellValueChanged(object sender,
        DataGridViewCellEventArgs e)
    {
        if (dataGridView1.Columns[e.ColumnIndex].Name == “CheckBoxes”)
        {
            DataGridViewDisableButtonCell buttonCell =
                (DataGridViewDisableButtonCell)dataGridView1.
                Rows[e.RowIndex].Cells["Buttons"];

            DataGridViewCheckBoxCell checkCell =
                (DataGridViewCheckBoxCell)dataGridView1.
                Rows[e.RowIndex].Cells["CheckBoxes"];
            buttonCell.Enabled = !(Boolean)checkCell.Value;

            dataGridView1.Invalidate();
        }
    }

    // If the user clicks on an enabled button cell, this event handler 
    // reports that the button is enabled.
    void dataGridView1_CellClick(object sender,
        DataGridViewCellEventArgs e)
    {
        if (dataGridView1.Columns[e.ColumnIndex].Name == “Buttons”)
        {
            DataGridViewDisableButtonCell buttonCell =
                (DataGridViewDisableButtonCell)dataGridView1.
                Rows[e.RowIndex].Cells["Buttons"];

            if (buttonCell.Enabled)
            {
                MessageBox.Show(dataGridView1.Rows[e.RowIndex].
                    Cells[e.ColumnIndex].Value.ToString() +
                    ” is enabled”);
            }
        }
    }
}

public class DataGridViewDisableButtonColumn : DataGridViewButtonColumn
{
    public DataGridViewDisableButtonColumn()
    {
        this.CellTemplate = new DataGridViewDisableButtonCell();
    }
}

public class DataGridViewDisableButtonCell : DataGridViewButtonCell
{
    private bool enabledValue;
    public bool Enabled
    {
        get
        {
            return enabledValue;
        }
        set
        {
            enabledValue = value;
        }
    }

    // Override the Clone method so that the Enabled property is copied.
    public override object Clone()
    {
        DataGridViewDisableButtonCell cell =
            (DataGridViewDisableButtonCell)base.Clone();
        cell.Enabled = this.Enabled;
        return cell;
    }

    // By default, enable the button cell.
    public DataGridViewDisableButtonCell()
    {
        this.enabledValue = true;
    }

    protected override void Paint(Graphics graphics,
        Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
        DataGridViewElementStates elementState, object value,
        object formattedValue, string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        // The button cell is disabled, so paint the border, 
        // background, and disabled button for the cell.
        if (!this.enabledValue)
        {
            // Draw the cell background, if specified.
            if ((paintParts & DataGridViewPaintParts.Background) ==
                DataGridViewPaintParts.Background)
            {
                SolidBrush cellBackground =
                    new SolidBrush(cellStyle.BackColor);
                graphics.FillRectangle(cellBackground, cellBounds);
                cellBackground.Dispose();
            }

            // Draw the cell borders, if specified.
            if ((paintParts & DataGridViewPaintParts.Border) ==
                DataGridViewPaintParts.Border)
            {
                PaintBorder(graphics, clipBounds, cellBounds, cellStyle,
                    advancedBorderStyle);
            }

            // Calculate the area in which to draw the button.
            Rectangle buttonArea = cellBounds;
            Rectangle buttonAdjustment =
                this.BorderWidths(advancedBorderStyle);
            buttonArea.X += buttonAdjustment.X;
            buttonArea.Y += buttonAdjustment.Y;
            buttonArea.Height -= buttonAdjustment.Height;
            buttonArea.Width -= buttonAdjustment.Width;

            // Draw the disabled button.               
            ButtonRenderer.DrawButton(graphics, buttonArea,
                PushButtonState.Disabled);

            // Draw the disabled button text.
            if (this.FormattedValue is String)
            {
                TextRenderer.DrawText(graphics,
                    (string)this.FormattedValue,
                    this.DataGridView.Font,
                    buttonArea, SystemColors.GrayText);
            }
        }
        else
        {
            // The button cell is enabled, so let the base class
            // handle the painting.
            base.Paint(graphics, clipBounds, cellBounds, rowIndex,
                elementState, value, formattedValue, errorText,
                cellStyle, advancedBorderStyle, paintParts);
        }
    }
}

How to: Host Controls in Windows Forms DataGridView Cells

Friday, May 29th, 2009

http://msdn.microsoft.com/ru-ru/library/7tas5c80(en-us,VS.80).aspx

using System; 
using System.Windows.Forms; 
 
public class CalendarColumn : DataGridViewColumn 
{ 
    public CalendarColumn() : base(new CalendarCell()) 
    { 
    } 
    public override DataGridViewCell CellTemplate 
    { 
        get 
        { 
            return base.CellTemplate; 
        } 
        set 
        { 
            // Ensure that the cell used for the template is a CalendarCell. 
            if (value != null &amp;&amp; 
                !value.GetType().IsAssignableFrom(typeof(CalendarCell))) 
            { 
                throw new InvalidCastException("Must be a CalendarCell"); 
            } 
            base.CellTemplate = value; 
        } 
    } 
} 
public class CalendarCell : DataGridViewTextBoxCell 
{ 
    public CalendarCell() 
        : base() 
    { 
        // Use the short date format. 
        this.Style.Format = "d"; 
    } 
    public override void InitializeEditingControl(int rowIndex, object 
        initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) 
    { 
        // Set the value of the editing control to the current cell value. 
        base.InitializeEditingControl(rowIndex, initialFormattedValue, 
            dataGridViewCellStyle); 
        CalendarEditingControl ctl = 
            DataGridView.EditingControl as CalendarEditingControl; 
        ctl.Value = (DateTime)this.Value; 
    } 
    public override Type EditType 
    { 
        get 
        { 
            // Return the type of the editing contol that CalendarCell uses. 
            return typeof(CalendarEditingControl); 
        } 
    } 
    public override Type ValueType 
    { 
        get 
        { 
            // Return the type of the value that CalendarCell contains. 
            return typeof(DateTime); 
        } 
    } 
    public override object DefaultNewRowValue 
    { 
        get 
        { 
            // Use the current date and time as the default value. 
            return DateTime.Now; 
        } 
    } 
} 
class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl 
{ 
    DataGridView dataGridView; 
    private bool valueChanged = false; 
    int rowIndex; 
    public CalendarEditingControl() 
    { 
        this.Format = DateTimePickerFormat.Short; 
    } 
    // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
    // property. 
    public object EditingControlFormattedValue 
    { 
        get 
        { 
            return this.Value.ToShortDateString(); 
        } 
        set 
        { 
            if (value is String) 
            { 
                this.Value = DateTime.Parse((String)value); 
            } 
        } 
    } 
    // Implements the 
    // IDataGridViewEditingControl.GetEditingControlFormattedValue method. 
    public object GetEditingControlFormattedValue( 
        DataGridViewDataErrorContexts context) 
    { 
        return EditingControlFormattedValue; 
    } 
    // Implements the 
    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method. 
    public void ApplyCellStyleToEditingControl( 
        DataGridViewCellStyle dataGridViewCellStyle) 
    { 
        this.Font = dataGridViewCellStyle.Font; 
        this.CalendarForeColor = dataGridViewCellStyle.ForeColor; 
        this.CalendarMonthBackground = dataGridViewCellStyle.BackColor; 
    } 
    // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
    // property. 
    public int EditingControlRowIndex 
    { 
        get 
        { 
            return rowIndex; 
        } 
        set 
        { 
            rowIndex = value; 
        } 
    } 
    // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
    // method. 
    public bool EditingControlWantsInputKey( 
        Keys key, bool dataGridViewWantsInputKey) 
    { 
        // Let the DateTimePicker handle the keys listed. 
        switch (key &amp; Keys.KeyCode) 
        { 
            case Keys.Left: 
            case Keys.Up: 
            case Keys.Down: 
            case Keys.Right: 
            case Keys.Home: 
            case Keys.End: 
            case Keys.PageDown: 
            case Keys.PageUp: 
                return true; 
            default: 
                return false; 
        } 
    } 
    // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    // method. 
    public void PrepareEditingControlForEdit(bool selectAll) 
    { 
        // No preparation needs to be done. 
    } 
    // Implements the IDataGridViewEditingControl 
    // .RepositionEditingControlOnValueChange property. 
    public bool RepositionEditingControlOnValueChange 
    { 
        get 
        { 
            return false; 
        } 
    } 
    // Implements the IDataGridViewEditingControl 
    // .EditingControlDataGridView property. 
    public DataGridView EditingControlDataGridView 
    { 
        get 
        { 
            return dataGridView; 
        } 
        set 
        { 
            dataGridView = value; 
        } 
    } 
    // Implements the IDataGridViewEditingControl 
    // .EditingControlValueChanged property. 
    public bool EditingControlValueChanged 
    { 
        get 
        { 
            return valueChanged; 
        } 
        set 
        { 
            valueChanged = value; 
        } 
    } 
    // Implements the IDataGridViewEditingControl 
    // .EditingPanelCursor property. 
    public Cursor EditingPanelCursor 
    { 
        get 
        { 
            return base.Cursor; 
        } 
    } 
    protected override void OnValueChanged(EventArgs eventargs) 
    { 
        // Notify the DataGridView that the contents of the cell 
        // have changed. 
        valueChanged = true; 
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true); 
        base.OnValueChanged(eventargs); 
    } 
} 
public class Form1 : Form 
{ 
    private DataGridView dataGridView1 = new DataGridView();
    [STAThreadAttribute()] 
    public static void Main() 
    { 
        Application.Run(new Form1()); 
    } 
    public Form1() 
    { 
        this.dataGridView1.Dock = DockStyle.Fill; 
        this.Controls.Add(this.dataGridView1); 
        this.Load += new EventHandler(Form1_Load); 
        this.Text = "DataGridView calendar column demo"; 
    } 
    private void Form1_Load(object sender, EventArgs e) 
    { 
        CalendarColumn col = new CalendarColumn(); 
        this.dataGridView1.Columns.Add(col); 
        this.dataGridView1.RowCount = 5; 
        foreach (DataGridViewRow row in this.dataGridView1.Rows) 
        { 
            row.Cells[0].Value = DateTime.Now; 
        } 
    } 
}

SpyLog

Tuesday, May 26th, 2009

Сегодня SpyLog обновил web-интерфейс для своих отчетов. Теперь они выглядят как неполноценный клон Google Analitics.
Все графики, шрифты и т.п. полностью слизали из Google Analitics. При этом большинство отчетов просто тупо не работают.

Понятно, что починят и заработает. Но не понимаю что ими движет. Кому нужен еще один Google Analitics.
Ведь те, кто хочет, поставит у себя именно оригинал, а не их клон. Зачем им-то копировать? Почему не отличаться?

Вот лично мне старая форма больше нравилась. А по идее сейчас я их вообще должен снести. Зачем они мне, если на страницах и так уже стоит Google Analitics…

is file a valid .NET assembly (CLR type)

Tuesday, May 26th, 2009

Returns true if the file specified is a real CLR type, otherwise false is returned.

function IsDotNetAssembly(const AFileName: string): Boolean;
var
  fs: TFileStream;
  peHeader, peHeaderSignature,
  timestamp, pSymbolTable, noOfSymbol: dWord;
  machine, sections, optionalHeaderSize, characteristics: Word;
  dataDictionaryRVA: array[0..14] of dWord;
  dataDictionarySize: array[0..14] of dWord;
  i: Integer;
begin
  fs := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
  try
    //PE Header starts @ 0x3C (60). Its a 4 byte header.
    fs.Seek($3C, soFromBeginning);
    fs.Read(peHeader, SizeOf(peHeader));
    //Moving to PE Header start location...
    fs.Position := peHeader;
    fs.Read(peHeaderSignature, SizeOf(peHeaderSignature));
    //We can also show all these value, but we will be
    //limiting to the CLI header test.
    fs.Read(machine, SizeOf(machine));
    fs.Read(sections, SizeOf(sections));
    fs.Read(timestamp, SizeOf(timestamp));
    fs.Read(pSymbolTable, SizeOf(pSymbolTable));
    fs.Read(noOfSymbol, SizeOf(noOfSymbol));
    fs.Read(optionalHeaderSize, SizeOf(optionalHeaderSize));
    fs.Read(characteristics, SizeOf(characteristics));
 
    { Now we are at the end of the PE Header and from here, the
    PE Optional Headers starts...
    To go directly to the datadictionary, we'll increase the
    stream's current position to with 96 (0x60). 96 because,
    28 for Standard fields
    68 for NT-specific fields
    From here DataDictionary starts...and its of total 128 bytes.
    DataDictionay has 16 directories in total,
    doing simple maths 128/16 = 8.
    So each directory is of 8 bytes.
 
    In this 8 bytes, 4 bytes is of RVA and 4 bytes of Size.
    btw, the 15th directory consist of CLR header! if its 0,
    it is not a CLR file }
 
    fs.Seek($60, soFromCurrent);
    for i := 0 to 14 do
    begin
      fs.Read(dataDictionaryRVA[i], SizeOf(dataDictionaryRVA[i]));
      fs.Read(dataDictionarySize[i], SizeOf(dataDictionarySize[i]));
    end;
  finally
    fs.Free
  end;
  Result := (dataDictionaryRVA[14] &lt;&gt; 0)
end;

Created in Delphi from http://www.codeproject.com/KB/cs/AutoDiagrammer.aspx

звонки по телефону

Thursday, May 14th, 2009

Есть в Украине замечательынй сервис www.zadarma.com

Раньше я пользовался ихним бесплатным dialup’ом (т.е. плата идет только за поминутку самому Укртелекому)

А потом они поставили бесплатный шлюз для VoIP. Т.е. звонишь на их мобильный номер, а потом набираешь любой номер телефона в любой стране и идет дозвон. Это тоже бесплатно и платится только по тарифу за звонок на мобильный. Скорее всего внутри звонок переводится на Skype, а деньги берут за входящий звонок с мобильного оператора

Я этим пользуюсь часто для звонков в Израниль, т.к. из “бесплатных” пакетных минут у МТС каждый месяц что-то остается. И это “что-то” я расходую через zadarma.com и таким образом эти минуты мне вообще бесплатно обходятся

Сегодня тоже попытался позвонить таким образом в Израиль, но уже на тамошний мобильный номер (раньше всегда звонил на “городские” стационарные номера). И оказалось, что такое они уже не пропускают:-)

Видать сумма, взятая с входящего оператора, меньше, чем тариф Skype:-)
Пришлось звонить по Skype самому. Они берут по 15-16 центов за минуту против обычных 2 центов за звонок на стационарный телефон в Израиле

транзакции в коде

Thursday, May 14th, 2009

В базах данных есть транзакции. При работе с несколькими таблицами без них невозможно обеспечить целостность данных.

Такая же функциональность была бы очень полезна при работе с переменными, классами и т.п. в языках программирования. Классы могут быть связаны между собой. Да еще и могут затрагивать какие-то глобальные-локальные переменные.

И изменение всей этой лабуды должно происходить в “пакете” – либо все (commit), либо ничего (rollback к предыдущему состоянию всех свойств-переменных)

Windows 7. Загрузка системы с диска VHD

Monday, May 11th, 2009

Пошаговая демонстрация как поставить Windows 7 на виртуальный vhdisk (в одном файле):
http://www.techdays.ru/videos/1237.html