Окна произвольной формы на C#

30 дек. 2009 г. | | |

Недавно наткнулась на свою программку, которая создает окно произвольной формы. Написана она была на C#, код довольно простой. Логически код можно разделить на две части - одна отрисовывает форму произвольной формы, заданной bmp-файлом, другая занимается отслеживанием перемещений формы. На самой форме нет ничего, FormBorderStyle установлен в None.
Принцип работы этого кода прост. Методу CreateFromBMP() в качестве аргументов передается bmp-русинок, в котором содержится желаемая форма для окна, и цвет, который надо из рисунка исключить, чтобы получить контур. Для примера использовался рисунок машинки, созданный в mspaint :)

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.BackgroundImage = global::Window.Properties.Resources.bg;
this.Region = CreateFromBMP(global::Window.Properties.Resources.bg, Color.FromArgb(255, 255, 255));
}

#region Create Form Border From BMP

Region CreateFromBMP(Bitmap bg, Color excludeColor)
{
GraphicsPath path = new GraphicsPath();

int width = bg.Width;
int height = bg.Height;

for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (bg.GetPixel(x, y) != excludeColor)
{
path.AddRectangle(new Rectangle(x, y, 1, 1));
}
}
}

return (new Region(path));
}
#endregion

#region Moving form
private bool toMove = false;
private Point delta = new Point();

private void start_MouseMove(object sender, MouseEventArgs e)
{
if (toMove)
{
Point coords = this.PointToScreen(e.Location);

Point location = new Point(this.Location.X + (coords.X - delta.X), this.Location.Y + (coords.Y - delta.Y));

this.Location = location;

delta = coords;
}
}

private void start_MouseDown(object sender, MouseEventArgs e)
{
if ((e.Button == MouseButtons.Left) && (e.Clicks == 1))
{
toMove = true;
delta = this.PointToScreen(e.Location);
}
}

private void start_MouseUp(object sender, MouseEventArgs e)
{
toMove = false;
}
#endregion

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape) Application.Exit();
}
}

Результат работы кода:
Скачать проект можно отсюда.

Постеры пространств имён

27 дек. 2009 г. | | |

Постер пространства имен .NET 3.5 скачать pdf
Постер пространства имен .NET 4.0 скачать pdf
Постер LinQtoSQL скачать pdf

Microsoft Enterprise Library

| | |

Microsoft Enterprise Library – это набор блоков приложений многоразового использования, созданных как решения проблем, с которыми специалисты по разработке программного обеспечения обычно сталкиваются при создании корпоративных приложений. Для использования библиотеки необходим .NET 3.5. Живет проект по адресу http://www.codeplex.com/entlib. Скачать Microsoft Enterprise Library 4.1 можно отсюда http://www.microsoft.com/downloads/details.aspx?FamilyId=1643758B-2986-47F7-B529-3E41584B6CE5&displaylang=en либо по предыдущей ссылке.
В Enterprise Library входят следующие блоки:
- блок кэширования (Caching Application Block), который применяется для реализации локального кэша;
- блок криптографии (Cryptography Application Block), служащий для исполнения алгоритмов хеширования и симметрического шифрования;
- блок доступа к данным (Data Access Application Block). Он используется для реализации функциональности, связанной с доступом к базам данных;
- блок обработки исключений (Exception Handling Application Block). Применяется для реализации унифицированной обработки исключений на всех уровнях приложения;
- блок протоколирования (Logging Application Block). Служит для исполнения механизмов ведения протоколов;
- блок безопасности (Security Application Block). Реализует механизмы авторизации и безопасного кэширования.
Посмореть презентацию об Enterprise Library вы можете по ссылке http://pnp.in.ua/video/EntLib/default.html, а по этой ссылке http://pnp.in.ua/Slides/EntLib/default.html находятся слайды из это презентации.

Набор системных диалогов для .Net

| | |


Оказывается, существует такая полезная библиотека для .NET 3.5 SP1 Ookii.Dialogs, которая содержит разные системные диалоги (Task dialog, Progress dialog, Credential dialog, Input dialog, Vista-style common file dialogs и др.). В библиотеке представлены две версии диалогов - для WinForms и для WPF. Однако при использовании этой библиотеки нужно учитывать, что большинство диалогов появилось только начиная с Vista. Поэтому для ОС версией меньше Vista, нужно писать обертку для отображения системных диалогов.
Скачать библиотеку можно по ссылке http://www.ookii.org/download.ashx?id=Dialogs. В архиве есть исходный код библиотеки, а так же полная документация.

Горячие клавиши (Hotkeys) Windows 7

26 дек. 2009 г. | | |

Список хоткеев в Window 7. Естественно, часть хоткеев не будет для вас новой, потому как унаследована от Windows XP. Сразу оговорюсь, список не претендует на полноту.

Управление окнами

Win+Home: Свернуть/развернуть все окна, кроме активного. («Потрясти» окно)
Win+Space: Сделать все окна прозрачными. (Задержать курсор над небольшой кнопкой в правом нижнем углу экрана.)
Win+Up: Развернуть активное окно на весь экран. (Перетащить окно вверх до упора, или дважды кликнуть по верхней рамке)
Win+Down: Свернуть активное окно или восстановить размер, если оно развёрнуто на весь экран
Shift+Win+Up: Развернуть окно по высоте (Перетащить нижнюю границу окна до таскбара)
Win+Left/Right: Занять окном левую/правую половину монитора, или восстановить размер (Перетащить окно влево/вправо до упора)

Таскбар

Win+цифра: Запустить программу под этим номером или переключиться на неё
Shift+Win+цифра: Запустить новую копию программы под этим номером (кликнуть колёсиком по иконке)
Ctrl+Win+цифра: Переключиться на следующее окно программы под этим номером (кликнуть, зажав Ctrl)
Alt+Win+цифра: Открыть джамплист программы под этим номером
Win+Tab(+Shift): Переключаться между всеми открытыми окнами с превьюшками над таскбаром в прямом (обратном) порядке
Win+B: Фокус на трэй
Ctrl+Shift+Click: Запустить программу от имени Администратора
Shift+Right-Сlick: Показать меню окна / группы

Проводник и Десктоп

Win+E: Вызвать окно проводника
Win+D: Показать Рабочий стол
Win+F: Поиск
Ctrl + Win + F: Поиск компьютеров
Ctrl+Shift+N: Создать новую папку
Alt+Up: Подняться на уровень выше по папкам
Backspace: Вернуться на предыдущий уровень по папкам
Alt+P: Включить панель просмотра файлов
Shift+Right-Click (по файлу): Добавляет в контекстное меню пункт «Скопировать путь» и много дополнительных пунктов в подменю «Отправить»
Shift+Right-Click (по папке): Добавляет в контекстное меню пункт, позволяющий открыть командную строку из этой папки
Ctrl + Scroll: уменьшение/увеличение размеров иконок
Ctrl+C: Копировать объект (папку, файл, фрагмент текста....)
Ctrl+Х: Вырезать объект (папку, файл, фрагмент текста....)
Ctrl+V: Вставить объект (папку, файл....)

Разное

Win+P: Открыть меню настройки режима презентации (второй монитор — проектор)
Win+(+/-): увеличить / уменьшить изображение (вызывает экранную лупу)
Win+G: Переключаться между запущенными гаджетами
Ctrl+Shift+Esc: диспетчер задач
Win+Pause: Панель управления\Все элементы панели управления\Система (Свойства системы)
Win, "Первые буквы названия программы", Enter: поиск программы по первым буквам ее названия, запуск. Раньше для этого надо было устанавливать сторонний софт типа Launchy, а теперь все влючено!
Win+R: Диалог "Выполнить"

Библиотека

22 дек. 2009 г. | | |

С. Макконнелл. Совершенный код (скачать)
Более 10 лет первое издание этой книги считалось одним из лучших практических руководств по программированию. Сейчас эта книга полностью обновлена с учетом современных тенденций и технологий и дополнена сотнями новых примеров, иллюстрирующих искусство и науку программирования. Опираясь на академические исследования, с одной стороны, и практический опыт коммерческих разработок ПО - с другой, автор синтезировал из самых эффективных методик и наиболее эффективных принципов ясное прагматичное руководство. Каков бы ни был ваш профессиональный уровень, с какими бы средствами разработками вы ни работали, какова бы ни была сложность вашего проекта, в этой книге вы найдете нужную информацию, она заставит вас размышлять и поможет создать совершенный код.





Майкл Ховард, Дэвид Леблан. Защищенный код. (скачать)
В этой книге разработчики найдут советы и рекомендации по защите создаваемых приложений на всех этапах процесса создания ПО — от проектирования безопасных приложений до написания надежного кода, способного устоять перед атакам хакеров. Здесь рассказывается о моделировании угроз, планировании процесса разработки защищенных приложений, проблемах локализации и связанных с ней опасностях, недостатках файловых систем, поддержке секретности в приложениях и анализе исходного кода на предмет безопасности. Авторы иллюстрируют свой рассказ примерами программ на самых разных языках — от C# до Perl. Издание обогащено знанием, полученным авторами в процессе реализации Windows Security Push — инициативы по укреплению защиты продуктов Microsoft. Интересно, что эту книгу Билл Гейтс объявил 'обязательным чтением в Microsoft'.

Библиотека

21 дек. 2009 г. | | |

Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования. (скачать)
В предлагаемой книге описываются простые и изящные решения типичных задач, возникающих в объектно-ориентированном проектировании. Паттерны появились потому, что многие разработчики искали пути повышения гибкости и степени повторного использования своих программ. Найденные решения воплощены в краткой и легко применимой на практике форме. Авторы излагают принципы использования паттернов проектирования и приводят их каталог. Таким образом, книга одновременно решает две задачи. Во-первых, здесь демонстрируется роль паттернов в создании архитектуры сложных систем. Во-вторых, применяя содержащиеся в справочнике паттерны, проектировщик сможет с легкостью разрабатывать собственные приложения.
Издание предназначено как для профессиональных разработчиков, так и для программистов, осваивающих объектно-ориентированное проектирование.



Крэг Ларман. Применение UML 2.0 и шаблонов проектирования (скачать)
Применение UML 2.0 и шаблонов проектирования - всемирно известное издание, с помощью которого можно начать "мыслить объектами" и проникнуть в самую суть объектно-ориентированного анализа и проектирования. Основываясь на двух предыдущих изданиях, получивших широкую поддержку во всем мире, Крэг Ларман полностью обновил книгу, чтобы рассказать о новом стандарте UML 2.0, помочь читателям освоить искусство объектного проектирования и способствовать развитию эффективных приемов итеративного и гибкого моделирования.
Основываясь на своем беспрецедентном опыте преподавателя и консультанта, Ларман помогает читателям разобраться с подходами эволюционного определения требований и прецедентов, моделированием предметной области, проектированием на основе обязанностей, а также наиболее важными принципами объектно-ориентированного проектирования и многоуровневой архитектурой. С помощью этой книги вы сможете познакомиться также с шаблонами проектирования GoF и GRASP, итеративными методами, гибким подходом к использованию унифицированного процесса и многими другими темами.


Грегор Хоп, Бобби Вульф. Шаблоны интеграции корпоративных приложений. (скачать)
В данной книге исследуются стратегии интеграции корпоративных приложений с помощью механизмов обмена сообщениями. Авторы рассматривают шаблоны проектирования и приводят практические примеры интеграции приложений, демонстрирующие преимущества обмена сообщениями и эффективность решений, создаваемых на основе этой технологии. Каждый шаблон сопровождается описанием некоторой задачи проектирования, обсуждением исходных условий и представлением элегантного, сбалансированного решения. Авторы подчеркивают как преимущества, так и недостатки обмена сообщениями, а также дают практические советы по написанию кода подключения приложения к системе обмена сообщениями, маршрутизации сообщений и мониторинга состояния системы.
Книга ориентирована на разработчиков программного обеспечения и системных интеграторов, использующих различные технологии и продукты для обмена сообщениями, такие как Java Message Service (JMS), Microsoft Message Queuing (MSMQ), IBM WebSphere MQ, Microsoft BizTalk, TIBCO, WebMethods, SeeBeyond, Vitria и др.


Джошуа Кериевски. Рефакторинг с использованием шаблонов (скачать)
Данная книга представляет собой результат многолетнего опыта профессионального программиста по применению шаблонов проектирования. Авторский подход к проектированию состоит в том, что следует избегать как недостаточного, так и избыточного проектирования, постоянно анализируя готовый работоспособный код и реорганизуя его только в том случае, когда это приведет к повышению его эффективности, упрощению его понимания и сопровождения. Шаблоны проектирования - не панацея, так что бывают как ситуации, когда такая реорганизация должна выполняться с использованием шаблонов проектирования, так и ситуации, когда наилучшее решение состоит в отказе от них.
Автор на основании как собственного, так и чужого опыта детально рассматривает различные признаки кода, требующего рефакторинга, описывает, какой именно рефакторинг наилучшим образом подходит для той или иной ситуации, и описывает его механику, подробно разбирая ее на конкретных примерах из реальных задач.
Книга может рассматриваться и как учебник по рефакторингу для программиста среднего уровня, и как справочное пособие для профессионала, которое может подсказать, какое именно решение стоит принять в той или иной сложной ситуации.

Вигерс Карл. Программирование: Разработка требований к программному обеспечению. (скачать)
Эта книга посвящена разработке качественных требований к продукту, здесь описаны дюжины проверенных на практике способов выявления, формулирования, разработки, проверки, утверждения и тестирования требований к ПО, которые помогут разработчикам ПО, менеджерам и маркетологам создать эффективное ПО. Это перевод второго издания оригинальной книги, которое дополнено новыми главами о роли аналитика требований, важности бизнес-правил, а также о том, как формулирование требований важно для проектов по обслуживанию, для комплексных решений и проектов, разрабатываемых сторонними организациями.
Основная аудитория - аналитики требований и разработчики продукта, а также дизайнеры, программисты, тестеровщики ПО и другие члены команды , задача которых понять и удовлетворить чаяния клиентов, а также маркетологи, менеджеры по продуктам и менеджеры проекта, которые должны проникнуться "духом" и особенностями продукта, чтобы сделать его в полной мере конкурентоспособным.

Скотт Аблер. Гибкие технологии: экстремальное программирование и унифицированный процесс разработки. (скачать)
Книга посвящена гибкому моделированию - процессу, базирующемуся на практической деятельности и описывающему принципы построения полезных моделей. Она начинается с рассмотрения идей, принципов и методологии гибкого моделирования и описания методик, которые повысят вашу производительность. Кроме того, в этой книге переосмысливаются некоторые важные вопросы разработки программного обеспечения, такие как написание документации, организовация сеансов моделирования, подбор команды, занимающейся моделированием, применение UML. Как сказано в названии книги, в ней детально рассматриваются вопросы эффективного моделирования в XP-проектах. Книга рассчитана на разработчиков или специалистов по моделированию, которые хотят повысить свой профессиональный уровень.




Кент Бек. Экстремальное программирование: разработка через тестирование (скачать)
Изящный, гибкий и понятный код, который легко модифицировать, который корректно работает и который не подкидывает своим создателям неприятных сюрпризов. Неужели, подобное возможно? Чтобы достичь цели, попробуйте тестировать программу еще до того, как она написана. Именно такая парадоксальная идея положена в основу методики TDD (Test-Driven-Development — разработка, основанная на тестировании). Бессмыслица? Не спешите делать скороспелых выводов. Рассматривая применение TDD на примере разработки реального программного кода, автор демонстрирует простоту и мощь этой новой методики. В книге рассматриваются два программных проекта, целиком и полностью реализованных с использованием TDD. За рассмотрением примеров следует обширный каталог приемов работы в стиле TDD, а также паттернов и рефакторингов, имеющих отношение к TDD. Книга будет полезна для любого программиста, желающего повысить производительность свой работы и получить удовольствие от программирования.

Пишем приложение, поддерживающее плагины

20 дек. 2009 г. | | |

Идея проста – есть интерфейс ( IPlugin ), о котором знает главная программа, и который должны реализовывавать все плагины. Вот, в принципе, и вся идея :)

Плагины наше приложение будет искать и автоматически подгружать в меню Plugins из папки plugins. Естественно, плагины должны быть реализованы ввиде dll-модуля. Если в папке будет dll, содержащая классы, не реализующие интерфейс IPlugin, то лоадер просто игнорирует их.

Реализовать данную затею предлагаю на C# в виде простенького Windows Forms Application.

Итак, создаем новый проект (Windows Forms Application), назовем его, к примеру, PluginTest. На главную форму добавим меню (menuStrip1) и панель (contentHolder), на которую будем подгружать наши формы.


В меню добавляем пункты, как на картинке. На событие Click пункта меню Exit пишем код

Application.Exit();

По клику на SampleForm в панель contentHolder приложение должно будет загрузить форму. Давайте создадим класс, который будет ответственный за это. Для этого добавим в проект класс ContentManager. Перед использование его нужно инициализировать контролом, на который нужно подгружать различные формы. Код:

class ContentManager
{
protected static Control _contentHolder;

public ContentManager()
{

}

public static void Inizialize(Control ctrl)
{
_contentHolder = ctrl;
}

public static void LoadContent(Control content)
{
_contentHolder.Controls.Clear();
content.Dock = DockStyle.Fill;
_contentHolder.Controls.Add(content);
}
}

Теперь добавим в проект UserControl с именем SampleForm. Какой функционал будет выполнять данный контрол - полет вашей фантазии, я ограничусь лишь кнопочкой "Hello, world!". После этого на событие Click пункта меню SampleForm напишем:

ContentManager.LoadContent(new SampleForm());


Сейчас приступим к реализации плагинной системы. Помните, мы говорили об интерфейсе? Так вот, добавьте в солюшн проект типа Class Library и назовите его IPlugin. Вот код самого интерфейса:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace IPlugins
{
public interface IPlugin
{
Control GetContent();
String GetName();
}
}

Таким образом, плагин для нашего приложения должен реализовать две функции - GetContent() - должна вернуть контол т.е. форму плагина, а GetName() - название плагина для красивого отображения в меню.
Добавим ссылку на проект IPlugin в проект PluginTest.
А теперь создадим парочку плагинов! Для этого в солюшн добавьте еще один проект типа Class Library и назовите его SamplePlugin. В References этого проекта тоже надо добавить ссылку на проект IPlugin. Теперь подключим в using IPlugin и напишем простенький плагин :)

public class Plugin1 : IPlugin
{
private String _pluginName = "Plugin1";

public Plugin1()
{
}

public String GetName()
{
return _pluginName;
}

public Control GetContent()
{
SamplePluginUI content = new SamplePluginUI();
return content;
}

}
}

Класс Plugin1 реализует интерфейс IPlugin. В методе GetContent() он создает UserControl SamplePluginUI и возвращает его получателю. Добавьте в проект SamplePlugin UserControl с название SamplePluginUI.
Теперь осталось чуть-чуть. Наш ContentManager пока умеет подгружать на форму только Control'ы. Давайте научим его еще добывать формы из плагинов. Для этого в класс ControlManager добавьте следующий метод:

public static void LoadContent(Type t)
{
IPlugin plugin = (IPlugin)Activator.CreateInstance(t);
LoadContent(plugin.GetContent());
}

Теперь осталось совсем чуть-чуть. Во-первых, нужно добавить метод в главную форму солюшена PluginTest, который будет искать плагины и подгружать их. Назовем его CheckForPlugins().

private void CheckForPlugins()
{
String PluginsDir = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "plugins");

if (!Directory.Exists(PluginsDir))
{
Directory.CreateDirectory(PluginsDir);
}

String[] PluginAssemblies = Directory.GetFiles(PluginsDir, "*.dll");

ToolStripMenuItem pluginsMenu = (ToolStripMenuItem) menuStrip1.Items["plugins"];

if (pluginsMenu.DropDown == null)
{
pluginsMenu.DropDown = new ToolStripDropDown();
}

foreach (String file in PluginAssemblies)
{
Assembly AddInAssembly = Assembly.LoadFrom(file);
foreach (Type t in AddInAssembly.GetExportedTypes())
{
if (t.IsClass && typeof(IPlugin).IsAssignableFrom(t))
{
AddPlugin(t, pluginsMenu);
}
}
}
}

private void AddPlugin(Type t, ToolStripMenuItem where)
{
IPlugin plugin = (IPlugin)Activator.CreateInstance(t);
string pluginName = plugin.GetName();
ToolStripMenuItem mi = new ToolStripMenuItem(pluginName);
mi.Click += new EventHandler(mi_Click);
mi.Tag = t;
where.DropDownItems.Add(mi);
}

void mi_Click(object sender, EventArgs e)
{
Type t = (Type)((ToolStripMenuItem)sender).Tag;
ContentManager.LoadContent(t);
}

Что тут происходит? В самом начале метода мы находим путь к папке plugins и проверяем, существует ли она. Потом выбираем из нее все файлы с расширением dll в массив PluginAssemblies. Далее, мы проверяем каждый элемент этого массива на то, является ли он классом и реализует ли интерфейс IPlugin. Если результат положительный, то добавляем его в меню Plugins методом AddPlugin().
Осталось только подправить конструктор формы Form1:

public Form1()
{
InitializeComponent();
ContentManager.Inizialize(this.contentHolder);
CheckForPlugins();
}

Вот и все, приложение, поддерживающее плагины, готово!
Исходный код можно скачать отсюда.

Ускоряем NetBeans

18 дек. 2009 г. | | |

Сегодня совершенно случайно :) набрела на заметку о том, как можно немного ускорить любимую IDE NetBeans (после Visual Studio, конечно). И так, суть ускорения сводится к настройкам для java-машины, с помощью которых мы разрешаем использовать большее количество памяти (384Мб), компилировать в машинный код большинство функций и оптимизировать их. Для этого в /etc/netbeans.conf или в ярлык для запуска IDE нужно добавить следующие опции

-J-client -J-Xms32m -J-Xmx384m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Xverify:none -J-XX:CompileThreshold=100 -XX:+CompressedOOPS -XX:+AggressiveOpts -XX:+TieredCompilation -XX:+DoEscapeAnalysis -XX:+UseConcMarkSweepGC -J-XX:+CMSClassUnloadingEnabled -J-XX:+CMSPermGenSweepingEnabled
О расшифровке ключей можно почитать тут - http://performance.netbeans.org/howto/jvmswitches/index.html (англ.)
Найдено тут

Рисуем красивые заголовки с помощью библиотеки gd PHP

14 дек. 2009 г. | | |

Как сделать красивый заголовок для статьи, например, рукописным текстом? Для одной статьи или, если их немного, можно посидеть в фотошопе и сделать заголовки. А если статей много и добавляются они регулярно - замучаешься сидеть в фотошопе!
В php есть чудная библиотека для работы с графикой, зовется gd. Ее функционалом мы и воспользуемся для решения поставленной задачи.
Сразу скажу, дабы избежать проблем с кириллицей, используйте шрифты, поддерживающие кириллицу!
А теперь начнем. Сперва создадим php-скрипт, который будет создавать чудный заголовок. В качестве параметра методом get мы будем передавать нашему скрипту текст заголовка.

<?php
#говорим браузеру, что далее будет картинка в формате png
header('Content-type: image/png');

if (isset($_GET['text']))
{
$text = rawurldecode(htmlspecialchars($_GET['text']));
}else $text = 'Without caption';
#ширина одной буквы выбранного текста
$letterwidth=12;
#ширина всей картинки
$width=$letterwidth*strlen($text);
#указываем путь к шрифту
$font = 'fonts/cyr.ttf';
#создаем картинку
$im = imagecreatetruecolor($width, 40);
#определяем цвета
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 113, 129, 152);
#закрашиваем фон
imagefilledrectangle($im, 0, 0, 999, 40, $white);
#пишем текст
imagettftext($im, 30, 0, 10, 30, $black, $font, $text);
#выдаем браузеру готовую картинку
imagepng($im);
#освобождаем ресурсы
imagedestroy($im);
?>
Думаю, что более комментировать скрипт не нужно. Теперь вместо заголовка статьи пишем

<img src="caption.php?text=Заголовок для статьи" alt="" />

Вот и все :)
Скрипт в работе вы можете увидеть тут
Скачать исходник вы можете тут

Прозрачный PNG в IE

13 дек. 2009 г. | | |

Тема довольно старая и избитая, но все же расскажу о том, что я делаю, чтобы в ИЕ прозрачные PNG картинки отображались без ужасного серого фона, который "любимый браузер" прикручивает к ним. И так, все совершенно не сложно.
Нам потребуется прозрачный gif размером 1х1 пикселей, которую назовем blank.gif. Далее, в хтмл-файле в разделе <head> пишем следующее:

<!--[if lt IE 7]>
<![if gte IE 5.5]>
<script type="text/javascript">
function fixPNG(element)
{
if (/MSIE (5\.5|6).+Win/.test(navigator.userAgent))
{
var src;

if (element.tagName=='IMG')
{
if (/\.png$/.test(element.src))
{
src = element.src;
element.src = "blank.gif";
}
}
else
{
src = element.currentStyle.backgroundImage.match(/url\("(.+\.png)"\)/i)
if (src)
{
src = src[1];
element.runtimeStyle.backgroundImage="none";
}
}

if (src) element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "',sizingMethod='none')";
}
}
</script>
<style type="text/css">
.iePNG, IMG { filter:expression(fixPNG(this)); }
.iePNG A { position: relative; }
</style>
<![endif]>
<![endif]-->

Не забудьте исправить путь к gif-изображению, иначе фокус не получится.
Собственно говоря, это все. Скрипт когда-то давно был честно скачан, откуда - не припоминается. Спасибо автору скрипта!

Защита контента с помощью javascript

| | |

При выполнении очередного заказа столкнулась с проблемой защиты контента от копирования. Конечно, самая лучшая защита - не выкладывать контент в интернет :). Но так как этот вариант не подходил, то для защиты контента от копирования был написан маленький скриптик:

<script language="JavaScript">
//autor tan4eg
function disableSelection(target)
{
if (typeof target.onselectstart!="undefined")
{
target = document;
target.onselectstart=function(){return false;};
}
else
{
if (typeof(target.style.MozUserSelect)!="undefined")
{
target.style.MozUserSelect="none";
}
else
{
target = document;
target.onmousedown=function(){return false;};
}
}
target.style.cursor = "default";
}
document.oncontextmenu = function() { return false; }
window.onload = function()
{
if (document.getElementById("maintable"))
{
disableSelection(document.getElementById("maintable"));
}
}
</script>

Для использования скрипта достаточно поместить его текст между тэгами <head>
Суть работы скрипта в том, что он запрещает выделение контента у конкретного элемента, id которого мы задаем в обработчике window.onload. Для большей уверенности скрипт также запрещает контекстное меню. Однако это далеко не панацея :(

Почему компьютерщики выглядят бездельниками

23 нояб. 2009 г. | | |

Internet Explorer 8 и уязвимости

21 нояб. 2009 г. | | |

Недавно прочла интересную заметку об уязвимости веб-браузеров. Особенно порадовали новости об IE8. Компания Cenzic, которая проводит исследования интернет-безопасности, опубликовала аналитический отчёт об уязвимости различных браузеров. Данные были получены в ходе исследования, проведённого специалистами Cenzic в первой половине 2009 года. Согласно этим результатам браузер Internet Explorer 8 был признан одним из самых безопасных и надёжных: в нём было обнаружено всего 15% уязвимостей. По этим показателям интернет-браузер от Microsoft смог обойти своих конкурентов Firefox и Safari, в которых было обнаружено 44% и 35% уязвимостей соответственно. Вот как это прокомментировал Владимир Мамыкин, директор по информационной безопасности ООО "Майкрософт Рус":

Специалистам всегда было известно, что браузер Firefox имеет значительно больше уязвимостей чем IE. Для этого достаточно регулярно заходить на популярный сайт secunia.com, на котором публикуются подробные списки всех уязвимостей продуктов мировых производителей. Например, на конец 2008 года Firefox 2.0. имел 154 уязвимости, а IE 7. – 70. На конец июня 2009 Firefox 3. имел 81 уязвимость, а IE 8. – всего 8. А на 10 ноября 2009 Firefox 3. имеет 133 уязвимости, а IE 8. – всего 16! Так что «открытие» Cenzic никого из специалистов не удивляет.
Так что не все еще потеряно, быть может, когда-то ИЕ станет вполне юзабельным и безопасным, а пока... пока Фаер Фокс форева!

Ускоряем сайт: чистим изображения

16 нояб. 2009 г. | | |

Трудно себе представить сайт без картинок. А, между прочим, картинки, после видео и звука, самая "тяжелая" часть сайта. Поэтому мы поговорим об уменьшении размера картинок без потери качества. Пакет утилит (jpegtran, pngout, pngrewrite, pngcrush, optipng), рассмотренных в статье, можно скачать отсюда.
И так, разберемся для начала с форматом PNG.
Для чистки png-файлов существует несколько утилит:
Pngout
Pngcrush
Pngrewrite
Optipng
Возьмем для примера утилиту pngout. Туториал по работе с ней находится тут http://advsys.net/ken/util/pngout.htm.
После банального прогона картинки (с опцией /k0, которая удаляет ненужные фрагменты из файла) утилиткой имеем следующие результаты:
Неплохо, правда? Утилита имеет множество параметров, которые позволяют более гибко оптимизировать изображения.
Теперь возьмемся за JPEG.
Зачастую JPEG-файлы содержат некоторое количество метаданных, которые включают:
1) комментарии
2) метаданные, нужные для приложения (например, для Photoshop)
3) EXIF-информацию, например, от фотоаппарата, которая может содержать дату фотографии и даже небольшое превью или аудио-запись!
Согласитесь, вряд ли нам все это нужно для использования картинки на сайте. А ведь все это лишние байты-килобайты :) ! Весь этот мусор можно совершенно безопасно удалить безо всякой потери качества (с учетом того, что jpeg-картинка теряет качество после каждого сохранения) отображения каждого конкретного пиксела. Для этого воспользуемся утилиткой jpegtran. Запускаем из командной строки

jpegtran -copy none -optimize -progressive img.jpg imgoptim.jpg
и получаем следующий результат:
Из картинки весом 21 Кб мы получили такую картинку такого же качества, только почти в 4 раза меньше размером!
Еще у нас есть GIF-формат. Советую его переводить в PNG, а потому ужимать описанными выше утилитами.
Ну и напоследок, учитывая, что все люди немного ленивы - да и просто неудобно десятки файлов вручную чистить - приведу скрипт (ложится в bat-файл), который автоматизирует чистку файлов в какой-то папке.
for %%f in (*.png) do pngout /k0 %%f
for %%f in (*.jpeg, *.jpg) do jpegtran -copy none %%f %%f
З.Ы. Спасибо за дельные советы Artri ;)

Ошибка 720

14 нояб. 2009 г. | | |

Недавно, помогая знакомым в настройке подключения к интернету через vpn, столкнулась с "ошибкой 720". И ничего не помогало, а лекарство от всех болезней - переустановка оси - применять не хотелось... Но после полной переустановки стека TCP/IP все заработало! Ниже приведена пошаговая инструкция, как это сделать.
1) Удаляем разделы реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock и HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock2 командой REG DELETE в консоли (Пуск->Выполнить) либо в редакторе реестра(regedit.exe) ищем и удаляем соответствующие ветки.

REG DELETE HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock
REG DELETE HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock2
2) Перезагружаемся
3) В папке %winroot%\inf найтите файл nettcpip.inf (перед редактирование лучше сделать резервную копию) и откройте его в текстовом редакторе (например Notepad).
Строки:
[MS_TCPIP.PrimaryInstall]
; TCPIP has properties to display
Characteristics = 0xA0 ; NCF_HAS_UI | NCF_NOT_USER_REMOVABLE
Изменяем на:
[MS_TCPIP.PrimaryInstall]
; TCPIP has properties to display
Characteristics = 0x80 ; NCF_HAS_UI

4) Сохраняем изменения в файле nettcpip.inf
5) Открываем Network Connections и щелкнув правой кнопкой мыши по свойству нужного нам сетевого подключения выбрать Install->Protocol->Add. Далее выбрать "have disk" и указать путь %winroot%\inf (обычно эта папка скрыта!)
6) Выбрать TCP/IP из списка. После этого вы опять попадете в окно свойств сетевого подключения, но для TCP/IP теперь кнопка Uninstall будет активна.
7)Выберите в списке This connection uses the following items протокол TCP/IP и нажмите кнопку Uninstall.
8) Перезагружаемся
9) Установить протокол TCP/IP аналогично шагам 5-8.
Папка %winroot% - папка windows на диске, где установлена ОС. Обычно, С:\windows.

Утилиты Minifuzz и BinScope от Microsoft

21 окт. 2009 г. | | |

Недавно компания Microsoft выпустила две новые бесплатные утилиты - Minifuzz и BinScope. Главное назначение этих утилит - помочь сторонним разработчикам в проверке своих программ на соответствие требованиям безопасности. Скачать их можно по ссылке http://msdn.microsoft.com/en-us/security/cc421514.aspx, где можно найти и другие бесплатные и полезные утилиты :)

Утилита Minifuzz представляет собой инструмент для обнаружения ошибок в коде путем подачи приложению в качестве входных параметров случайных данных. Согласно стандарту безопасной разработки Microsoft SDL (Secure Development Lifecycle – жизненный цикл безопасной разработки), каждый алгоритм и программный модуль должен проходить масштабную проверку на наличие переполнений буфера и других распространенных уязвимостей путем тестирования случайными входными данными (fuzzing). Если крупные разработчики программных продуктов уже давно внедрили эту технологию для своих производственных процессов, то независимые разработчики до сих пор редко использовали подобные методики. С появлением свободно распространяемой утилиты Minifuzz входной барьер на пути к методике тестирования случайными входными данными значительно снижается.

Утилита BinScope Binary Analyzer предназначена для проверки исполняемого кода на соблюдение множества общепринятых правил написания кода. Она обеспечивает расширенную проверку результатов работы программистов путем анализа самих исполняемых файлов. Например, проверяет, какая версия компилятора использовалась при сборке программы – конечно, для ответственных задач необходимо использовать самую актуальную версию компилятора. Также утилита BinScope уведомит тестировщика о том, что файл был скомпилирован без ключа /GS, который эффективно предотвращает атаки на приложение с использованием переполнения буфера.

Чтобы программу BinScope не могли использовать злоумышленники при поиске уязвимостей в чужих программных продуктах, утилита BinScope работает только тогда, когда пользователь имеет полномочный доступ к специальному набору отладочной информации для проверяемого исполняемого файла (private symbol) – в большинстве ситуаций эта информация недоступна никому, кроме самих разработчиков.

В последнее время компания Microsoft прилагает серьезные усилия по повышению качества не только собственных программ, но и инструментов разработки. Особенно это касается заботы о сторонних разработчиках Windows-приложений. Новые бесплатные утилиты Minifuzz и BinScope еще раз напоминают, что Microsoft не бросает этих разработчиков на произвол судьбы, что не может не радовать :)

Как проверить версию .Net Framework и установлен ли он вобще

15 окт. 2009 г. | | |

Типичная ситуация: есть приложение, использующее .Net Framework, и есть юзер, желающий использовать программу, но не имеющий .Net Framework. Итог: программа не запускается и выдает непонятную ошибку. И начинается поиск решения, как же проверить, установлен ли .Net Framework на конечной машине и требуемая ли версия установлена. Есть несколько вариантов действий - проверить реестр или проверить файловую систему. В первом случае воспользуемся веткой реестра

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft
Если тут существует ветка
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup
то в ветке
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP
можно найти все установленные версии .Net.

Готовое решение этого варианта вы можете найти тут http://msdn.microsoft.com/en-us/library/ydh6b3yb.aspx
Во втором варианте просмотреть установленные версии можно %windir%\Microsoft.NET\Framework.

В любом случае, выполнить проверку из программы, написанной на .Net Framework, невозможно. Значит, надо писать утилиту на С++ или другом языке, не требующем .Net Framework. Решение, которое понравилось мне больше всего - это использование batch-файла. Например, мне нужно проверить, установлена ли версия 3.5 и , если нет, запустить установку. Вот что получается:

@ECHO OFF
SET FileName=%windir%\Microsoft.NET\Framework\v3.5
IF EXIST %FileName% GOTO Skip
ECHO.You currently do not have the Microsoft® .NET Framework 3.5 installed.
ECHO.This is required for MyApplication.
ECHO.
ECHO.The Microsoft® .NET Framework 3.5 will now be installed on you system.
ECHO.After completion setup will run MyApplication.
ECHO.
Pause
SET FileName=
Start /WAIT .\files\dotnetfx35.exe
ECHO ON
:Skip
Start .\MyApplication.exe
Exit

Заметьте, что данный скрипт не проверяет, установлен ли фреймворк. В любом случае, если не существует в файловой системе пути %windir%\Microsoft.NET\Framework\ будет устанавливаться .Net, а после окончания установки будет запущено приложение.

Дни разработчика в Краснодаре

8 окт. 2009 г. | | |

7 октября сего года прошел семинар "Дни разработчика'09" в Краснодаре, участником которого к превеликой моей радости мне посчастливилось быть.
Семинар состоял из трех докладов и серии вопросов-ответов. Конечно, мне как silverlight-разработчику, интересно было послушать доклад "Обзор возможностей Silverlight 3 и Expression 3". К сожалению, доклад был крайне обзорным - все это уже было опубликовано в блогах и на сайте microsoft, когда вышел Silverlight 3, поэтому того, чего мне хотелось услышать - более глубокого анализа технологии - не было. Но это не беда, потому что была открыта великая тайна - почему у silverlight нет поддержки Опера. :) Так же еще раз была отмечена тенденция перехода от Software and Services к Software as Services.
Что еще понравилось - вслух была произнесена магическая фраза "мы уже думаем о Silverlight 4", но на все вопросы ответ был "не располагаем информацией".
Понравился последний доклад "Возможности Windows 7 для разработчиков". Но больше всего понравились кофе-брейки :) Отменный кофе, хочу сказать. Да и печеньки у них неплохие :). Вобщем, Microsoft знает, что нужно разработчику - кофе и печеньки!

Вторая общекрымская торрентовка

6 окт. 2009 г. | | |

3-4 октября в Алуште, с. Лучистое, прошло Вторая общекрымская торрентовка, посвещенная дню рождения любимого и лучшего трекера torrents.ru.
Впечатлений - море! Впечатления - только положительные! Огромное спасибо организатору - Probeg, респект и уважуха! А так же огромное спасибо всем, кто приехал, спасибо за замечательную компанию! :) :) :) С нетерпением жду следующей торрентовки! Ни капли, ни минуты, ни секунды не жалею, что поехала, оно того стоило!

Об алгоритмах....

1 окт. 2009 г. | | |

Едут в одном вагоне четверо программистов и четверо пользователей. У пользователей четыре билета на четверых, а у программистов один. Приходит пора предъявлять билеты. Программисты запираются в туалете, приходит контролер. Стучится, из сортира высовывается рука и протягивает билет. Контролер уходит. Пользователи все видят и им завидно.
Едут все те же пользователи и программисты обратно. Но на этот раз у пользователей один билет на четверых, а у программистов - ни одного. Приходит пора проверки билетов. Пользователи запираются в сортир. Приходит один из программистов и стучится в дверь. Ему высовывают билет. Он берет билет, программисты запираются в другом сортире. Приходит контролер...
Мораль: не всякий алгоритм, разработанный системным программистом, подходит для рядового пользователя.
(c)перто


Юзабилити

18 сент. 2009 г. | | |


— У вас это… юзабилити плохое.
— Мне надо, чтобы было просто и удобно.
— Я не моряк, чтобы разбираться, как его крутить.
— Мне жаль вас, у вас всё так сложно и неудобно.
Взято с http://malinnikov.ru

Альтернатива массивам для извращенцев

| | |

Как-то раз попросил знакомый решить такую вот задачку (цитирую):

смотри есть к примеру ряд переменных
перем1
перем2
перем3
можно ли как то обратиться
к ним в цикле например
Для сч = 1 по 3 Цикл
сообщить(Перем+Сч)
КонецЦикла

Первое, и адекватное, что приходит в голову - использовать массив. Но по условиям задачи, массив никак не подходил. Но вспомнилось, что-то где-то виделось... и вот, реализация данной задачи на php.

<?
for($i = 0; $i<10; $i++)
{
$commonVar = "varName".$i;
$$commonVar = "new value".$i; /*в этом месте переменной с именем выражения "varName".$i присваивается значение "new value*/
echo $$commonVar."<br />";
}
?>

15 сент. 2009 г. | | |


25 августа сего года компания DevExpress выпустила совершенно free очень полезную надстройку для Visual Studio 8 CodeRushExpress for C# and VB, скачать который можно тут.
CodeRushExpress предлагает расширенный набор функций для выделения кода, навигации в коде и объявлений классов и тд в коде.
Кроме того, CodeRush Xpress включает в себя более 50 рефакторингов, что, конечно же, просто замечательно. Если вы не счастливый обладатель полной версии CodeRush, то определенно must have в арсенале разработчика!

Разработчики всех стран, объединяйтесь!

13 сент. 2009 г. | | |

Замечательная тема, посвещенная Дню Программиста http://www.techdays.ru/DevDay/
Разработчики всех стран, объединяйтесь!

Законы программирования

12 сент. 2009 г. | | |

Закон программирования № 1. Ничто не работает так, как планировалось запрограммировать.

Закон программирования № 2. Ничто не программируется так, как должно работать.

Закон программирования № 3. Хороший программист характеризуется умением доказать почему задачу невозможно выполнить, когда ему просто лень её выполнять.

Закон программирования № 4. На решение проблемы уходит в три раза меньше времени, чем на обсуждение всех "за" и "против" её решения.

Закон программирования № 5. Обещанный срок сдачи - это аккуратно рассчитанная дата окончания проекта плюс шесть месяцев.

Закон программирования № 6. Программисту всегда известна последовательность действий, которыми пользователь может повесить его программу, но он никогда не чинит эту проблему, надеясь на то, что никому никогда не придёт в голову эту последовательность исполнять.

Закон программирования № 7. Настоящие программисты любят Windоws - все ошибки, сделанные по собственной тупости, можно свалить на Micrоsоft.

Закон программирования № 9. В случае голодовки настоящий программист ещё месяц сможет питаться едой, выковырянной из-под кнопок клавиатуры.

Закон программирования № 10. Настоящий программист уже как минимум поменял три залитых пивом клавиатуры.

Закон программирования № 11. Все, кто испытывает проблемы с настройкой кодировки, автоматически считаются неандертальцами.

Закон программирования № 12. Дилетантские разговоры о компьютерах вызывают резкую тошноту вплоть до приступов рвоты. Вопрос о том, как поменять "обои" в Windоws вызывает желание перерезать горло вопрошающему.

Закон программирования № 13. У большинства людей, нуждающихся в твоей помощи, причина ошибки в работе программы чисто генетическая.

Закон программирования № 14. HTML, HTTP, FTP, SMTP, TCP/IP, RTFM и т.д. - это слова, а не аббревиатуры.

Не знаю, откуда (с)перто, но забавно.

Работа с sqlite в С#. Часть 2. Опыты. Выводы.

10 сент. 2009 г. | | |

Итак, дошло время до практической части. Которая меня, скажем прямо, огорчила.
Так как хотелось использовать в своем проекте LinQ, а при попытке создать dbml-файлик штатными средствами студии выскакивает окошечко с ошибочкой (см. рис. ниже), то будем генерировать dbml с помощью DbMetal, о котором упоминалось в предыдущей части цикла.
Для начала создадим нашу базу данных, которая будет состоять из двух таблиц - Journal, главная таблица, в которую будут записываться факты поставки по конкретной дате, и таблица Items, в которой будут детали поставок по конктретной дате.

CREATE TABLE "journal" ("ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "Date" DATETIME DEFAULT CURRENT_DATE);
CREATE TABLE "items" ("ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "journalID" INTEGER NOT NULL , "supplier" VARCHAR DEFAULT supplier1, "store" VARCHAR DEFAULT store1, "amount" FLOAT DEFAULT 0)

Теперь сгенерируем dbml файл и подключим его в проект. Для генерации dbml напишем небольшой batch-файл, чтобы ручками впредь не выполнять эту операцию. Во-первых, в папке, где наша база, нужно расположить DbMetal.exe и библиотеки, которые он использует. Там же должен располагаться make_dbml.bat со следующим содержимым:

@echo on
DbMetal.exe -dbml:sample.dbml -provider:Sqlite -conn="data source=sample.sqlite"
dbMetal.exe -code:sample.designer.cs -namespace:SampleDataContext -provider:Sqlite -conn="data source=sample.sqlite"

Добавляем сгенерированный sample.dbml в проект (правый клик по проекту - Add->Existing item...).
Так как мы пишем тестовое приложение, которое, естественно, не может затронуть все аспекты, скажу о некоторых отрицательных моментах, с которыми мне довелось столкнуться. Во-первых, не поддерживается тип Boolean. Долго пришлось возиться в поисках проблемы - резко началось рушиться приложение, а оказалось, всего-навсего, не sqlite не поддерживает тип Boolean, который использовался в одной из таблиц базы данных. И, хоть альтернативу логическому типу очень легко найти (использовать тот же varchar (1)), все же очень неприятно. Во-вторых, (но это уже проблема не самого sqlite), при dbmetal почему-то не генерирует представления :( Вот так просто нас лишили крутой возможности. Опять же, ручками все делается. Но как-то неспортивно. После ковыряния в исходниках dbmetal, которые лежат в открытом доступе на svn, и перекомпиляции с включеной опцией views, стали генерироваться пустые классы. На этом решено было не тратить больше время на всякую ерунду. Ведь существуют платные хорошо работающие альтернативы, если кому надо.
И так, вернемся к нашему приложению. Его задача - отображать по выбранной дате все поставки за этот день. ГУИ будет таким:
TreeView - для отображения списка дат
ListView - для отображения поставок по датам
Теперь, собственно, будем все это оживлять.
Создадим класс DBClass, который будет заведовать работой с бд. Код:

class DBClass
{
private Main _connection = null;

public DBClass()
{
_connection = new Main(new XSqlConnection("Data Source=sample.sqlite"));
}

public List GetJournal()
{
List items = new List();
items = _connection.Journal.ToList();
return items;
}

public List GetItems(int journalId)
{
List items = new List();
items = _connection.Items.Where(i => i.JournalID == journalId).ToList();
return items;
}

public Items AddItem(Items item)
{
_connection.Items.InsertOnSubmit(item);
_connection.SubmitChanges();
return item;
}

public Journal AddJournal(DateTime date)
{
Journal item = new Journal() { Date = date };
_connection.Journal.InsertOnSubmit(item);
_connection.SubmitChanges();
return item;
}

public void DeleteItem(int id)
{
_connection.Items.DeleteOnSubmit(
_connection.Items.SingleOrDefault(i => i.ID == id)
);
_connection.SubmitChanges();
}

public void DeleteJournal(int id)
{
_connection.Journal.DeleteOnSubmit(
_connection.Journal.SingleOrDefault(i => i.ID == id)
);
_connection.SubmitChanges();
}
}

Теперь, все, что нам остается - брать и использовать методы класса в форме.
Инициализируем наше дерево:

private void InitTree()
{
foreach (Journal item in db.GetJournal())
{
AddJournalDate(item);
}
}

private void AddJournalDate(Journal item)
{
TreeNode node = new TreeNode(item.Date.Value.ToShortDateString());
node.Tag = item.ID;
tvJournal.Nodes[0].Nodes.Add(node);
}

Теперь, напишем обработчик события NodeMouseDoubleClick для отображения поставок по выбранной дате:

private void tvJournal_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (tvJournal.SelectedNode != null && tvJournal.SelectedNode.Tag != null)
{
int journalId = 0;
if (int.TryParse(tvJournal.SelectedNode.Tag.ToString(), out journalId))
{
lvItems.Items.Clear();
foreach (Items item in db.GetItems(journalId))
{
AddItem(item);
}
}
}
}
private void AddItem(Items item)
{
ListViewItem lvi = new ListViewItem(new string[] { item.Supplier, item.Store, item.Amount.ToString() });
lvi.Tag = item.ID;
lvItems.Items.Add(lvi);
}

Теперь научим наше приложение добавлять дату в список и удалять дату. Для удаления даты добавим триггер в таблицу Journal:

CREATE TRIGGER "main"."OnDelete" DELETE ON journal BEGIN Delete From items Where items.journalID = deleted.ID; END

Код обработки клика для кнопки "Удалить выбранную дату" выглядит так:

private void button2_Click(object sender, EventArgs e)
{
int journalId = (int)tvJournal.SelectedNode.Tag;
db.DeleteJournal(journalId);
tvJournal.Nodes[0].Nodes.Remove(tvJournal.SelectedNode);
}

Ниже приведены обработчики событий клика по кнопкам "Добавить поставку" и "Удалить выбранную поставку" соответственно:

private void addItemToJournal_Click(object sender, EventArgs e)
{
int journalId = 0;
if (int.TryParse(tvJournal.SelectedNode.Tag.ToString(), out journalId))
{
Items item = new Items() {
Amount = float.Parse( tbAmount.Text ),
Store = tbStore.Text,
Supplier = tbSupplier.Text,
JournalID = journalId
};
AddItem(db.AddItem(item));
}
}

private void DeleteItemFromJournal_Click(object sender, EventArgs e)
{
if (lvItems.SelectedItems.Count > 0)
{
int itemID = (int)lvItems.SelectedItems[0].Tag;
db.DeleteItem(itemID);
lvItems.Items.Remove(lvItems.SelectedItems[0]);
}
}

Вот и все. Поигрались и хватит :) Весь рассмотренный функционал можно воплотить и через ADO.NET, без пляски с бубном вокруг LinQ, но вы же сами знаете, что так не интересно :)
Исходник можно скачать тут.

Работа с sqlite в С#. Часть 1. Инструменты.

9 сент. 2009 г. | | |


Инструментов для работы с этой хоть маленькой, но удаленькой БД существует много. Есть и платные, и бесплатные решения. Полный список инструментов - и врапперов, и конвертеров, и менеджеров - вы найдете тут. Данная статья не дает на полный обзор и сравнительную характеристику всех средств для работы с sqlite. Так как в статье рассматривается версия БД под Windows, то инструменты, соответственно, для этой платформы.
Начнем с System.Data.SQLite - провайдера, обеспечивающего полноценную поддержку ADO.NET 2.0/3.5, поддержку design-time в VS, а так же много чего другого, о чем можно почитать тут http://sqlite.phxsoftware.com/
Еще один Linq2Sqlite провайдер - это DbLinq. Но последний официальный релиз за сентябрь 2008 года, хотя в свн проект постоянно обновляется. Адрес проекта http://code.google.com/p/dblinq2007/
Следующий продукт для работы с sqlite в .NET - это Mono (Mono.Data.SqliteClient), версия для sqlite3 которого базируется на коде предыдущего враппера. Сайт проекта http://www.mono-project.com/SQLite
Для работы с sqlite в Visual Studio компания DevArt приготовила специальный коннектор -
dotConnect for SQLite - который имеется в облегченной standard free-версии (нет поддержки linq и некоторых других фич) и в триал professional версии за 149.95$ для одного человека. Скачать бесплатную версию можно по ссылке http://www.devart.com/dotconnect/sqlite/download.html. Тут же находится документация и примеры.
Как говорится на сайте разработчика, dotConnect поддерживает ADO.NET Entity Framework, LINQ to Sqlite, так же есть специальные фичи для Winforms (гибкое связывание данных и др) и для ASP .NET, есть поддержка редактирования БД из VS, что очень и очень удобно.
Далее, удобная штука для работы с sqlite - SQLite Manager - это аддон для Firefox, который можно скачать по ссылке https://addons.mozilla.org/ru/firefox/addon/5817. Добавлена поддержка Firefox>3.5, что очень порадовало. Удобное дерево объектов БД, удобные диалоги при работе с БД (только слегка маниакальные, имхо), возможность экспорта таблиц/представлений/БД в csv/xml/sql формат, возможность импорта данных из этих же форматов и другие фичи предлагает данный плагин. Удобная и бесплатная вещь.
Следующая тулза - SQLite Administrator - поддерживает больше форматов для экспорта ( XLS / CSV / HTML / XML), есть функция мигрирования с QLite2 БД в SQLite3. Радует поддержка русского интерфейса. Полный список фич, а так же скачть программу можно по ссылке http://sqliteadmin.orbmu2k.de/
Так же для работы с sqlite есть удобная вещь SQLite Maestro, но это уже из области платных программ. Домашняя страничка программы с описанием всех фич находится по адресу http://www.sqlmaestro.com/en/products/sqlite/maestro/
Есть еще вот такая бесплатная программулина SQLite2009 Pro Enterprise Manager, живущая по адресу http://osenxpsuite.net/?xp=3&uid=managementtools, по этому же адресу живет и ее описание.
И, самая удобная, на мой взгляд тулза, это SqliteDeveloper от компании SharpPlus. Скачать можно тут http://www.sqlitedeveloper.com/sqlite-developer-sqlite3-database-manager

Работа с sqlite в С#. Введение.

8 сент. 2009 г. | | |

Бывают проекты, в которых необходимо хранение данных, объем и структура которых делает хранение в обычных файлах неудобным, а использование СУБД - слишком громоздкое и дорогое решение. Представьте, для программы весом в пару мегабайт, которая спокойно умещается на флешке, ставить SQL Server. Немного утрировано, но всё же...
Для решения подобного рода проблем очень хорошо подходят embedded-БД (встраиваемые БД), например, sqlite, firebird или из области объектных бд - db4o. Конечно, им всем далеко до полноценных СУБД, но не для конкуренции с ними создавались встаиваемые БД, а для облегчения распространения приложений, использующих небольшие БД. Понятно, что для достижения этой цели пришлось чем-то жертвовать, и каждый жертвовал, чем мог :) Так как разговор в данной статье должен идти о первой из списка embedded-БД - sqlite, то давайте как раз посмотрим, чем же порадуют нас разработчики.
Как ожидается из названия, данная embedded-БД должна быть лёгкой. Это правда - размер подключаемой библиотеки со всеми фичами, как говорят разработчики, меньше 300 КБ. К тому же, с ней легко работать, ее легко внедрять в создаваемое ПО, ее легко администрировать и еще много таких "легко". Sqlite распространяется на условиях "открытого исходного кода", скачать ее можно с официального сайта http://www.sqlite.org.
Чем хороша sqlite:

  • Поддержка языка запросов версии SQL92 (без особенностей типа процедур)
  • База данных сохраняется в одиночном файле на диске
  • Файл базы данных можно свободно разделить между процессами (например, тот же embedded firebird блокирует файл БД для монопольного использования)
  • Поддерживает базы данных размером до 2-х терабайт (241 байт)
  • Размеры строковых данных и BLOB данных ограничены только памятью
  • Нет никакой внешней зависимости от других библиотек
  • Поддержка операционных систем WINDOWS (практически все версии начиная с WIN95), *unix
  • Распространяется совершенно бесплатно

Чем плоха sqlite:

  • не Oracle или MS SQL.

Естественно, SQLite не предназначена, чтобы быть двигателем базы данных предприятия, это не вариант для использования в крупных проектах, разве как временную резервную БД (и звучит это даже как-то по-мазохистски). Как написано на официальном сайте движка, sqlite не предназначена, чтобы заменить Oracle, но для замены fopen().

Резиновый бэкграунд

27 авг. 2009 г. | | |

Как-то встала передо мной задача сделать для сайта резиновый бэкграунд - то есть такой, который меняет размеры под размер окна браузера автоматически.
Сделать это совсем не сложно.
Задумка такова - делаем два слоя с разными z-index, на первом, с меньшим z-index, располагаем фон, на втором слое, который будет сверху, располагаем контент.
Изображение, которое будет фоновым, делаем размером, который, как мы думаем, будет максимальным размером окна. В примере это 1680х1050.
В html это выглядит так:

<div id="page">
<div class="note">Wellcome!</div>
</div>
<div id="fon">
<img src="http://www.blogger.com/bg.jpg" alt="" />
</div>

CSS для первого слоя (бэкграунд):

#fon{
height:100%;
width:100%;
z-index:1;
min-width:1024px;
min-height:768px;
}
#fon img{
height:100%;
width:100%;
position:absolute;
}

CSS для слоя с контентом:

*{margin:0;padding:0;}
html, body{
width:100%;
height:100%;
min-width:1024px;
}
#page{
position:absolute;
top:0;bottom:0;right:0;left:0;
z-index:100;
}
.note{
border:none;
margin:0px;
width:100%;
float:left;
min-height:400px;
height:auto !important;
position:relative;
color:#FFFFFF;
font-size:20px;
font-family:Tahoma;
}

Пример можно посмотреть тут: http://wsite.in.ua/files/index.htm

Создание собственного Splash Screen в Silverlight

24 авг. 2009 г. | | |


Создавая приложение, хочется всегда сделать что-нибудь такое эдакое, чтоб красиво и оригинально :) Стильный дизайн формочек, кнопочек и прочих элементов gui, делающих их такими привлекательными для пользователя, что он аж не может удержаться, чтоб не потыкать их мышкой, это хорошо. Это просто отлично. Но это все подается пользователю после загрузки программы, а до этого .... До этого мы видим Splash Screen. Вспомним PhotoShop, CorelDraw - пока загружаются необходимые библиотеки, мы видим Splash Screen с логотипом программы. Очень умный и хороший шаг. Но это для десктоп приложений. В сфере web-приложений (сейчас я говорю о приложениях, созданных с помощью Java, Flex, Silverlight) начальная загрузка приложения гораздо более длительна по времени в силу ограничений пропускной способности интернет-канала. И , ожидая загрузки приложения, мы зачастую видим однотипные Splash Screens, которые встроены и идут по умолчанию для конкретных инстументальных средств. Например, для Silverlight картинка загрузки приложения такова:Красиво, но для коммерческого законченого продукта непременимо. Даже для себя хочется чего-нибудь другого....
Чтобы изменить Spash Screen в Silverlight , потребуются руки, немного фантазии , любимые инструменты (топор и секира :) ) и вобщем-то всё :)
Изменения Splash Screen условно можно разделить на два этапа - подговка нового Splash Screen и его внедрение. Вот так это пафосно звучит :)
И так, создаем новое Silverlight-приложение со следующими опциями:


Далее, в настройках проекта изменяем стартовую страницу с *.asp на *.html:
Теперь в папку ClientBin добави файл SplashScreen.xaml. Уточню, что нам нужен только обычный xaml, не UserControl! В этом файле будет наш Splash Screen. Открываем файл в Expression Blend и редактируем. Вот что получилось у меня:


<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="201" Height="89"
Background="#FFFFFFFF">
<canvas name="LayoutRoot">
<Rectangle x:Name="rectBorder" StrokeThickness="1" Stroke="#FFC8C8C8" Height="7" Width="200" HorizontalAlignment="Left"/>
<Rectangle name="rectBar" fill="#FF336EA9" height="7" width="0" horizontalalignment="Left" />
<textblock top="29" width="157" height="29" text="My Splash Screen" textwrapping="Wrap" fontsize="18" left="24" foreground="#FF1C516D"></textblock>
</canvas>
</canvas>


На этом, в принципе, первая часть заканчивается. Могу посоветовать добавить в клиентскую часть ресурсный файл и в него запихнуть чего-нибудь тяжелого, например, видео-ролик где-то размером с 20 мб. Это для того, чтобы успеть увидеть SplashScreen.
Теперь вторая часть - внедрение!
Создаем файл SpashSreen.js со следующим содержанием и добавляем его в серверную часть проекта (splash.web):


function onSourceDownloadProgressChanged(sender, eventArgs)
{
var rectBar = sender.findName("rectBar");
var rectBorder = sender.findName("rectBorder");
if (eventArgs.progress)
rectBar.Width = eventArgs.progress * rectBorder.Width;
else rectBar.Width = eventArgs.get_progress() * rectBorder.Width;
}




Это фунция будет вызываться каждый раз, как увеличится процент загрузки xap-файла приложения. Что и как делает функция, по-моему, понятно интуитивно.
Далее.
Открываем файл, который указали как стартовый при билде. У меня это splashTestPage.html. В раздел <head> страницы добавляем строку

<script type="text/javascript" src="SplashScreen.js"></script>.

Далее в теле документа Silverlight-объекту добавим такие параметры:


<param name="splashscreensource" value="ClientBin/SplashScreen.xaml">
<param name="onSourceDownloadProgressChanged" value="onSourceDownloadProgressChanged">

Все. Запускаем и наслаждаемся :)
Почитать еще об этой процедуре можно тут http://msdn.microsoft.com/en-us/library/cc903962(VS.95).aspx
Исходный код примера можно скачать тут http://wsite.in.ua/files/splash_screen.rar

Бесплатный пакер исполняемых файлов форматов PE32/PE32+/.NET/MAC-DARWIN.

28 июл. 2009 г. | | |

Недавно познакомилась с отличной программулиной - MPRESS.
MPress - это отличный бесплатный пакер для исполняемых файлов, который поддерживает кучу форматов - PE32/PE32+/.NET/MAC-DARWIN. Программа является бесплатной даже для коммерческого использования, что, несомненно, огромнейший плюс. МPress использует для сжатия собственную библиотеку LZMAT. которая неплохо (в моем случае было 1.89 мб стало 501 кб) сжимает исполняемы файлы и библиотеки, делая быстрее их загрузку при использовании сети или низкоскоростных внешних накопителей. Так же программа, по словам разработчика, использует in-place декомпрессию, что предотвращает разные проблемы с памятью. Конечно, как и любой упаковщик, программа обеспечивает защиту для пакуемого файла от реверсинга, но следует отметить, что защита работает только для непрофессиональных хакеров.
Об остальных фичах программы можно почитать на сайте http://www.matcode.com/mpress.htm , там же можно и скачать последнюю версию программы.
Единственный минус, которым обладает MPress, это отсутствие гуи. Но интерфейс коммандрной строки - это ж не повод отказаться от столько замечательной утилитки!

Маст хэв в арсенале разработчика.

О работе

2 июл. 2009 г. | | |

Лето, жара, море, золотой песок.... Отпуски, путешествия, дачи, огороды.... Сидя в кафе и попивая колу, вдалеке от моря, но рядом с Днепром широким, думаю мысли о работе...
Старая, но очень и очень точно описывающая процесс взаимопонимания всех участников разработки ПО картинка заставила в который раз улыбнуться....

Super Mario Bros Theme Orcestra

29 июн. 2009 г. | | |

Что не смогло не зацепить меня.... Аж слеза навернулась... Спасибо тем, кто это сделал!

Screenshoot C#

25 июн. 2009 г. | | |

А поведать в этой маленькой заметке я хочу о скриншотах. Точнее о том, как их можно программно реализовать на C#.
Скриншот, как известно, это моментальный снимок экрана. И делается он одним волшебным нажатием кнопки PrintScreen (PrtScr). Ловкость рук и никакого мошейничества... Далее снимок экрана помещается в буффер обмена Windows, откуда его можно вытащить не менее волшебным нажатием сочетания кнопок Ctrl+V или воспользовавшись пунктом меню "Вставить" графического редактора (или не графического.... каждый вставляет куда хочет ;) ).
А теперь, как это реализовать на C#.

PictureBox screenshootBox = new PictureBox();
//Нажмем на кнопочку PrintScreen
SendKeys.Send("{PRTSC}");
//А теперь получим изображение из буффера обмена
screenshootBox.Image = Clipboard.GetImage();


Вот и всё. Опять же только ловкость рук....
Правда, тут есть маленький нюанс - вышепреведенный код сделает скриншот исключительно окна активного приложения, так как класс SendKeys
предоставляет методы для отправки сообщений о нажатиях клавиш исключительно текущему приложению (http://msdn.microsoft.com/ru-ru/library/system.windows.forms.sendkeys.aspx). Если мы хотим получить скриншот всего экрана, то нужно поступить несколько иначе.
Во-первых, нам надо сделать активным десктоп, а после этого уже послать ему сообщение о нажатии кнопки. Но для начала нам надо получить хэндл десктопа.
Для этого потребуются функции FindWindow, FindWindowEx, SetForegroundWindow, которые нужно для начала импортировать из user32.DLL.

[DllImport("user32.DLL")]
public static extern IntPtr FindWindow(string lpszClass, string lpszWindow);
[DllImport("user32.DLL")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern bool SetForegroundWindow(IntPtr hwnd);


Только после этого их можно использовать в коде. Код для получения скриншота всего экрана прост:

//ищем хэндл дэсктопа
IntPtr vHandle = FindWindow("Progman", null);
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", null);
//сделаем активным окно по полученному хэндлу
SetForegroundWindow(vHandle);
//Нажмем на кнопочку PrintScreen
SendKeys.Send("{PRTSC}"); 


Вот и все.
Маленькую тестовую программку вы можете скачать отсюда (36 KB)

UPD: Спасибо за комментарии. Описанный выше способ получения скриншота лучше не использовать, а статью рассматривать как альтернативный способ выстрелить себе в ногу для сильных духом:
1) если кто-то очистит буффер обмена между вызовами MakeSreenshoot() и GetScreenshoot(), то сделанный снимок экрана пропадёт.
2) весь этот зоопарк с импортированием системных win32 dll в .net и вызовом методов оттуда не есть хорошая практика. Например, теряется кроссплатформенность кода (зависимость от win platform dll), нужны привелегии для импортирования dll ( SecurityPermission(SecurityPermissionFlag.UnmanagedCode) ). Гораздо лучше и проще воспользоваться средствами, предоставляемыми библиотекой .net. Несколько примеров таких решений можно найти в комментариях.