В Windows XP появились встроенные подсказки, которые выводятся в текстовом поле, пока пользователь не поставит туда курсор. По-английски они называются cue banners, а вот русский термин мне не известен (Language Portal не помог).
Необходимые действия для создания кьюшки в обычном дотнетовском текстовом поле уже подробно описаны до нас; нам нужно только применить рецепт для вытаскивания текстового поля из девэкспрессовских контролов.
Итак, необходимые объявления:
private const int EM_SETCUEBANNER = 0x1501; private const int EM_GETCUEBANNER = 0x1502; [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern Int32 SendMessage( IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
Установка кьюшки на девэкспрессовский контрол (помним, что контролы DevExpress содержат текстовое поле в качестве дочернего контрола):
foreach (Control control in buttonEdit1.Controls) { if (control is TextBox) { WinApi.SendMessage(control.Handle, WinApi.EM_SETCUEBANNER, 0, "Cue banner"); } }
Вот так выглядит результат:
К сожалению, кьюшки абсолютно стандартны и ничего не знают о темах девэкспресса, поэтому на инверсной теме они выглядят довольно убого.
Тэги: c#, работа, советы
Комментарии (1)
Многим известно, что сочетание Ctrl+U в Visual Studio приводит букву под курсором к нижнему регистру, а Ctrl+Shift+U, наоборот, к верхнему. Обе команды заодно передвигают курсор вправо на одну позицию, что позволяет, зажав клавиши, изменить регистр у целого слова.
Однако мало кто знает, что модификатор Ctrl+Alt+Shift включает «решарперовский» режим реорганизации кода, который позволяет переупорядочивать блоки кода, операнды бинарных операций и аргументы методов.
Рассмотрим последний пример подробно. Ставим курсор на один из операндов бинарной операции (например, операции присваивания) и зажимаем Ctrl+Alt+Shift. Появляется подсказка; следуя ей, нажимаем стрелку влево, и операнды меняются местами. Отпускаем Ctrl+Alt+Shift.
Так же меняются местами аргументы в определении методов. А нажимая стрелку вверх или вниз, можно перемещать блоки: одиночные операторы, составные операторы и даже целые методы.
Редакция от 15 октября 2009
Тэги: visual studio, работа, советы
Написать комментарий
Концепция производного класса — это адаптация префиксной нотации классов, принятой в Simula, и уже поэтому она схожа с концепцией подкласса в Smalltalk. Названия «производный» и «базовый» были выбраны потому, что я никак не мог запомнить, что есть sub, а что — super, и заметил, что такие сложности возникают не только у меня. Вот ещё одно наблюдение: для многих тот факт, что подкласс обычно содержит больше информации, чем его суперкласс, кажется неестественным.
Бьёрн Страуструп. Дизайн и эволюция C++. М.: ДМК Пресс; Спб.: Питер, 2007.
Зато по суб-/супер- (или под-/над-, если угодно) сразу видно, кто из них шире, а кто ýже в смысле принципа подстановки Лисковой. Говоря в терминах смолтока, трудно забыть, что субкласс должен удовлетворять контракту суперкласса. А вот производный класс явно расширяет базовый, отсюда и квадрат, производный от прямоугольника.
Подложил нам Страуструп хрюшку, короче.
Тэги: программирование, язык
Написать комментарий
Загадка. Что напечатает следующий отрывок кода на языке си#?
var args = new DrawItemEventArgs( g, font, rect, 0, DrawItemState.Selected, Color.Black, Color.Goldenrod); Console.WriteLine("{0}, {1}", args.ForeColor, args.BackColor);
Если кто-то думает, что там будет Black
или Goldenrod
, он ошибается.
Color [HighlightText], Color [Highlight]
А вся фишка в том, что свойство BackColor
в DrawItemEventArgs
реализовано так:
public Color get_BackColor() { if ((this.state & DrawItemState.Selected) == DrawItemState.Selected) { return SystemColors.Highlight; } return this.backColor; }
Редакция от 15 октября 2009
Тэги: c#, wtf, работа
Написать комментарий
На работе мы подняли сайт на моём движке, конечно, не такой, как «Непостижимые поля». Там всё чинно: полезные советы из жизни си#, объявления о новом инфраструктурном коде и прочая программистская рутина.
Интересно другое. Я вновь получил то, чего мне, оказывается, не хватало два последние года: мгновенную отдачу при разработке движка.
Оно понятно, что отдельно должна быть боевая установка с реальными данными, а отдельно — тестовая, где фичи отлаживаются, а баги устраняются. И что даже мелкие изменения, а уж тем более крупные переделки надо устраивать в тихом уголке, где ничего нельзя запортить.
Но где тогда брать те эмоции, которые сопровождают правку кода на горячую, прямо по живому, на боевом сайте? Страх ошибиться пополам с предвкушением: вот сейчас, ещё строчка — и фича заработает!
Нет, крупные изменения, конечно, нельзя вносить не запланировав, не продумав, не оттестировав. Но зато и мелочью, если понимаешь, что эффект от неё появится через месяц-другой, после регулярного обновления, заниматься не хочется совершенно. Зачем? Успеется.
Редакция от 8 октября 2009
Тэги: indiana, программирование, работа
Написать комментарий
class Poo : Exception { } // ... throw new Poo();
Редакция от 15 октября 2009
Тэги: c#, fun
Написать комментарий
В русской версии Visual Studio 2008 меню Build называется «Построение». Понятно, что слово сборка уже занято (так перевели термин assembly тогда, когда русской «студии» не было даже в планах).
Только вот build всегда назывался по-русски сборкой (или билдом), так что испугавшимся омонимии составителям глоссария следует идти лесом. Построение и перестроение — это не про программные продукты, а про солдат на плацу.
Все, кого я знаю, по-прежнему говорят «сборка».
Редакция от 22 сентября 2010
Тэги: visual studio, русский язык, трудности перевода
Комментарии (2)
Есть три традиционных способа называть языки программирования в русском тексте: кириллицей строчными (питон), кириллицей с прописной (Питон), латиницей с прописной (Python). Старые языки ещё иногда пишут всеми прописными (BASIC, ФОРТРАН).
Но почему мы говорим на логлане, эсперанто, интерлингве, а программируем на C++, ФОРТРАНе и Паскале?
Понятно, что последний способ наиболее однозначный, и так или иначе придётся указывать оригинальное название, если, например, упоминается малоизвестный язык — какая-нибудь Cobra.
К сожалению, русский язык просит падежей, а выражения писать на Python-е, функции Lisp’а выглядят уродливо — и по тексту неизбежно расползаются паразитные конструкции типа в языке Lisp.
А уж если русифицировать названия языков программирования, то лучше записывать их так же, как естественные: со строчной буквы. В конце концов, по-английски принято говорить не только Python и Fortran, но и English и Russian.
Забавный побочный эффект такого способа написания: книга Василеску будет называться просто и со вкусом: «Прикладное программирование на языке ада».
Редакция от 17 августа 2009
Тэги: лучшее, программирование, русский язык
Комментарии (7)
Самый важное в этой книге: она заставляет задуматься об отвратительном устройстве множества простых вещей, от электронных часов до программ. Проблема, которую идентифицирует Купер, состоит в том, что разработчики и пользователи хотят разного, но первые не могут стать на место вторых.
Купер считает, что заниматься проектированием взаимодействия должны специально обученные люди (и ни в коем случае не программисты). Думаю, он заблуждается: просто нужно помнить, на каком стуле сидишь.
В книге есть интересная метафора: заходя в самолёт, пользователи хотят повернуть направо (в салон), а программисты — налево (в кабину пилотов). Первые хотят спокойствия и комфорта, вторые готовы променять уют на контроль. Метафора парадоксальная и верная, но даже самые рьяные авиаэнтузиасты вряд ли согласились бы всякий раз, когда летят, сами пилотировать. Но Купер не принимает это в расчёт: он полагает, что энтузиасту не понять пассажира, а программисту — пользователя.
Разумеется, разделение на проектировщиков взаимодействия и программистов — такая же чушь, как деление людей на технарей и гуманитариев по принципу «тройка по русскому — технарь, тройка по физике — гуманитарий». Если верить Куперу, программист — это человек, неспособный разработать интерфейс. Видимо, проектировщик взаимодействия должен характеризоваться в первую очередь неумением писать код.
Автор совершенно верно указывает на то, что принципы взаимодействия с пользователем отличны от принципов взаимодействия с компьютером. Однако вывод о том, что первым и вторым должны заниматься разные люди, мягко говоря, необоснован.
Вообще конкретные рекомендации Купера относительно метедик проектирования (профессия проектировщика, использование т. н. «персонажей») интересны, однако теряются на фоне основной идеи книги: проектирование человеко-машинного интерфейса — это отдельная и важная задача, а не подэтап написания кода.
Редакция от 28 апреля 2009
Тэги: программирование, свежие отзывы
Комментарии (2)
Кому-то снятся чужие сны, а мне время от времени приходят в голову чужие идеи. Такие, которые уже до тебя придуманы и где-то реализованы, и, если их применишь, окружающие неизбежно решат, что ты их оттуда целиком и утянул. Вот примеры.
Недавно пришло мне в голову, что в багтрекере правильнее было бы классифицировать случаи не просто по важности (blocker, critical, major, minor, trivial), а минимум по двум параметрам: серьёзности и вероятности. Тогда, если бы серьёзность и вероятность задавалась как величина в диапазоне 0..1, то важность можно было бы получить простым перемножением.
К счастью, добрые люди меня просветили: эта модель давно используется в методиках по управлению рисками. Да и задолбаешься всё это в трекер вбивать, на самом-то деле.
Где-то с полгода назад я окончательно определился, как удобнее всего оценивать книги и что делать с полемикой, которая неизбежно появляется везде, где читателям предлагают «оставить рецензию». В первом случае я придумал для себя простую и симметричную шкалу −2..+2, которая достаточно проста для того, чтобы соотнести впечатление с определённой цифрой шкалы. Во втором — решил отделить мух от котлет, разнеся рецензии (отзывы) и обсуждение (флуд) пользователей.
И то, и другое предназначалось для моей многострадальной, уже больше года не могущей добраться до веба библиотеки. Но — вот незадача! — обе эти идеи много раньше пришли в голову разработчикам «Яндекс-маркета».
Даже немножко грустно становится.
Тэги: reflection, webdev, программирование
Комментарии (1)
Google Desktop Search отображает результаты поиска по дискам компьютера при помощи специального сервера, который обслуживает запросы с интерфейса lo. При этом результаты поиска отображаются в виде веб-страницы, на которой есть ссылки на открытие как найденных файлов, так и папок, в которых они лежат. Ясно, что простой ссылкой вида
<a href="d:\documents\plan.doc">plan.doc</a>
здесь не обойдёшься. Вместо этого ссылка указывает снова на локальный сервер, который и открывает файл или папку.
Я приспособил эту идею вот для чего. У меня дома есть сервер, на котором, во-первых, лежат разные файлы, а, во-вторых, крутится интранет-сайт. Файлы просто находятся в общей папке (\\serv\share), которая подмонтирована к каждому из компьютеров сети как сетевой диск (S:). Таким образом, к файлу plan.doc, лежащему в папке share\docs, можно обратиться с любого компьютера по адресу S:\docs\plan.doc.
Теперь собственно задача. Я хочу иметь возможность поставить с интранет-сайта (доступ к которому есть только изнутри сети) ссылку на этот документ.
Я написал небольшой сценарий на питоне. Этот сценарий запускает сервер (применён BaseHTTPServer) на порту 8080, каковой сервер отвечает на пришедшие запросы, открывая при помощи функции startfile() папку, имя которой было передано в строке запроса:
def browse(path): folder = normpath(unquote(path).decode('utf-8')) startfile(folder)
Этот сценарий был добавлен в автозагрузку на всех компьютерах сети. Теперь для создания ссылки на share\docs\plan.doc можно использовать такой код:
<a href="http://localhost:8080/s:/docs/plan.doc">plan.doc</a>
Некоторые детали, такие как проверку реферера для защиты от посторонних ссылок, я опустил для краткости.
Редакция от 18 мая 2010
Тэги: python, webdev
Написать комментарий
Внимание программистов, мегафункция:
function Return() { return; }
В нашем продакшн-коде, помню, как-то раз мне встретилось следующее:
public void DoSomething() { // много кода return; return; }
Тоже дао.
Тэги: wtf, программирование, работа
Написать комментарий
«Я продал душу „Майкрософту“. Поставь „Студию“ 2008 и присоединяйся!» —
как бы говорит нам человек на фото.
Редакция от 27 ноября 2009
Тэги: screenshots, visual studio, wtf
Комментарии (3)
Ну не из грязных же носков php-кодеров и script kiddies он [искуственный интеллект] зародится.
И что ему, бедному, зародившись, делать в сети, рассчитанной на присутствие миллионов злонамеренных естественных интеллектов, отточенных миллиардами лет биологической и десятками тысяч — социальной эволюции.
Будет, как домашняя кошка, ластиться к хозяину, чтобы кормил вовремя, и мышей таскать.
Редакция от 17 сентября 2008
Тэги: интеллект, программирование, цитаты
Комментарии (1)
Неделю назад я озаботился установкой багтрекера (это событие чудесным образом совпало по времени с моментом моего знакомства с «джирой» на работе). За эту неделю я успел вбить туда 58 «случаев» (case) и закрыть 8 из них.
Багтрекером я пользуюсь пока исключительно для «индианы»: другими проектами я занимаюсь так редко и так мало, что для них трекер не нужен.
Раньше я сначала держал баги в голове, потом записывал их в виде скрытых (и не очень) записей на сайте, пробовал приспособить для этого гостевую. В какой-то момент решил хранить их в OneNote, но замечаний оказалось слишком много, чтобы можно была их эффективно сортировать.
Сейчас же я распределил баги, замечания и идеи по реализации новой функциональности не только по важности, но и по номеру целевого релиза. К примеру, реализация RSS-ленты для конкретного тэга очень важна, но не для ближайшего релиза, а для того, в котором я собираюсь вернуть некогда существовавший многоязычный интерфейс.
А вот важность задачи «убрать ссылку „Регистрация“ со страницы входа в систему» сама по себе менее важна, но разобраться с ней надо до ближайшего релиза.
Такая организация задач позволяет, как это ни плоско прозвучит, выделить самые приоритетные дела и заниматься ими, а не разрываться между кучей «самых страшных» багов.
К сожалению, у меня нет возможности пользоваться функциональностью по оценке сложности работы, на основе которой можно подсчитывать дату ближайшего релиза. Увы: посвящать время разработке движка я вынужден урывками.
Редакция от 11 июля 2009
Тэги: software, warmland, программирование
Написать комментарий
Казалось бы, задача проще некуда, из тех, что сможет сделать даже студент-первокурсник. Но нет.
Мы с паре с моим непосредственным начальником разрабатывали участок кода, связанный с отрисовкой изображения. В какой-то момент возникла необходимость построить по двум точкам прямоугольник со сторонами, параллельными осям. Понятно, что для этого нужно проверить, что пары x и y-координат упорядочены, и обменять их, если это условие не выполнено. Я, не долго думая, написал следующий код:
int t = y1; y1 = t; y2 = y1;
Мы запустили тестовое приложение и поняли, что что-то пошло не так. Мой начальник сказал: «А, ясно, да ты тут ошибся в обмене!» — и исправил мои три строчки на вот такой вариант:
int t = y2; y1 = t; y2 = y1;
Программа снова не заработала. Тут мы наконец остановились и поняли, что оба не смогли с первого раза правильно написать обмен двух переменных. Для очистки совести мы подозвали коллегу и попросили его быстро, не проверяя себя, написать на бумажке решение злополучной задачи. Вот что у него получилось:
int t = y2; y1 = y2; y2 = t;
Поиск ошибок в вышеприведённых примерах, а также правильного решения задачи мы оставим читателю в качестве самостоятельного упражнения.
Редакция от 15 октября 2009
Тэги: c#, wtf, работа
Комментарии (2)
В текстовых полях, предназначенных для ввода имён файлов, в Windows, как правило, включено автодополнение, позволяющее быстро ввести имя файла с клавиатуры, не боясь ошибиться.
Для реализации аналогичной функциональности в .NET-приложении можно воспользоваться функцией SHAutoComplete.
Для использования функции потребуется объявить её, как описано на pinvoke.net:
[Flags] public enum AutoCompleteFlags : uint { SHACF_DEFAULT = 0x00000000, SHACF_FILESYSTEM = 0x00000001, SHACF_URLALL = (SHACF_URLHISTORY | SHACF_URLMRU), SHACF_URLHISTORY = 0x00000002, SHACF_URLMRU = 0x00000004, SHACF_USETAB = 0x00000008, SHACF_FILESYS_ONLY = 0x00000010, SHACF_FILESYS_DIRS = 0x00000020, SHACF_AUTOSUGGEST_FORCE_ON = 0x10000000, SHACF_AUTOSUGGEST_FORCE_OFF = 0x20000000, SHACF_AUTOAPPEND_FORCE_ON = 0x40000000, SHACF_AUTOAPPEND_FORCE_OFF = 0x80000000, } [DllImport("shlwapi.dll", ExactSpelling = true, PreserveSig = false)] public static extern Int32 SHAutoComplete( IntPtr hwndEdit, AutoCompleteFlags dwFlags );
Для активации автодополнения в обычном текстовом поле достаточно такого вызова:
SHAutoComplete(textBox1.Handle, AutoCompleteFlags.SHACF_FILESYSTEM);
Если же необходимо включить автодополнение в элементах управления ButtonEdit
или TextEdit
из библиотеки DevExpress, то код будет немного сложнее:
foreach (Control control in buttonEdit1.Controls) { if (control is TextBox) { SHAutoComplete(control.Handle, AutoCompleteFlags.SHACF_FILESYSTEM); } }
Дело в том, что элементы DevExpress не являются текстовыми полями, а включают их в качестве дочерних элементов.
Вот так выглядит автодополнение в элементе ButtonEdit
:
Редакция от 15 октября 2009
Тэги: c#, screenshots, советы
Написать комментарий
От создателей edlin и command.com.
Редакция от 27 ноября 2009
Тэги: potd, screenshots, visual studio, wtf, работа
Комментарии (2)
This is how I used to comment my code, twenty years ago (Note: dramatization):
/** * By the time we get to this point in the function, * our structure is set up properly and we've created * a buffer large enough to handle the input plus some * overflow space. I'm not sure if the overflow space * is strictly necessary, but it can't hurt. Next we * have to update the counter to account for the fact * that the caller has read a value without consuming * it. I considered putting the counter-increment on * the shoulders of the caller, but since it meant every * caller had to do it, I figured it made more sense to * just move it here. We can revisit the decision down * the road if we find some callers that need the option * of incrementing it themselves. */ counter++; // increment the consumed-value counter
Не зря всё-таки этого товарища критикуют за слишком длинные заметки. Дело ведь не в длине, дело в плотности текста. Стив сам напоминает двухлетнюю девочку Эмили: он несколько раз повторяет одну и ту же мысль. Неужели для вывода о том, что излишнее употребление метаданных вредно, необходимо 10 экранов текста? Зачем подробно — и ядовито! — рассказывать об ошибках, которые допускают начинающие программисты (к слову, далеко не все).
Да, чрезмерная любовь к статической типизации может привести к плачевным результатом. Но это же общее правило! Use it, don’t abuse it. Вот и всё. Да, нужно балансировать между строгостью и гибкостью. Верная мысль, но не особенно новая.
В общем, слово rants, вынесенное в заговок блога, не совсем точно характеризует его заметки. Это даже не пустословие, а скорее нытьё.
Тэги: ненависть, программирование, ссылки
Написать комментарий
Поставил себе в Visual Studio шрифт Consolas. Выглядит очень приятно, гораздо меньше режет глаз, чем засечки «курьера».
Шрифт поставляется с «вистой». Также Майкрософт предлагает скачать его, но только пользователям Visual Studio.
Редакция от 15 октября 2009
Тэги: vista, visual studio, работа
Написать комментарий
fs = []
for x in [1, 2, 3]: fs.append(lambda : x) for f in fs: print f(),
Вот такая простая программа выводит 3 3 3, хотя вроде как должна 1 2 3. Кто может объяснить, почему?
Update: Ответ Глайдера.
Редакция от 15 октября 2009
Тэги: python, tech
Комментарии (2)
Бритьё похоже на программирование testing-first. Сначала делаешь тестовое покрытие (мажешься пеной). Потом это покрытие реализуешь (бритвой). Конечно, если что-то не заспецифицировал вначале, то можно и не побрить, зато с пеной на лице точно из ванной уйти не потянет.
Тэги: reflection, программирование
Написать комментарий
http://www.justsayhi.com/bb/html_quiz
Я вспомнил 50.
Редакция от 14 сентября 2008
Тэги: tests, программирование
Написать комментарий
С «решарпером» программирование стало напоминать тетрис. Перейти к нужному слову, Alt+Enter, выбрать нужную опцию, подумать, повторить. Набирать вслепую я не могу, но на стрелки, Alt и Enter попадаю не глядя.
Редакция от 15 октября 2009
Тэги: c#, visual studio, работа
Написать комментарий