Windows Mobile の Today のプラグインを実装しようと思うと、WnProc を実装する必要があり、C#だけでは実装できない。
http://msdn.microsoft.com/en-us/library/ms839442.aspx
に、Creating a Pocket PC Today Screen Plug-in with the .NET Compact Framework という方法も載っているが、これだと共有メモリを使ってHTMLをレンダリングさせる方法なので、かえって見通しが悪そう。これなら、直接C++/CLIで実装して、一部を C#で書いたほうが楽そう。ただ、TodayのプラグインがC++/CLIで実装可能かどうか・・・C++/CLIでも実装可能なら、一部を C# で書くことも可能なので、ちょっと込み入った実装もだいぶ楽になるはず。
少し調べていたら、
http://www.atmarkit.co.jp/fdotnet/special/cppcli/cppcli_01.html
に「いままたC++が熱い!「C++/CLI」として大進化したVisual C++ 2005」の記事があり、C++/CLI によるScreen Saver のサンプルがあったので、試してみた。
結果はWinProc をC++/CLIで動かすことができる。ということは、おそらく Windows Mobile の Today のプラグインも同様に動くと思われると、思ったが、スマートデバイスのプロジェクトテンプレートでは、C++/CLI がサポートされないみたい orz
ピーデー 川俣 晶さんがアップしているコードを VS2008用にちょっと修正したので、とりあえずメモ。
- コンパイル時の設定に、構成プロパティ→全般に 共通言語ランタイムサポート をセット。
- 構成プロパティ→リンカ→追加の依存ファイルに scrnsavw.lib comctl32.lib をセット。
- コンパイルしたイメージを /Sで起動。
#include <stdafx.h>
#include <windows.h>
#include <scrnsave.h>
#using <mscorlib.dll>
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
UINT_PTR wTimer;
WORD wElapse = 1000;
int xText=0, yText=0;
#define ID_TIMER 1
LONG CALLBACK ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
wTimer = SetTimer(hWnd, ID_TIMER, wElapse, NULL);
}
break;
case WM_TIMER:
{
HDC hdc = GetDC(hWnd);
xText = rand() % GetDeviceCaps(hdc,HORZRES);
yText = rand() % GetDeviceCaps(hdc,VERTRES);
ReleaseDC(hWnd,hdc);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case WM_DESTROY:
if( wTimer ) KillTimer(hWnd, ID_TIMER);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
{
System::Drawing::
Graphics ^ g = Graphics::FromHdc((IntPtr)hDC);
Font font("MS ゴシック", 160);
SolidBrush brush( Color::Blue);
PointF position( (float)xText, (float)yText );
g->DrawString( "テスト!", %font, %brush, position );
}
EndPaint(hWnd, &ps);
}
break;
case WM_ERASEBKGND:
{
RECT rc;
GetClientRect(hWnd,&rc);
FillRect((HDC)wParam, &rc,
(HBRUSH)GetStockObject(BLACK_BRUSH));
}
return 0L;
default:
break;
}
return DefScreenSaverProc(hWnd, msg, wParam, lParam);
}
BOOL WINAPI RegisterDialogClasses (HANDLE hInst)
{
return TRUE;
}
BOOL CALLBACK ScreenSaverConfigureDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return FALSE;
}