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. Несколько примеров таких решений можно найти в комментариях.

Таблица html-кодов символов

16 июн. 2009 г. | | |









































































































































































































































































































































































Сводная таблица HTML-кодов
"&quot;&&amp;<&lt;>&gt;&nbsp;
¡&iexcl;¢&cent;£&pound;¤&curren;¥&yen;
¦&brvbar;§&sect;¨&uml;©&copy;ª&ordf;
«&laquo;¬&not;®&reg;¯&macr;°&deg;
±&plusmn;²&sup2;³&sup3;´&acute;µ&micro;
&para;·&middot;¸&cedil;¹&sup1;º&ordm;
»&raquo;¼&frac14;½&frac12;¾&frac34;&#8539;
&#8540;&#8541;&#8542;¿&iquest;À&Agrave;
Á&Aacute;Â&Acirc;Ã&Atilde;Ä&Auml;Å&Aring;
Æ&AElig;Ç&Ccedil;È&Egrave;É&Eacute;Ê&Ecirc;
Ë&Euml;Ì&Igrave;Í&Iacute;Î&Icirc;Ï&Iuml;
Ð&ETH;Ñ&Ntilde;Ò&Ograve;Ó&Oacute;Ô&Ocirc;
Õ&Otilde;Ö&Ouml;×&times;Ø&Oslash;Ù&Ugrave;
Ú&Uacute;Û&Ucirc;Ü&Uuml;Ý&Yacute;Þ&THORN;
ß&szlig;à&agrave;á&aacute;â&acirc;ã&atilde;
ä&auml;å&aring;æ&aelig;ç&ccedil;è&egrave;
é&eacute;ê&ecirc;ë&euml;ì&igrave;í&iacute;
î&icirc;ï&iuml;ð&eth;ñ&ntilde;ò&ograve;
ó&oacute;ô&ocirc;õ&otilde;ö&ouml;÷&divide;
ø&oslash;ù&ugrave;ú&uacute;û&ucirc;ü&uuml;
ý&yacute;þ&thorn;ÿ&yuml;Ć&#262;ć&#263;
ı&#305;IJ&#306;ij&#307;Ł&#321;ł&#322;
Œ&OElig;œ&oelig;Š&Scaron;š&scaron;Ÿ&Yuml;
Ž&#381;ž&#382;ƒ&fnof;ˇ&#711;˘&#728;
˙&#729;˚&#730;˛&#731;˝&#733;Α&Alpha;
Β&Beta;Γ&Gamma;Δ&Delta;Ε&Epsilon;Ζ&Zeta;
Η&Eta;Θ&Theta;Ι&Iota;Κ&Kappa;Λ&Lambda;
Μ&Mu;Ν&Nu;Ξ&Xi;Ο&Omicron;Π&Pi;
Ρ&Rho;Σ&Sigma;Τ&Tau;Υ&Upsilon;Φ&Phi;
Χ&Chi;Ψ&Psi;Ω&Omega;α&alpha;β&beta;
γ&gamma;δ&delta;ε&epsilon;ζ&zeta;η&eta;
θ&theta;ι&iota;κ&kappa;λ&lambda;μ&mu;
ν&nu;ξ&xi;ο&omicron;π&pi;ρ&rho;
ς&sigmaf;σ&sigma;τ&tau;υ&upsilon;φ&phi;
χ&chi;ψ&psi;ω&omega;ϑ&thetasym;ϕ&#981;
ϖ&piv;ϵ&#1013;&ndash;&mdash;&lsquo;
&rsquo;&sbquo;&ldquo;&rdquo;&bdquo;
&dagger;&Dagger;&bull;&permil;&prime;
&Prime;&lsaquo;&rsaquo;&oline;&frasl;
&euro;&#8463;&image;&weierp;&real;
&trade;&alefsym;&larr;&uarr;&rarr;
&darr;&harr;&#8597;&#8629;&lArr;
&uArr;&rArr;&dArr;&hArr;&#8661;
&forall;&part;&exist;&empty;&nabla;
&isin;&notin;&ni;&prod;&sum;
&minus;&#8723;&lowast;&radic;&prop;
&infin;&ang;&and;&or;&cap;
&cup;&int;&there4;&sim;&#8771;
&cong;&asymp;&ne;&equiv;&#8802;
&le;&ge;&#8810;&#8811;&sub;
&sup;&nsub;&#8837;&sube;&supe;
&oplus;&otimes;&perp;&sdot;&lceil;
&rceil;&lfloor;&rfloor;&lang;&rang;
&#9115;&#9116;&#9117;&#9118;&#9119;
&#9120;&#9121;&#9122;&#9123;&#9124;
&#9125;&#9126;&#9127;&#9128;&#9129;
&#9130;&#9131;&#9132;&#9133;&#9135;
&#9474;&#9633;&loz;&#9675;&#9756;
&#9758;&spades;&clubs;&hearts;&diams;
&#10003;

Как вытащить картинку из поля OLE из Access

11 июн. 2009 г. | | |

Недавно столкнулась с такой проблемой - надо было организовать работу с БД Access через php. Извращение в чистом виде, особенно, если учесть, что в бд были столбцы типа OLE, в которых хранились картинки. А эти картинки надо было отображать на странице. Долго искала решение, но так нигде и не нашла.
На одном из сайтов прочитала, что при сохранении картинки в столбец OLE Аксес добавляет заголовок. О длине этого заголовка точно известно не было - в одном месте утверждали, что он 78 байт, в другом - что зависит от региональных настроек. Час от часу не легче....
На самом деле, как показала практика, фиксированной длины у этого заголовка нет.
В итоге всех моих поисков, методом тыка я нашла собственное решение. И оно оказалось элементарно просто!!! В базе, с которой пришлось мне работать, все картинки были в основном в bmp-формате, поэтому я приведу пример кода для конкретного случая.
И так, для начала нужно подключиться к бд с помощью odbc (более подробно как сделать это описано тут):

$connection = odbc_connect( $dsn, $user, $pwd);

Далее делаем запрос на выборку поля с картинкой:

$result = odbc_exec($connection, "Select Foto From Users Where UserID=1");

Теперь надо извлечь данные. Тут есть одна тонкость. Так как картинка больше 4096 байт (это длина данных , возвращаемая по умолчанию для LONG столбцов ), то нужно указать, что хотим, нет, даже требуем! чтобы нам передали большее количество данных с помощью функции odbc_longreadlen:

if ($result!== FALSE)
{
odbc_longreadlen($result, 1048576);
odbc_fetch_row($result, 0);
$data = odbc_result($result, "Foto");

Стандартный bmp начинается со символов "BM". Так как Аксес добавляет свой заголовок к данным файла и в нем могут встречатится такое же сочетание букв, то искать начало нашей картинки будем после фразы "PBrush", которая находится в конце заголовка, который добавляет аксес. Дело за малым, осталось из полученных данных вырезать картинку и отправить ее в браузер:

$data = substr($data, strpos($data, "BM", strpos($data, "PBrush")));
header("Content-type: ".image_type_to_mime_type(IMAGETYPE_BMP));
echo $data;
exit;
}

Для форматов gif, png, jpeg понадобиться только искать соответствующий формату заголовок.
Для изображений, который были сохранены с отметкой Microsoft PhotoEditor 3.0, я так решения и не нашла :(