Pages

Wednesday, July 29, 2009

Windows Mobile 6: Keep Display On

Статья опубликована на Experts-Echange.
For the application that extensively works with the data such as a map or GPS, it is important to keep the display on all the time. Few years ago the function SystemIdleTimerReset() did its job. On our side we needed to detect the device idle time and call this function appropriately. In Windows Mobile 6 this function keeps the system running, but the display is turned off. So the problem is to keep the backlight on.

Of course the solution was found. If you need to keep your device at full power just use the following code:

HANDLE hBacklight = SetPowerRequirement(_T("BKL1:"), D0, POWER_NAME, NULL, 0);


Do not forget to release handle when you close application:

ReleasePowerRequirement(hBacklight)


SystemIdleTimerReset() should be used also – this function keeps the device running. If you will forget about it, the display will be on, but the device will “go to sleep” together with your application. It will look like your application gets stuck.
MSND article "Program Applications to Turn the Smartphone Backlight Off and On" explains it with more details and has a working example.
Bruce Eitman proposed new solution in his article “Windows CE: Keeping the Backlight On”. He found out that the power manager is monitoring a named event. The name of this event can be obtained from the registry:

const static LPCWSTR s_szGWE_REG_PATH = L"SYSTEM\\GWE";
const static LPCWSTR s_szActivityKey = L"ActivityEvent";
DWORD EventName(LPWSTR& lpszName)
{
HKEY hKey = NULL;
DWORD nResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, s_szGWE_REG_PATH, 0, 0, &hKey);
if (nResult != ERROR_SUCCESS)
return 0;

DWORD nNumBytes = 0;
DWORD nType;
nResult = RegQueryValueEx(hKey, s_szActivityKey, NULL, &nType, NULL, &nNumBytes);
if (nResult == ERROR_SUCCESS)
{
nResult = 0;
if (nNumBytes > 0)
{
lpszName = (LPWSTR)malloc(nNumBytes + 2);
if (lpszName != NULL)
{
ZeroMemory(lpszName, nNumBytes + 2);
nResult = RegQueryValueEx(hKey, s_szActivityKey, NULL, &nType, (LPBYTE)lpszName, &nNumBytes);
nResult = wcslen(lpszName);
}
}
RegCloseKey(hKey);
}
return nResult;
}



If we have the name, we can create this event:

HANDLE hPowerEvent = CreateEvent(NULL, FALSE, FALSE, lpszEventName);


and raise it periodically:

SetEvent(hPowerEvent);

Tuesday, July 28, 2009

"Странное" программирование

Вот такая "пустая" программа (ни одной строчки в функции main):

#include <iostream>
using namespace std;

struct Strange
{
Strange()
{
cout << "Hello" << endl;
}

~Strange()
{
cout << "Bye" << endl;
}

} tagStrange;

int main()
{
return 0;
}


а работает:

Все знают, что глобальные объекты создаются во время загрузки программы. Всем привычно видеть что-то такое:

#include <iostream>
using namespace std;
int x = 5;
int main()
{
cout << x << endl;
return 0;
}


Но не все знают и о трюке, что я показал. Можно же в конструктор и деструктор более важные вещи поставить. Например, CoInitialize(NULL) и CoUninitialize().

GeoSkeeper. Personal Communicator with Distress Alarm and GPS Location

Немного рекламы. Main features:
Built-in Cellular Speakerphone;
GPS Location and Tracking;

Немного о плохом ! В телефонах HTC обнаружена критическая уязвимость.

Эксперт в области безопасности Альберто Морено Табладо выявил уязвимость в смартфонах HTC, работающих под управлением Windows Mobile 6 или Windows Mobile 6.1, которая позволяет взломщикам получить доступ к любому файлу, хранящемуся в смартфоне, или загрузить на него вредоносный код при помощи Bluetooth.
По его словам, устройства HTC с операционной системой Windows Mobile 6 и Windows Mobile 6.1 уязвимы к обходу директории в Bluetooth OBEX FTP Service. Смартфоны на базе Windows Mobile 5 данной дыры не имеют. Для того чтобы атака прошла успешно, на целевом устройстве должен быть включен Bluetooth и активирован совместный доступ к файлам через Bluetooth, сообщает ИА ВирусБлокада со ссылкой на Хакер.
Пользователям, желающим обезопасить себя от возможной атаки, следует спаривать свои смартфоны только с доверенными устройствами, кроме того будет полезно удалить из списка спаренных устройств все уже имеющиеся там аппараты.

Источник:
http://zman.com/news/article.aspx?ArticleId=49793&CategoryId=25

Monday, July 27, 2009

Netbook от Apple


Слухи говорят, что этот нетбук появится в продаже к Рождественским распродажам. Будет там какой-то "Cocktail", позволяющий скачивать целые альбомы из интернет-магазинов.

C++ классы: размещение в памяти.

Experts-Exchange опубликовал английский вариант этой статьи:
Visual C++ Object Memory Layout

Sunday, July 26, 2009

В.В.Высоцкий

И снизу лед, и сверху - маюсь между:
Пробить ли верх иль пробуравить низ?
Конечно, всплыть и не терять надежду!
А там - за дело в ожиданьи виз.

Лед надо мною - надломись и тресни!
Я весь в поту, хоть я не от сохи.
Вернусь к тебе, как корабли из песни,
Все помня, даже старые стихи.

Мне меньше полувека - сорок с лишним, -
Я жив, тобой и Господом храним.
Мне есть что спеть, представ перед Всевышним,
Мне будет чем ответить перед Ним.

Saturday, July 25, 2009

Virtual base classes (Diamond problem)

Эта статья опубликована на сайте Experts-Exchange в разделе MS Visual C++.

The following diagram presents a diamond class hierarchy:


As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourth class (e.g., CTest).

The following is how would expect the diagram to be implemented:

#include <stdio.h>
class CBase
{
public:
virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CDerived1 : public CBase
{
};

class CDerived2 : public CBase
{
};

class CTest : public CDerived1, public CDerived2
{
};

int main()
{
CTest test;
test.test();
return 0;
}

However, the Microsoft VC+ 2005 .NET compiler gives the following message:

1>-- Build started: Project: vft_test, Configuration: Debug Win32 --
1>Compiling...
1>main_romb.cpp
1>c:\source\vft_test\vft_test\main_romb.cpp(27) : error C2385: ambiguous access of 'test'
1> could be the 'test' in base 'CBase'
1> or could be the 'test' in base 'CBase'
1>c:\source\vft_test\vft_test\main_romb.cpp(27) : error C3861: 'test': identifier not found
1>Build log was saved at "file://c:\Source\vft_test\vft_test\Debug\BuildLog.htm"
1>vft_test - 2 error(s), 0 warning(s)
====== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ===

Since CDerived1 and CDerived2 can have very different implementations of CBase::test(), the compiler is unsure which CTest derives. This is the so called "Diamond problem" or even "Dreaded Diamond".


How to deal with this "dread"?
The following code will give you a clue:

#include <stdio.h>
class CBase
{
public:
CBase()
{
printf("CBase::CBase()\r\n");
}
virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CDerived1 : public CBase
{
public:
CDerived1()
{
printf("CDerived1::CDerived1()\r\n");
}
};

class CDerived2 : public CBase
{
public:
CDerived2()
{
printf("CDerived2::CDerived1()\r\n");
}
};

class CTest : public CDerived1, public CDerived2
{
public:
CTest()
{
printf("CTest::CTest()\r\n");
}
};

int main()
{
CTest test;
//test.test();
return 0;
}



This program is compiled successfully and works:


Of course you know how CTest object is created. It derives firstly from CDerived1 object that inherits from CBase, and, secondly, CTest derives from CDerived2 that also inherits from CBase. So the complier (probably any compiler) creates CBase object, then CDerived1, and now it needs to create CBase again, …, etc., we got 2 CBase objects! The diagram didn’t show that CBase class appears twice in the class hierarchy.
C++ provides a technique for such case. The declaration of the CBase class as virtual solves the situation:

#include <stdio.h>

class CBase
{
public:
CBase()
{
printf("CBase::CBase()\r\n");
}
virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CDerived1 : virtual public CBase
{
public:
CDerived1()
{
printf("CDerived1::CDerived1()\r\n");
}
};

class CDerived2 : virtual public CBase
{
public:
CDerived2()
{
printf("CDerived2::CDerived1()\r\n");
}
};

class CTest : public CDerived1, public CDerived2
{
public:
CTest()
{
printf("CTest::CTest()\r\n");
}
};

int main()
{
CTest test;
test.test();
return 0;
}



The application output is shown on the following screenshot:

In this example CBase is inherited virtually. CDerived1 and CDerived2 classes share the same implementation of CBase. The compiler creates only one CBase object.
Of course, it is possible to solve this “Diamond problem” in another ways. For example like that:

#include <stdio.h>

class CBase
{
public:
virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CDerived1 : public CBase
{
};

class CDerived2 : public CBase
{
};

class CTest : public CDerived1, public CDerived2
{
};

int main()
{
CTest test;
test.CDerived1::test();
return 0;
}


I think that the best solution is to try to avoid such diamond problems. That will keep the design simple.
The following source code shows how we can use aggregation instead of the diamond inheritance with our same classes:

#include <stdio.h>

class CBase
{
public:
virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CDerived1 : public CBase
{
};

class CDerived2 : public CBase
{
};

class CTest
{
CDerived1 m_One;
CDerived2 m_Two;
public:
void test()
{
m_One.test();
m_Two.test();
//or just
//m_One.test();
}
};

int main()
{
CTest test;
test.test();
return 0;
}


You see that this way makes CTest objects bigger in the memory - it contains of CDerived1 and CDerived2 and which of them has own CBase.

Friday, July 24, 2009

iPhone и навигация

Вот три наиболее известных навигационных программы для iPhone.
Navigon - текущая цена 70$. Нет помесячной оплаты. Поддержка так называемого landscape view, почему-то преподносится в списке достоинств этой программы. Наверное, в надежде, что большинство пользователей поддумают о трехмерном изображении на экране. А речь то просто о горизонтальном расположении телефона.

TomTom. Очент много сплетен об этой программе - Apple финансировал разработку, хочет купить фирму и так далее. Подтвержденное отличие от остальных - имеют специальный cradle (крепление?) для установки телефона в машине.

AT&T Navigator (powered by TeleNav). Очень тихо появились. Даже неожиданно. Очень красиво выглядят.



Бегемот от навигации - Sony NV-U3DV


Navigadget назвал этот новый навигационный прибор от Sony бегемотом - размер экрана больше 6 дюймов! Прибор поддерживает телевизионные каналы. Одно плохо - существует только в Японии.

C++ классы: размещение в памяти. Часть V.

Можна и подменить:

#include <stdio.h>
#include <memory>

class CBase
{
public:
virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CVirtTest
{
public:
virtual void test()
{
printf("CVirtTest::test()\r\n");
}
};

typedef void (* func)();
typedef struct
{
func Entry;
} FUNC_TABLE;

void Trick()
{
printf("Trick()\r\n");
}

int main()
{
CVirtTest test;
CBase* pBase = (CBase*)&test;

FUNC_TABLE funcTable = { Trick };
FUNC_TABLE* pFuncTable = &funcTable;
memcpy(&test, &pFuncTable, sizeof(long));

pBase->test();
return 0;
}



Для проверки можно закоментировать строку:
//memcpy(&test, &pFuncTable, sizeof(long));
получается:

Работает!

C++ классы: размещение в памяти. Часть IV.

"Пустой" класс с виртуальным методом имеет размер 4 байта. Можно добавить еще один или несколько виртуальных методов, но размер не меняется:

#include <stdio.h>
class CEmpty
{
public:
virtual ~CEmpty() {};
};
class CEmpty2
{
public:
virtual ~CEmpty2() {};
virtual void nothing() {};
};
class CEmpty3
{
public:
virtual ~CEmpty3() {};
virtual void nothing() {};
virtual void something() {};
};
int main()
{
CEmpty empty;
printf("size of CEmpty object is %d\r\n", sizeof(empty));
CEmpty2 empty2;
printf("size of CEmpty2 object is %d\r\n", sizeof(empty2));
CEmpty3 empty3;
printf("size of CEmpty3 object is %d\r\n", sizeof(empty3));
return 0;
}



Програмки из предыдущей части, если классы имеют виртуальные функции, не работают.
Если посмотреть память, то видно, что переменные передвинулись на 4 байта в памяти от "начала" класса:

Это хорошо видно, если использовать класс со строкой из предадущих примеров:

#include <stdio.h>
#include <Windows.h>
class CCharArray
{
char x[24];
public:
CCharArray()
{
strcpy(x, "Hello");
}
virtual void out()
{
printf("x is %s\r\n", x);
}
};
int main()
{
CCharArray objCharArray;
printf("size of CCharArray object is %d\r\n", sizeof(objCharArray));
printf("CCharArray as string is %s\r\n", (char*)&objCharArray);
objCharArray.out();
return 0;
}



Строка
printf("CCharArray as string is %s\r\n", (char*)&objCharArray);
не работает.

Добавили только виртуальный метод. Память изменилась. Вывод - это указатель на виртуальные функции. Точнее - на таблицу виртуальных функций. Эту таблицу можна просмотреть:

#include <stdio.h>

class C1Int
{
int x;

public:
virtual void test()
{
printf("C1Int::test()\r\n");
}
};

class C2Int : public C1Int
{
int y;

public:
virtual void test()
{
printf("C2Int::test()\r\n");
}

virtual void test1()
{
printf("C2Int::test1()\r\n");
}

virtual void test2()
{
printf("C2Int::test2()\r\n");
}
};

int main()
{
C2Int two_int;
printf("size of C2Int object is %d\r\n", sizeof(two_int));
printf("Address of C2Int object is %p\r\n", &two_int);

int* p = (int*)(&two_int);
printf("Address of C2Int pointer is %p\r\n", p);

int p1 = *((int*)(&two_int));
printf("Value of this pointer is %x\r\n", p1);

int* _p1 = (int*)*((int*)(&two_int));
printf("Same.. pointer is %p\r\n", _p1);

int* p2_1 = (int*)*((int*)*(int*)(&two_int));
printf("Value of first entry of C2Int VTable is %p\r\n", p2_1);

int* p2_2 = (int*)*((int*)*(int*)(&two_int) + 1);
printf("Value of second entry of C2Int VTable is %p\r\n", p2_2);

int* p2_3 = (int*)*((int*)*(int*)(&two_int) + 2);
printf("Value of third entry of C2Int VTable is %p\r\n", p2_3);

int* p2_4 = (int*)*((int*)*(int*)(&two_int) + 3);
printf("Value of fourth entry of C2Int VTable is %p\r\n", p2_4);

int* p2_5 = (int*)*((int*)*(int*)(&two_int) + 4);
printf("Value of fifth entry of C2Int VTable is %p\r\n", p2_5);

return 0;
}



C2Int class имеет только 3 виртуальных метода, но программа пытается найти 5. Эта "ошибка" показывает, что таблица заканчивается нулем.
Функции нашлись. Их и вызвать можна не спрашивая разрешения у класса:

#include <stdio.h>

class C1Int
{
public:
virtual void test()
{
printf("C1Int::test()\r\n");
}
};

class C2Int : public C1Int
{
public:
virtual void test()
{
printf("C2Int::test()\r\n");
}

virtual void test1()
{
printf("C2Int::test1()\r\n");
}

virtual void test2()
{
printf("C2Int::test2()\r\n");
}
};

typedef void (* func)();

int main()
{
C2Int two_int;
printf("size of C2Int object is %d\r\n", sizeof(two_int));
printf("Address of C2Int object is %p\r\n", &two_int);

int* p = (int*)(&two_int);
printf("Address of C2Int pointer is %p\r\n", p);

int p1 = *((int*)(&two_int));
printf("Value of this pointer is %x\r\n", p1);

int* _p1 = (int*)*((int*)(&two_int));
printf("Same.. pointer is %p\r\n", _p1);

int* p2_1 = (int*)*((int*)*(int*)(&two_int));
printf("Value of first entry of C2Int VTable is %p\r\n", p2_1);

int* p2_2 = (int*)*((int*)*(int*)(&two_int) + 1);
printf("Value of second entry of C2Int VTable is %p\r\n", p2_2);

int* p2_3 = (int*)*((int*)*(int*)(&two_int) + 2);
printf("Value of third entry of C2Int VTable is %p\r\n", p2_3);

func f1 = (func)p2_1;
f1();

f1 = (func)p2_2;
f1();

f1 = (func)p2_3;
f1();

C1Int one_int;
func f2 = (func)((int*)*((int*)*(int*)(&one_int)));
f2();

return 0;
}


Thursday, July 23, 2009

C++ классы: размещение в памяти. Часть III.

А эта программа меняет закрытые переменные класса:

#include <stdio.h>
class C1Int
{
int x;
public:
void out_x()
{
printf("x = %d\r\n", x);
}
};
int main()
{
C1Int one_int;
printf("size of C1Int object is %d\r\n", sizeof(one_int));
int* pInt = (int*)&one_int;
*pInt = 123456789;
one_int.out_x();
printf("object as integer %d\r\n", one_int);
return 0;
}



Можна и строку поменять:

#include <windows.h>
#include <stdio.h>
class C1Char
{
char x[24];
public:
C1Char()
{
strcpy(x, "hello");
}
void out_x()
{
printf("x = %s\r\n", x);
}
};
int main()
{
C1Char one;
printf("size of C1Char object is %d\r\n", sizeof(one));
one.out_x();
char* pText = (char*)&one;
strcpy(pText, "bye");
one.out_x();
return 0;
}



Вывод: класс по размеру равен сумме размеров своих переменных и в памяти объект класса это область, где расположены его члены (так уж это переводится).
И это так, пока не появляются виртуальные функции.

C++ классы: размещение в памяти. Часть II.

Запустим одну из этих програм и остановим в дебаггере, чтобы посмотреть один какой-то экземпляр класса:

В окне просмотра памяти находится область &objCharArray = 0x0012FF1C. Виден блок не инициализированной памяти – несколько строк с 0xCC. Это массив x[24]. Чтобы убедится, запишем в него слово и проверим в дебаггере еще раз.

#include <stdio.h>
#include <Windows.h>
class CCharArray
{
char x[24];
public:
CCharArray()
{
strcpy(x, "Hello");
}
void method()
{
printf("method\r\n");
}
};
int main()
{
CInt objInt;
printf("size of CInt object is %d\r\n", sizeof(objInt));
CDouble objDouble;
printf("size of CDouble object is %d\r\n", sizeof(objDouble));
CChar objChar;
printf("size of CChar object is %d\r\n", sizeof(objChar));
CCharArray objCharArray;
printf("size of CCharArray object is %d\r\n", sizeof(objCharArray));
return 0;
}



“Hello” записано в начале памяти отведенной для объекта objCharArray.
Студия находит внутренние переменные и показывает их. А это и не сложно. Вот программа, которая имеет "ошибку" (printf получил параметром класс вместо "ожидаемого" числа целого типа) и тоже показывает скрытые переменные класса:

#include <stdio.h>
#include <Windows.h>
class CInt
{
int x;
public:
CInt() : x(123) {}
};
class CCharArray
{
char x[24];
public:
CCharArray()
{
strcpy(x, "Hello");
}
};
int main()
{
CInt objInt;
printf("size of CInt object is %d\r\n", sizeof(objInt));
printf("CInt as integer %d\r\n", &objInt);
CCharArray objCharArray;
printf("size of CCharArray object is %d\r\n", sizeof(objCharArray));
printf("CCharArray as string is %s\r\n", &objCharArray);
return 0;
}



А ведь стандартный С++ говорит, что это private переменная и доступа к ней нет.

А вот так вторую и третью переменные из класса вывести на экран можна:

#include <stdio.h>
#include <Windows.h>
class CInt
{
int x;
int y;
int z;
public:
CInt() : x(123), y(456), z(789) {}
};
int main()
{
CInt objInt;
printf("size of CInt object is %d\r\n", sizeof(objInt));
printf("CInt: first private member %d\r\n", objInt);
printf("CInt: second private member %d\r\n", *((int*)&objInt + 1));
printf("CInt: third private member %d\r\n", *((int*)&objInt + 2));
return 0;
}


C++ классы: размещение в памяти. Часть I.

Маленький ребенок разломал игрушку. Родители возмущены - такая красивая игрушка... ай-я-яй..., столько денег стоила,... А деточка хотел узнать как эта штука устроена, хотел подправить кое-что, усовершенствовать даже.
С++ не игрушка, но тоже хочется понять как это устроено. Ломать не будем. Просто посмотрим и назад положим. Никто и не заметит, что трогали.
Вот классы - это как раз то, что эти плюсы (С++) к названию языка добавило - есть, просто С. А с классами - С++. То, что это абстракция всем понятно. И как работать с этой абстракцией тоже понятно. Вот эту абстракцию на байты и разберем.
Я должен уточнить, что я работаю с Microsoft Visual Studio 2005 и поэтому все программы приведенные в статье сделаны для компилятора Microsoft. Больше того – я допускаю, что и само распределение памяти для объектов классов может быть организовано по-другому в других компиляторах.
#include <stdio.h>
class CEmpty
{
};
int main()
{
CEmpty empty;
printf("size of CEmpty object is %d\r\n", sizeof(empty));
return 0;
}

В этой программе создан объект "пустого" класса т определяется его размер - это 1 байт. Должен же быть у объекта какой-то размер. Именно так и определяется стандартом языка. Если такой класс наследуется, тот же стандарт позволяет компиляторам "удалять" такие пустые классы в процессе оптимизации.
Добавим частную переменную целого типа в класс:

#include <stdio.h>
class CNotEmpty
{
int x;
};
int main()
{
CNotEmpty empty;
printf("size of CNotEmpty object is %d\r\n", sizeof(empty));
return 0;
}


Размер стал 4 байта. Добавим еще одну переменную типа int:

#include <stdio.h>
class CNotEmpty
{
int x;
int y;
};
int main()
{
CNotEmpty empty;
printf("size of CNotEmpty object is %d\r\n", sizeof(empty));
return 0;
}


Размер 8 байт:

С третьей переменной целого типа будет 12:

Добавим метод:

#include <stdio.h>
class CNotEmpty
{
int x;
int y;
int z;
public:
void method()
{
printf("method\r\n");
}
};
int main()
{
CNotEmpty empty;
printf("size of CNotEmpty object is %d\r\n", sizeof(empty));
empty.method();
return 0;
}


Размер не меняется:

Проверим другие типы переменных:

#include <stdio.h>
class CInt
{
int x;
int y;
int z;
public:
void method()
{
printf("method\r\n");
}
};
class CDouble
{
double x;
public:
void method()
{
printf("method\r\n");
}
};
class CChar
{
char x;
public:
void method()
{
printf("method\r\n");
}
};
class CCharArray
{
char x[24];
public:
void method()
{
printf("method\r\n");
}
};
int main()
{
CInt objInt;
printf("size of CInt object is %d\r\n", sizeof(objInt));
CDouble objDouble;
printf("size of CDouble object is %d\r\n", sizeof(objDouble));
CChar objChar;
printf("size of CChar object is %d\r\n", sizeof(objChar));
CCharArray objCharArray;
printf("size of CCharArray object is %d\r\n", sizeof(objCharArray));
return 0;
}



Размер объекта это сумма размеров его переменных. Объект, если рассматривать его с точки зрения управления памятью - это объединение памяти переменных класса. Это только промежуточный вывод и он будет уточнен и детализирован позже. Дело в том, что я не упоминал в каком порядке эти переменные расположены, как наследование и полиморфизм влияют на распределения памяти для объектов.

Wednesday, July 22, 2009

Прикольная программа для начинающих на C#

Все очень просто - создать консольное приложение и изменить текст в Program.cs файле.
Программа создает таймер который работает с частотой 10 раз в секунду и печатает очередную букву из заданой строки в окне консоле.

using System;
using System.Timers;

namespace EventsInConsole
{
class Program
{
static int counter = 0;

static string displayString = "This string will appear one letter at a time.";

static void WriteChar(Object source, ElapsedEventArgs e)
{
Console.Write(displayString[counter++ % displayString.Length]);
}

static void Main(string[] args)
{
Timer myTimer = new Timer(100);
myTimer.Elapsed += new ElapsedEventHandler(WriteChar);
myTimer.Start();
Console.ReadLine();
}
}
}

Sunday, July 19, 2009

Navigon



Компаниям, производящим навигациооные приборы, совсем нелегко пережить этот кризис. Масса слухов и сплетен - Apple финансирует, а то и покупает, TomTom, Navigon объявляет о закрытии бизнеса в Штатах, .. прочее (совсем неприятное).
И вот приятно увидеть, пока только на картинках, новую версию от Navigon.
Это 5-инч прибор, где и навигационная программа больше похожа на вид через лобовое стекло (для нескольких городов пока), где и телевизионный приемник и еще неизвестно что. Говорят, что цена будет около 449 евро.

Тем, кто любит или ненавидит Apple.


Тем, кто любит (или ненавидит)Apple - вот так выглядели первые модели.

C, C++, C# , Charles Petzold

Чарльз Петзольд уже давно признаный авторитет в программировании для Microsoft Windows. Ему абсолютно все равно, что мой сосед использует его книги как подставку для монитора, а я все время хвалю и удивляюсь, как этот автор умеет находить и очень просто и доступно объяснять основополагающие вещи.

Только сейчас дошли руки открыть его книгу “Programming Microsoft Windows C#”. Чарльз Петзольд, который сам прошел эволюцию от С к С++, а затем к C#, уже в самом начале книги объяснил основное отличие между этими языками и, по-моему, просто открыл мне дверь для понимания C#.

Тривиальная задача взята за основу – посчитать номер дня в году. На С это выглядит супер просто и супер понятно:
#include <stdio.h>

struct Date
{
int year;
int month;
int day;
};

int IsLeapYear(int year)
{
return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}

int DayOfYear(struct Date date)
{
static int MonthDays[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
return MonthDays[date.month - 1] + date.day + ((date.month > 2) && IsLeapYear(date.year));
}

int main()
{
struct Date mydate;
mydate.month = 8;
mydate.day = 29;
mydate.year = 2001;

printf("Day of year = %i\n", DayOfYear(mydate));

return 0;
}


Превратить этот код в С++ не сложно:
#include <stdio.h>

struct Date
{
int year;
int month;
int day;
int IsLeapYear()
{
return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}

int DayOfYear()
{
static int MonthDays[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
return MonthDays[month - 1] + day + ((month > 2) && IsLeapYear());
}
};

int main()
{
struct Date mydate;
mydate.month = 8;
mydate.day = 29;
mydate.year = 2001;

printf("Day of year = %i\n", mydate.DayOfYear());

return 0;
}


И тоже все ясно – поскольку две функции «спрятались» в структуре, то и параметры им уже не нужны. Эту структуру можно заменить на класс.

А теперь просто можна показать эту же программу на C#:
using System;
using System.Collections.Generic;
using System.Text;

namespace DayOfYearCSharp
{
class Program
{
static void Main(string[] args)
{
Date mydate = new Date();
mydate.year = 2001;
mydate.month = 8;
mydate.day = 29;

Console.WriteLine("Day of year = {0}", mydate.DayOfYear());
}
}

class Date
{
public int year;
public int month;
public int day;

public static bool IsLeapYear(int year)
{
return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}

public int DayOfYear()
{
int[] MonthDays = new int[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
return MonthDays[month - 1] + day + ((month > 2) && IsLeapYear(year) ? 1 : 0);
}
}
}


Одна и та же задача решена на трех языках. Сразу видно, что все эти языки родственны – одно семейство С языков.

Friday, July 17, 2009

Социальные сети на часах


Одноклассники еще все-таки не так популярны, чтобы на этих часах появится.
Но часы можна назвать "Весь день в интернете".

Thursday, July 16, 2009

VisiCalc. 1979 год. 30 лет назад.

В 1979 году я был в 2 классе. А кто-то уже серьезно программировал. Вот так говорят выглядел прадед нанешнего Excel:


А эта версия 1981 года до сих пор работает:



Ее можна найти на http://www.bricklin.com/history/vcexecutable.htm




Wednesday, July 8, 2009

Google Chrome OS

Google объявляет о создании новой операционной системы для нетбуков и персональных компютеров:
http://googleblog.blogspot.com/2009/07/introducing-google-chrome-os.html
Это open-source OS, которая появится во второй половине 2010 года. OS будет работать на x86 и ARM чипах. Обещают простую архитектуру - новая оконная система над Linux ядром. Все апликации будут постоены на web-технологиях. То есть, компютер становится быстрым броузером. Google считает, что это именно то, что хочет пользователь.
Разработчики програмного обеспечения, видимо, не подпадают в категорию пользователей.

Sunday, July 5, 2009

Gestures, Multiple touch, Resistive, Capacitive,…

Я понятия не имею, как это перевести на русский. Словарь какую-то чепуху предлагает вообще – попробуй успей за развитием технологий сейчас.

Я “gestures” пытался своими словами объяснить – наткнулся на “resistive” и “capacitive”. Это-то должно быть знакомо электронщикам – наверное, что-нибудь типа резисторный и емкостный. А мне, как програмисту, позволительно не помнить такие термины.

К чему это я? Совсем в переводах потерялся.

А хотел просто об этих gestures написать. Когда эта вещь появилась в прошлом году на iPhone, это было как гром среди ясного неба. Не знаю как другие программисты, Microsoft, производители железа, но я чувствовал себя слегка обалдевшим или ошалевшим. Все занимались анимацией для мобильных устройств, у многих программы уже выглядели так, что и настольному компьютеру не снилось. Все видели будущее мобильных устройств в более быстром интернете, но только Apple нашел настоящую изюминку и в графическом интерфейсе пользователя – вот эти самые gestures и этот самый multi-touch.
Getsures (самый близкий словарный перевод - это телодвижение) – это более интуитивный, более естественный способ взаимодействия с пользователем – при помощи пальца, без каких-то нажатий, можно передвигать визуальные элементы на экране телефона – списки скроллируются, экраны – листаются. То есть, все это таже анимация, но реагирует на движения пальца – список передвигается вместе с движением пальца, остановился палец – останавливается и анимация.

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

Сейчас уже вышел Microsoft Windows 6.5 DTK, который уже «поддерживает» gestures. Появились какие-то неофициальные технические материалы по этому вопросу. Если бы я их прочитал в сентябре прошлого года – не было бы в нашей программе никаких gestures. Ребята из Microsoft красиво и убедительно рассказывают, что все дело в «железе» - начиная с Windows CE 1.0, операционная система поддерживает экраны с так называемой resistive технологией. Это надежный и дешевый экран. И эта технология, вообще, не предназначена ни для каких gestures.

Совсем коротко эту технологию можна объяснить так – экран состоит из двух прозрачных слоев. Indium Tin Oxide – так называется материал, из котого эти слои создают. Между ними воздушная прослойка. Нажатия на верхний слой приводит к тому, что слои соприкасаются. Это можно зафиксировать и использовать. С точки зрения програмиста, идет эмуляция щелчка мышки (mouse click).

Это прежде всего дешевая технология. Вообщем-то, это «точная» технология, которая позволила придумать стилус для нажатия на визуальные элементы экрана - фактически точечное нажатие. То есть на экранах с плохой резолюцией (320 на 240 пикселей, например) можно было размещать достаточное число визуальных элементов маленького размера.

К плюсам этой технологии относят и то, что верхний слой может быть загрязнен, но это не помешает графическому интерфейсу.

Но на такой технологии невозможен multi touch - касание в нескольких местах экрана одновременно. Просто не работает. Фиксируется замыкание между слоями в одном месте.

А gestures? Следить из программы за движением пальца?

С Windows это не просто. Это же Windows – много окон. Вся апликация это набор окон. Нажатие на экран для программы это клик мышки на одном из окон.

А если пальцем ведут по экрану, какому окно передать шелчек мышки? Тому где это двидение началось? Но это палец, а не тоненький (точечный) стилус.

Apple смотрел на проблему с более высокой точки. Как производитель «железа», они сделали экран на основе более дорогой (и менее надежной) технологии, которая называется capacitive (наверное, что-то о конденсаторах – радиодеталях). Это решило им проблему multi touch – одновременно в нескольких местах можно нажимать на экран. Кроме одного приема управления – нажатия/щелчка на визуальном элементе, появилась масса новых – элементы можно, например, растягивать и сжимать – это zoom на фотографии, картинке или карте. Можно «изобретать» вращения, спирали и так далее. А если программа, при помощи, анимации, как бы «повторяет» или следует за движением пальца, то вот он – gesture – вполне тривиальная идея.

Capasitive технология не требует никакого нажатия. Поэтому экран iPhone реагирует на дыхание. Стилус использрвать вообще нельзя. С нынешними резолюциями это и не нужно – визуальный элементы стали больше размером.

Friday, July 3, 2009

Ассемблер - сила

Любой может писать программы на Ассемблере. Это, наверное, самый легкий язык для изучение основ информатики.

Любой компьютер имеет программу debug. Запустите ее из командной строки.


Теперь, можна писать программу. Для этого нужно напечать -а.


А теперь программа складывающая 2 числа - просто печатать и нажимать Ввод:

mov ax, 03
mov bx, 04
add ax, bx
int 3

Все. Два раза нажмите Ввод, чтобы закончить редактирование. Появится символ '-'. Напечатайте g -от слова "go".
Программа отработает и вы увидите результат - в регистре AX на экране будет результат 07:


Если надоело, дайте команду -q.
Чего проще?

Microsoft: Последние сплетни и слухи

Уже год прошел как Бил Гейтс ушел на пенсию (27 июня 2008). Он возглавлял Microsoft и был главным архитектором (Chief Software Architect). Сейчас эти функции исполняют Стив Балмер и Оззи Рэй.
Я не могу утверждать, что что-либо изменилось в стратегии Microsoft. Люди поближе замечают изменения, но даже они не знают хорошо это или плохо. Они связывают эти изменения не только с уходом Била Гейтса, но и с экономическим кризисом, возросшей коркуренцией. В первую очередь со стороны Apple.
Вот слухи последней недели (вообщем-то, подтвердившиеся):
1. Pink phone campaing. Говорят, что Microsoft уже определился с рекламной компанием (AdWeek), которая будет заниматься этим новым продуктом. Да, Microsoft выпускает и что-то "железное" - то ли Motorola, то ли Sharp производят телефон для Microsoft (Zune HD). Кроме брэнда, Microsoft собирается обеспечить пользователем каким-то супер обслуживанием. Наверное, установят на телефон Windows 6.5 или 7 (что уж будет к тому времени), будет там новый поисковик Bing, дадут доступ к Microsoft Marketplace. К тому времени обеспечат этот маркетплайс программами (обещают 600 к Октябрю), музыкой, фильмами, книгами. Вообщем, будет конкурент телефонам от Apple, Google и Palm. Не знаю насколько достоверна информация о Sharp, но на этих можно понадеятся - телефон может выглядеть очень привлекательно. По фотографиям, доступным в интернете, можно утверждать, что это не Motorola. Группа, которая занимается софтвэр частью в этом проэкте, имеет пугающее название Danger.
2. Windows Live Butterfly. Это бета-тестеры. Долгое время участники этой программы тестировали разнообразные MSN/Windows Live программы, имели MVP. Программа закрыта в июня 2009. Wikipedia уже обновила статус этой программы: http://en.wikipedia.org/wiki/Windows_Live#Windows_Live_Butterfly

Apple: Рост продаж во втором квартале

Уж очень хочеться видеть признаки выхода из экономического кризиса. Наверное, поэтому радует любой оптимистический анализ и прогноз.
Сегодня появились статьи о последнем исследовании проведеннем Morgan Stanley. Аналитик Katy Huberty видит увеличение продаж уже сейчас и повышает ожидания для второго квартала и на 2009 и 2010 годы для Apple, Dell и HP.
AppleInsider называет рост продаж в последние недели "возвращением в школу" и радуется, что держатели акций заработают еще до выхода из кризиса.