kvv's home

Форма входа

Категории раздела

Лекции [14]
Разное [4]
Статьи на тему WM, не попавшие в лекции по разным причинам.

Поиск

Каталог статей

Главная » Статьи » Программирование под Windows Mobile » Лекции

Часть 6. Плагины Today
Плагины для экрана Today
Экран Today – главный экран Windows Mobile, появляется сразу после загрузки системы. На экране Today представлена различная информация о текущем времени, напоминание о событиях, информация о владельце, количество новых сообщений, имя сотового оператора (для коммуникаторов и смартфонов) и т.д.

Элементы экрана Today можно отключать, менять порядок их расположения. У некоторых элементов может быть окно дополнительных настроек. Чтобы добраться для настроек плагинов, надо зайти в "Settings">"Today">"Items" (для русской версии "Настройка">"Сегодня">"Элементы")
Кроме того, сущеcтвует возможность подключать дополнительные программы в виде плагинов. Написанием такого плагина мы сейчас и займемся.


Плагины для Today оформляются в виде DLL.

Эта DLL может экспортировать две функции:

Функция инициализации плагина - обязательная:

HWND APIENTRY InitializeCustomItem (
TODAYLISTITEM *ptli,
HWND hwndParent
);

Функция должна создать окно для будущего плагина. Входными параметрами является хэндл родительского окна и структура описания плагина TODAYLISTITEM


typedef struct _TODAYLISTITEM {
TCHAR szName[MAX_ITEMNAME]; // имя плагина
TODAYLISTITEMTYPE tlit; // тип плагина
DWORD dwOrder; // порядковый номер
DWORD cyp; // высота плагина
BOOL fEnabled; // флаг активности плагин
BOOL fOptions; // флаг окна дополнительных настроек
DWORD grfFlags; // дополнительные флаги
TCHAR szDLLPath[MAX_PATH]; // путь к dll плагина
HINSTANCE hinstDLL; // инстанс загруженной dll-ки
HWND hwndCustom; // хэндл окна дополнительных настроек
BOOL fSizeOnDraw; // зарезервировано
BYTE * prgbCachedData; // указатель на пользовательские данные
DWORD cbCachedData; // размер этих данных
} TODAYLISTITEMTYPE;

И функция обработки сообщений окна настроек - необязательная
BOOL APIENTRY CustomItemOptionsDlgProc (
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam
);

Это обычная функция обработки сообщений окна, обычно в ней обрабатываются сообщения WM_INITDIALOG (в нем происходит загрузка переменных в контролы) и WM_COMMAND (обработка клавиши OK – сохранение параметров)


Итак, поехали. Мы создадим простой плагин без окна настроек, который что-нибудь выведет на экран.
Создаем обычный Win32 Smart Device проект/ В настройках проекат включаем опцию создания Dll.

В полученный проект сразу же добавляем def файл, в которм перечислены экспортируемые функции:
--- miniplugin.def ---

LIBRARY "miniplugin"


EXPORTS

InitializeCustomItem @240 NONAME

--- miniplugin.def ---


Теперь создадим функицю InitializeCustomItem

HWND InitializeCustomItem(TODAYLISTITEM *ptli, HWND hwndParent)
{
g_hWnd = CreateWindow(L"MyPlugin",L"MyPlugin",WS_VISIBLE | WS_CHILD,
CW_USEDEFAULT,CW_USEDEFAULT,240,0,hwndParent, NULL, g_hInst, NULL) ;
SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG) WndProc);
ShowWindow (g_hWnd, SW_SHOWNORMAL);
UpdateWindow (g_hWnd) ;
return g_hWnd;
}

Как мы видим, в ней создается экземпляр класса окна будущего плагина. Нам надо будет создать функцию обработки сообщений этого окна
Добавим ее:
LRESULT CALLBACK WndProc (HWND hwnd, UINT uimessage, WPARAM wParam, LPARAM lParam)
{
switch (uimessage)
{
//проверка необходимости обновления окна плагина
case WM_TODAYCUSTOM_QUERYREFRESHCACHE:
{
TODAYLISTITEM *ptliItem;
ptliItem = (TODAYLISTITEM*)wParam;
if ((NULL == ptliItem) || (WaitForSingleObject(SHELL_API_READY_EVENT, 0) == WAIT_TIMEOUT))
{
return FALSE;
}
if (0 == ptliItem->cyp)
{
ptliItem->cyp = DRA::SCALEY(30);
return TRUE;
}
return FALSE;
}

case WM_CREATE:
break;

// функция отрисовки всякого
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rect;
RECT myRect;
HDC hDC;
GetWindowRect(hwnd, &rect);
hDC = BeginPaint(hwnd, &ps);
SetBkMode(hDC, TRANSPARENT);

myRect.left = 0;
myRect.top = DRA::SCALEY(2);
myRect.right = rect.right - rect.left;
myRect.bottom = rect.bottom - rect.top;

LOGFONT lf;
HFONT hSysFont;
HFONT hFont;
hSysFont = (HFONT) GetStockObject(SYSTEM_FONT);
GetObject(hSysFont, sizeof(LOGFONT), &lf);
lf.lfHeight = (long) -((7.0 * (double)GetDeviceCaps(hDC, LOGPIXELSY) / 72.0)+.5);
hFont = CreateFontIndirect(&lf);
HFONT hFontOld = (HFONT) SelectObject(hDC, hFont);
COLORREF crText = SendMessage(GetParent(hwnd), TODAYM_GETCOLOR, (WPARAM) TODAYCOLOR_TEXT, NULL);
SetTextColor(hDC, crText);
DrawText(hDC, L"Hello from Plugin =)", -1, &myRect, DT_LEFT);
SelectObject(hDC, hFontOld);
DeleteObject(hFont);
EndPaint(hwnd,&ps);
}
return 0;

case WM_DESTROY :
return 0 ;

// заливка области плагина фоновым цветом
case WM_ERASEBKGND:
TODAYDRAWWATERMARKINFO dwi;
dwi.hdc = (HDC)wParam;
GetClientRect(hwnd, &dwi.rc);
dwi.hwnd = hwnd;
SendMessage(GetParent(hwnd), TODAYM_DRAWWATERMARK, 0,(LPARAM)&dwi);
return TRUE;
}

return DefWindowProc (hwnd, uimessage, wParam, lParam) ;
}

По минимуму нам надо обработать только сообщение WM_PAINT, но мы так же добавим обработку WM_TODAYCUSTOM_QUERYREFRESHCACHE в которой мы укажем высоту плагина и WM_ERASEBKGND, в которой попросим систему залить область плагина фоновой картинкой.

Минимальный плагин готов. Теперь нужно его установить. Для этого сделаем следующее.
  • Скопируем полученную dll на девайс.
  • Создать ветку реестра в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Today\Items с именем раздела, совпадающего с именем нашего проекта
  • Внутри раздела создаем значения типа DWORD Type=4. Enabled=1, Options=0 и строковое значение DLL в котором укажем путь до нашей dll
  • Пошлем сообщение SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0xF2, 0);.
Если все сделано правильно, то наш плагин появится на экране.



Теперь научим наш плагин реагировать на нажатие мышом. Для этого добавим обработчик сообщения WM_LBUTTONUP
case WM_LBUTTONUP:
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
TCHAR szText[200];
wsprintf(szText,L"Mouse X=%d Y=%d",xPos,yPos);
MessageBox(0,szText,L"My plugin", MB_OK | MB_ICONINFORMATION);
return 0;
}

Таким образом можно обрабатывать нажатия на разные участки плагина.


Кстати, таким же образом можно обрабатывать нажатия на клавиши. Когда наш плагин активен, то при нажатии на клавиши система посылает ему сообщение WM_TODAYCUSTOM_USERNAVIGATION, обрабатывая которое, мы можем получать коды нажатых клавиш. При нажатии на клавишу Enter посылается сообщение WM_TODAYCUSTOM_ACTION. Добавим обработчики этих сообщений в WndProc:

case WM_TODAYCUSTOM_USERNAVIGATION:

{

int VirtKey = wParam;

// todo: use Virtual key

return TRUE;

}

case WM_TODAYCUSTOM_ACTION:

{

MessageBox(0,L"Return pressed",

L"My plugin", MB_OK | MB_ICONINFORMATION);

return 0;

}


Кстати, чтобы плагин можно было выделять, нужно создать в реестре DWORD параметр Selectability = 1


Теперь настало время добавить окно настроек. Для начала вносим в def файл проекта строку:

CustomItemOptionsDlgProc @241 NONAME

И описываем функцию обработки сообщений окна настроек:

LRESULT WINAPI CustomItemOptionsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

static TODAYLISTITEM *s_ptliItem = NULL;

switch (message)

{

case WM_INITDIALOG:

{

SHINITDLGINFO shidi;

shidi.dwMask = SHIDIM_FLAGS;

shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;

shidi.hDlg = hDlg;

SHInitDialog(&shidi);

s_ptliItem = (TODAYLISTITEM*)lParam;

}

return TRUE;


case WM_COMMAND:

if (LOWORD(wParam) == IDOK)

{

EndDialog(hDlg, LOWORD(wParam));

return TRUE;

}

break;


case WM_DESTROY:

s_ptliItem = NULL;

break;

}


В файл ресурсов необходимо вставить ресурс для диалога ID ресурса должен быть равен 500, иначе окно не будет активировано:

IDD_TODAY_CUSTOM DIALOG DISCARDABLE 0, 0, 140, 57
STYLE DS_CONTROL | WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE 0x80000000L
CAPTION "My Today Settings"
BEGIN
LTEXT "MyToday - Options",IDC_STATIC_TITLE,4,3,124,10
LTEXT "Description of the options for your DLL go here.",
IDC_STATIC_DESC,5,18,124,16
END

Не забудем также поменять параметр Options в ветке реестра плагина на 1.

Теперь при выборе кнопки Options в настройках Today, мы увидит наше окно настроек:


Ну, собственно, и все... Теперь мы умеем создавать плагины для Today. Правда наш плагин пока не умеет самостоятельно устанавливаться на девайс, что не позволит обычному юзеру правильно его использовать, поэтому самое время научиться делать CAB файлы для установки.


Категория: Лекции | Добавил: kvv (11.12.2008)
Просмотров: 9669 | Комментарии: 7 | Теги: Today plugins, Лекции | Рейтинг: 4.7/3
Всего комментариев: 7
7 josteteesiaph  
0
Добрый день! обращаем Ваше внимание на уникальный сайт http://reklamma.net тут за то что Вы добавите свой сайт заплатят только правда вывести не сможете админы за етим следят, но и пусть зато на шару можно прорекламить свой ресурс да и еще на своем сайте заработать, ет не траф биз где обманываю по пользователям, когда счетчики говорят одно а у них считаеться совсем другое! Заходите регайтесь http://reklamma.net

6 Neihoopsype  
0
[url=http://zevs-pk.ru/building.html]
Ñòðîèòåëüñòâî êîòòåäæåé â Ðÿçàíè[/url]

5 Neihoopsype  
0
[url=http://zevs-pk.ru/index.html]
ÎÎÎ Çåâñ ñïåöòåõíèêà è ëàíäøàôòíûé äèçàéí[/url]

3 YouROK  
0
Что значит
"Пошлем сообщение SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0xF2, 0);"
как и откуда его посылать?

4 kvv  
0
обычно это делается в инсталляторе. в его SetupDll

2 kvv  
0
Как правило, исходники примеров из статей выкладываются в каталоге файлов (раздел Файлы для лекций).
Для этой статьи исходники лежат вот тут http://kvv.my1.ru/load/3-1-0-9

1 Guest  
0
Было бы классно, если бы вы выкладывали исходники рассмотренных программ )

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Друзья сайта

  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Облако тэгов