05.09.08
Tags: Полезные программы, SilverLight, WPF (.Net 3.0), Программирование / 2:30 pm , Victor Laskin
Давненько хотел написать какой нить гаджет для висты. Изначально хотел сделать это на WPF, но выяснилось что к гаджетам у микрософта другой подход. Посути гаджет - это html веб страница со всеми вытекающим. Поэтому только xbap или silverlight можно засунуть в гаджет (причем стало это можно сделать относительно недавно).
Посмотрев в каталоге гаджетов, гаджеты, которые показывают курс валют, и не найдя там ничего интересного, я решил написать свой монитор курсов. У нашего центрабанка есть прекрасный веб сервис, который предоставляет всю информацию о курсах валют за любой период.
Попытка использовать сильверлайт закончилась неудачно. Во первых, под 64-битной вистой сильверлайт не работает в 64-битном сайдбаре. Это можно обойти, запуская 32-ух битную версию сайдбара, но это уже извращение. Во вторых, из сильверлайта в гаджете нельзя нормально обратиться к вебсервису. Это связано с тем, что сильверлайт в гаджете не видит конфигурационных xml файлов и не может получить доступ. Есть workaround, который передает данные в сильверлайт контрол через скрипт AJAX, но я считаю это не очень красивым.
В итоге я сделал проще - гаджет просто показывает картинку с вебсервера, обновляя ее раз в час. А на сервере работает php скрипт по крону, который запрашивает данные у центробанка. Гаджет показывает текущий курс бакса и евро, на сколько он изменился за день и за неделю и график динамики курсов за 3 недели.

Скачать гаджет
Просто запустите скаченный файл, и гаджет установится. Если этого не произойдет и он откроется как зип архив, то можно на гаджете нажaть Open with… Sidebar. Если и это не поможет, то можно создать папку C:\Users\Ваше имя\AppData\Local\Microsoft\Windows Sidebar\Gadgets\CurrencyRates.gadget\ и в нее скопировать содержимое архива.
Direct link
14.08.08
Tags: WPF (.Net 3.0), Программирование / 6:03 pm , Victor Laskin
Состоялся релиз сервис пака .NET Framework 3.5SP1 и VS2008 SP1.
Доступны они тут.
The .NET Framework 3.5 SP1 delivers:
* Performance increases between 20-45% for WPF-based applications – without having to change any code
* WCF improvements that give developers more control over the way they access data and services
* Streamlined installation experience for client applications
* Improvements in the area of data platform, such as the ADO.NET Entity Framework, ADO.NET Data Services and support for SQL Server 2008’s new features
Direct link
28.06.08
Tags: WPF (.Net 3.0), Программирование / 12:21 pm , Victor Laskin
Уже несколько раз подряд за последние дни упираюсь в “пределы” WPF. Причём задачи были отнюдь не экзотические.
Класс Popup генерирует окно, которое располагается поверх всех окон в системе. Если вы хотите изменить это вам поможет только Win32 API:
[DllImport(“user32″, EntryPoint = “SetWindowPos”)]
private static extern int SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int cx, int cy, UInt32 wFlags);
const UInt32 SWP_NOSIZE = 0×0001;
const UInt32 SWP_NOMOVE = 0×0002;
const UInt32 SWP_NOACTIVATE = 0×0010;
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
static readonly IntPtr HWND_TOP = new IntPtr(0);
public static void Popup_SetZOrderTop(Popup pop)
{
IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(pop.Child)).Handle;
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}
С помощью этой функции также можно регулировать какое из окон находиться наверху в данный момент.
Получение текущих координат мыши в WPF возможно только с указанием контрола, относительно которого вам нужны эти координаты. А что делать если этот самый контрол нужно двигать?
public struct POINT
{
public int x;
public int y;
};
[DllImport(“user32.dll”)]
static extern bool GetCursorPos(out POINT point);
Еще пара полезных функций (поиск окна и получение его положения):
[DllImport(“user32.dll”, SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport(“user32.dll”)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
};
Direct link
07.06.08
Tags: Программирование / 7:45 pm , Victor Laskin
Водится за мной такой недостаток, люблю изобрести велосипед… Временами это плохо отражается на результате, но ничего не могу с собой поделать. С другой стороны, иногда, велосипед дорабатывается до мощного мотоцикла…
Недавно делал локализацию (поддержку многих языков в приложении) и понял что делал ее неверно, даже несмотря на то что с самого начала разработки софта продумал как она будет сделана. Казалось бы, что может быть проще, но только теперь для меня стало понятно как она должна выглядеть. Можно уложить это в небольшой список рекомендаций:
Структура:
- Локализованные (переведённые) строки должны храниться во внешнем файле открытого формата (txt или xml например)
- Новый язык нужно мочь подключать без перекомпиляции кода
- Приложение должно уметь на любом этапе исполнения переключать язык, перечитать строки из файла и “перерисовать” весь интерфейс
- Любая функция по выводу текста должна вызывать функцию вида GetLocalText(string Token), где токен - идентификатор выводимой строчки
- Необязательно: Хорошо бы разбить строки по группам и написать маленькую утилитку для их быстрого редактирования и перевода.
Для чего все это нужно, если есть стандартные методы локализации? Не вижу смысла в файлах ресурсов, в формате непонятном простым смертным пользователям, которые могут захотеть перевести ваш продукт на свой язык. Любой пользователь должен уметь перевести интерфейс и видеть изменения, которые он делает, сразу в интерфейсе, без перекомпиляции и перезапусков. Конечно лучше воспользоваться услугами профессиональных переводчиков, но это не всегда реально.
Актуальны еще рекомендации по языку ресурсных строчек, которые можно найти в MSDN.
Язык:
- Не разбивайте фразы на куски, переводчику будет трудно понять как именно эти куски переводить
- Аналогично нельзя использовать отдельно многозначные термины или слова, которые могут быть глаголом и существительным одновременно
- Учтите, что при переводе размер надписей может увеличиться процентов на 50-75%. Это самая существенная проблема в компактных интерфейсах.
Эти проблемы как раз и призвана решить возможность оперативного просмотра результатов своей работы переводчиком.
Direct link
01.06.08
Tags: .Net 2.0, Программирование / 4:18 pm , Victor Laskin
Оказывается метод, который возвращает список директорий (GetDirectories) иногда может их не сортировать. Вроде как это происходит на винтах под FATом. Поэтому если Вы где-то визуализируете список директорий, то рекомендую Вам вставить туда алгоритм ручной сортировки, ибо сделать это легко с помощью Array.Sort:
DirectoryInfo[] dirs = dir.GetDirectories();
//Сортировочка:
Array.Sort(dirs, 0, dirs.Length, new DirectorySort());
Сам принцип сортировки нужно оформить ввиде класса реализующего интерфейс IComparer:
class DirectorySort : System.Collections.IComparer
{
public int Compare(object x, object y)
{
DirectoryInfo d1 = x as DirectoryInfo;
DirectoryInfo d2 = y as DirectoryInfo;
return String.Compare(d1.Name, d2.Name, true, CultureInfo.CurrentCulture);
}
}
Сортировка тут не различает заглавные-прописные буквы и учитывает CurrentCulture.
Direct link
13.05.08
Tags: WPF (.Net 3.0), Программирование / 11:29 pm , Victor Laskin
Вышла бета .NET 3.5 Service Pack 1 и Visual Studio 2008, скачать можно тут.
О нововведениях можно почитать тут. Обещаться большой прирост скорости холодной загрузки приложений, а также общей скорости работы WPF, рендеринга текста и битмап-эффектов. Также интересна прямая поддержка DirectX и шейдерных эффектов под WPF. Причём воспользоваться этими эффектами будет легко. Например, код

добавит под кнопку аппаратную тень:

Еще одна новая возможность заслуживает особого внимания - New .NET Framework Client Profile Setup Package. Это возможность создать компактный дистрибутив для машин, на которых не установлен .Net Framework, в котором будут содержаться только нужные части фреймворка:

Также много чего нового для удобства разработки веб приложений и работы с данными (ADO.NEТ Entity framework и ADO.NET Data Services).
Обещано, что это последняя бета и релиз совсем скоро.
Direct link
12.05.08
Tags: Программирование / 11:59 am , Victor Laskin
Оказалось, что совсем недавно вышла новая версия (Beta 2.0) технологии CUDA от NVIDIA. Эта технология позволяет использовать мощности графического ядра видеокарт серии geforce 8×00 и выше для математических расчётов. При этом алгоритмы, которые допускают распараллеливание, могут показать огромный выигрышь в производительности.

До недавнего релиза эта технология проходила мимо меня, так как просто не работала под 64-х битной Вистой. Но вот наконец она заработала и я поставил себе новые дровишки, cuda sdk и cuda toolkit. Я хотел прикрутить ее к своему проекту по обработке фото PerfectPhotos. Но, к сожалению, оказалось, что драйвера еще сыроваты и начали спонтанно перезапускаться в один прекрасный момент (когда я даже не работал с cuda), а потом дело дошло и до синего экрана, что под вистой является большой редкостью (лично у меня).
А тем временем NVIDIA и iXBT проводят конкурс для разработчиков (об этом я узнал тут).
Direct link
08.05.08
Tags: .Net 2.0, Программирование / 3:07 pm , Victor Laskin
В любой книжке по шарпу рассказывают о том, что такое сериализация объектов. Напомню сериализация - это просто сохранение всех свойств объекта, например, на жесткий диск для последующей загрузки (десериализации) и использования в дальнейшем. Достаточно написать волшебное слово
[Serializable]
перед описанием объекта, и его уже можно легко сохранить используя класс BinaryFormatter из System.Runtime.Serialization. Казалось бы все просто и чего еще можно хотеть… Рассмотрим ситуацию когда ваш объект изменяется в процессе написания новых версий программы. Вы добавите новое свойство и обнаружите, что чтение (десериализация) старых данных перестало работать, так как объект изменился. Можно управлять десериализацией вручную, однако это накладно.
Так вот, чтобы избавиться от этих проблем можно написать свой [де]сериализатор используя Reflection:
private static void WriteObject(object obj, StreamWriter writer)
{
Type t = obj.GetType();
PropertyInfo[] pi = t.GetProperties();
writer.WriteLine(Begin(t.Name));
//Store all props
foreach (PropertyInfo p in pi)
writer.WriteLine(FormXmlLine(p.Name, p.GetValue(obj, null).ToString()));
writer.WriteLine(End(t.Name));
}
private static string Begin(string name)
{
return “<” + name + “>”;
}
private static string End(string name)
{
return “</” + name + “>”;
}
private static string FormXmlLine(string name, string value)
{
return “ <” + name + “>” + value + “</” + name + “>”;
}
Метод просто записывает значения всех свойств объекта в формате XML. Его можно легко расширить для сохранения вложенных объектов и коллекций, добавив проверку типа свойства и видоизменив к рекуррентному виду. Хотя это не всегда нужно.
Прочитать сохраненный объект можно так:
//Lets read
public static void ReadObject(string filename, object Obj)
{
Type ObjType = Obj.GetType();
using (XmlReader reader = XmlReader.Create(filename))
{
while (reader.Read())
{
if (reader.IsStartElement())
{
if (reader.Name == ObjType.Name)
{
//Do nothing!
}
else
{
PropertyInfo[] pi = ObjType.GetProperties();
foreach (PropertyInfo p in pi)
if (p.Name == reader.Name)
{
reader.Read();
//Read the text content of the element.
if (p.PropertyType.Name == “String”)
p.SetValue(Obj, reader.ReadString(), null);
if (p.PropertyType.Name == “Int32″)
p.SetValue(Obj, reader.ReadContentAsInt(), null);
if (p.PropertyType.Name == “Int64″)
p.SetValue(Obj, reader.ReadContentAsInt(), null);
if (p.PropertyType.Name == “Long”)
p.SetValue(Obj, reader.ReadContentAsLong(), null);
}
}
}
}
}
}
Дополнив это дело нужными типами данных и проверкой ошибок, можно легко сохранять и читать объекты. Но, главное, теперь классы сохраняемых объектов можно видоизменять не заботясь о сериализации. Понятно, что формат XML можно заменить любым другим по вкусу и сохранять не на диск, а в базу данных.
Direct link
03.05.08
Tags: .Net 2.0, Программирование / 12:42 pm , Victor Laskin

Кто не в курсе, Flickr - это очень популярный хостинг фото и видео. Википедия утверждает, что в нем более 2 биллионов изображений. Ко всему этому богатству можно получить доступ из вашего .net приложения.
Самая сложная часть - это авторизация.
- Сначала Вам нужно зарегистрироваться на сервере. (как не странно
)
- Затем нужно получить ключи тут. Это две строчки - ApiKey и Secret, которые будут использоваться в вашем коде для получения доступа к сервису фликр (но не к вашему акаунту).
- Нужно скачать библиотечку Flickr.Net
- Подключив скачанную библиотеку (using FlickrNet;), Вы уже можете получить доступ к публичному контенту фликра, который доступен без авторизации.
flickr = new Flickr(ApiKey, SharedSecret);
- Но чтоб получить доступ к аккаунту нужно проделать еще одну операцию - получить Token.
tempFrob = flickr.AuthGetFrob();
string flickrUrl = flickr.AuthCalcUrl(tempFrob, AuthLevel.Write);
System.Diagnostics.Process.Start(flickrUrl);
Этот код запустит браузер, в котором пользователь должен подтвердить, что дает доступ вашему софту.
- Только теперь можно получить полный доступ:
Auth auth = flickr.AuthGetToken(tempFrob);
flickr.AuthToken = auth.Token;
- Полученный токен можно сохранить и использовать для быстрой авторизации в дальнейшем:
flickr = new Flickr(ApiKey, SharedSecret, Token);
- Теперь можно загрузить парочку фотографий:
string photoId = flickr.UploadPicture(file, title, descripton, tags);
Из бонусов механизма подобной авторизации можно отметить возможность просмотра статистики использования ApiKey, то есть вашего софта, которую можно найти там же, где вы получали ключи.
Что касается самого сервиса - обнаружил, что есть серьезное ограничение на размер фото, что меня лично, как любителя лучшего качества, не устраивает.
Напоследок - моя страница на фликре
Direct link
24.04.08
Tags: WPF (.Net 3.0), Программирование / 12:34 pm , Victor Laskin
А знаете ли Вы, что в XAML можно биндинг описать вот так:
<Border.Background>
<Binding Path=“Background“>
<Binding.RelativeSource>
<RelativeSource Mode=“FindAncestor“ AncestorType=“{x:Type ListBoxItem}“ AncestorLevel=“1“/>
</Binding.RelativeSource>
</Binding>
</Border.Background>
То есть можно связать свойство элемента с его родителем-контейнером. Этот биндинг очень удобно использовать при написании всяких ControlTemplate. В данном примере приведен кусок из шаблона элемента листбокса, который содержит в себе некий элемент оформления Border. Так вот цвет заливки этой рамки на элементе можно привязать к цвету самого элемента. Удобно.
Direct link
« Previous entries