Today プラグインサンプルプログラム2
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
#analog
#norelated
#contents
* Today プラグインサンプルプログラム2 [#xa500017]
** 背景透過 [#ofd9e8e8]
[[Today プラグインサンプルプログラム]]で作ったサンプルで...
この上に色々描いていってもいいのですが、せっかくToday画面...
というわけで、前回黒かった部分を透過して、壁紙を表示させ...
といっても、WindowsMobileSDKのサンプル等を見ると、WM_ERAS...
恐らく、アイテムの親ウィンドウにWS_CLIPCHILDRENがついてい...
ただ、なんらかの要因で親ウィンドウの更新がされずに、アイ...
実際、NULL指定だけでは、他のアプリを起動、終了させて、再...
ちらつきを抑えるという意味では、一旦親ウィンドウが背景を...
なのでまずは、WM_ERASEBKGNDで何もしないようにします。~
背景ブラシがNULLになっていれば、実質、DefWindowProcはWM_E...
プロトタイプ宣言は以下のように。~
BOOL Today_OnEraseBkgnd( HWND hwnd, HDC hdc ); // WM_ERA...
ウィンドウプロシージャも追加します。~
HANDLE_MSG( hwnd, WM_ERASEBKGND, Today_OnEraseBkgnd );
そして、何もせずに、背景を消去したという意味のTRUEを返し...
BOOL Today_OnEraseBkgnd( HWND hwnd, HDC hdc )
{
return TRUE;
}
次に、WM_PAINTの処理を作り、その中でバックバッファを作成...
ただし、毎回バックバッファを作り直すのは効率が悪いので、...
縦画面/横画面の切り替わりで、クライアント領域のサイズが変...
普通のWindowsプログラムだと、モニタの切り替わりをWM_DISPL...
縦横切り替えの検知は、サイズ変更でしか知り得ないのかな……?~
その辺りは後々調べますか……。~
で、ちょっと調べてみたところ、縦横の切替はChangeDisplaySe...
Todayのアイテムについては、WM_SIZEでウィンドウサイズが変...
コントロールの再配置等は、WM_SIZEでやったほうがよさげです...
バックバッファ作成のために、Todayウィンドウクラスに、以下...
HDC m_hdc; // デバイスコンテキスト
HBITMAP m_hOldbmp; // ビットマップハンドル
RECT m_rect; // クライアント矩形保存用
それぞれ、表示画面と互換性のあるデバイスコンテキストを保...
バックバッファ作成前に、GetClientRectでクライアント領域を...
サイズに変更がある場合のバックバッファ作成の流れは、解放...
次に、ウィンドウのデバイスコンテキストからCreateCompatibl...
ビットマップをSelectObjectするのは、windowsx.hにSelectBit...
作り終わったら、今回作成した領域の矩形を、メンバに保存し...
解放と作成の流れは、以下の通り。~
// バックバッファ解放
void CTodayWnd::freBkBuffer( void )
{
HBITMAP hbitmap = NULL; // ビットマップハンドル
if( m_hOldbmp ){
hbitmap = SelectBitmap( m_hdc, m_hOldbmp );
DeleteBitmap( hbitmap );
m_hOldbmp = NULL;
}
if( m_hdc ){
::DeleteDC( m_hdc );
m_hdc = NULL;
}
ZeroMemory( &m_rect, sizeof( RECT ));
}
// バックバッファ作成
bool CTodayWnd::creBkBuffer( void )
{
HDC hdc = NULL; // デバイスコンテキスト
HBITMAP hbitmap = NULL; // ビットマップハンドル
RECT rect; // クライアント矩形保存用
if( NULL == m_hwnd ){
return false;
}
// クライアント矩形取得
if( !::GetClientRect( m_hwnd, &rect )){
return false;
}
if( 0 == memcmp( &m_rect, &rect, sizeof( RECT ))){ // ...
return true;
}
freBkBuffer();
// ウィンドウのデバイスコンテキスト取得
hdc = ::GetDC( m_hwnd );
if( NULL == hdc ){
goto Error;
}
// コンパチデバイスコンテキスト作成
m_hdc = ::CreateCompatibleDC( hdc );
if( NULL == m_hdc ){
goto Error;
}
// コンパチビットマップ作成
hbitmap = ::CreateCompatibleBitmap( hdc, rect.right, re...
if( NULL == hbitmap ){
goto Error;
}
// ビットマップの関連付け
m_hOldbmp = SelectBitmap( m_hdc, hbitmap );
if( NULL == m_hOldbmp ){
goto Error;
}
CopyMemory( &m_rect, &rect, sizeof( RECT ));
return true;
Error:
freBkBuffer();
if( NULL != hdc ){
::ReleaseDC( m_hwnd, hdc );
hdc = NULL;
}
return false;
}
裏画面を作り終わったら、まずはこの裏画面に、透かした背景...
このためには、TODAYDRAWWATERMARKINFOという構造体に、アイ...
そして、背景が描かれた裏画面上に、自分で好きなものを描い...
試しに、背景にテキストを書いて、それを表画面に表示する処...
プロトタイプ宣言は以下のように。~
void Today_OnPaint( HWND hwnd ); // WM_PAINT処理
ウィンドウプロシージャも追加します。~
HANDLE_MSG( hwnd, WM_PAINT, Today_OnPaint );
実際の処理は、以下の通り。~
void Today_OnPaint( HWND hwnd )
{
LPCTodayWnd lpCTodayWnd = NULL; // Todayウィンドウクラス
TODAYDRAWWATERMARKINFO tdwmi; // 透かし描画用構造体
PAINTSTRUCT ps; // PAINT構造体
HDC hdc = NULL; // デバイスコンテキスト
lpCTodayWnd = ( LPCTodayWnd )::GetWindowLong( hwnd, GWL...
if( NULL == lpCTodayWnd ){
return;
}
// バックバッファ作成
if( !lpCTodayWnd->creBkBuffer() ){
return;
}
// 裏画面に背景を描いてもらう
ZeroMemory( &tdwmi, sizeof( TODAYDRAWWATERMARKINFO ));
tdwmi.hwnd = hwnd;
tdwmi.hdc = lpCTodayWnd->getBkDC();
if( !::GetClientRect( hwnd, &tdwmi.rc )){
return;
}
if( !::SendMessage( ::GetParent( hwnd ), TODAYM_DRAWWAT...
return;
}
if( !::ExtTextOut( lpCTodayWnd->getBkDC(), 0, 0, ETO_CL...
return;
}
// 裏画面を表画面に転送
ZeroMemory( &ps, sizeof( PAINTSTRUCT ));
hdc = ::BeginPaint( hwnd, &ps );
if( NULL == hdc ){
return;
}
::BitBlt( hdc, tdwmi.rc.left, tdwmi.rc.top, tdwmi.rc.ri...
::EndPaint( hwnd, &ps );
}
これで、以下のような表示になるはずです。~
#ref(test.png,left,nowrap,てすと)
背景のデバイスコンテキストの背景透過モードをONにしていな...
テキスト描画は、TextOutがWindowsMobileでは使えないので、E...
テキストを描くくらいでしたら、これで問題ないと思いますが...
マスク画像を用意しておいて、お手軽にSRCPAINT、SRCANDを使...
とりあえず、ここまでのソースをつけておきます。~
#ref(背景透過表示ソース.zip,left,nowrap,背景透過表示ソース)
終了行:
#analog
#norelated
#contents
* Today プラグインサンプルプログラム2 [#xa500017]
** 背景透過 [#ofd9e8e8]
[[Today プラグインサンプルプログラム]]で作ったサンプルで...
この上に色々描いていってもいいのですが、せっかくToday画面...
というわけで、前回黒かった部分を透過して、壁紙を表示させ...
といっても、WindowsMobileSDKのサンプル等を見ると、WM_ERAS...
恐らく、アイテムの親ウィンドウにWS_CLIPCHILDRENがついてい...
ただ、なんらかの要因で親ウィンドウの更新がされずに、アイ...
実際、NULL指定だけでは、他のアプリを起動、終了させて、再...
ちらつきを抑えるという意味では、一旦親ウィンドウが背景を...
なのでまずは、WM_ERASEBKGNDで何もしないようにします。~
背景ブラシがNULLになっていれば、実質、DefWindowProcはWM_E...
プロトタイプ宣言は以下のように。~
BOOL Today_OnEraseBkgnd( HWND hwnd, HDC hdc ); // WM_ERA...
ウィンドウプロシージャも追加します。~
HANDLE_MSG( hwnd, WM_ERASEBKGND, Today_OnEraseBkgnd );
そして、何もせずに、背景を消去したという意味のTRUEを返し...
BOOL Today_OnEraseBkgnd( HWND hwnd, HDC hdc )
{
return TRUE;
}
次に、WM_PAINTの処理を作り、その中でバックバッファを作成...
ただし、毎回バックバッファを作り直すのは効率が悪いので、...
縦画面/横画面の切り替わりで、クライアント領域のサイズが変...
普通のWindowsプログラムだと、モニタの切り替わりをWM_DISPL...
縦横切り替えの検知は、サイズ変更でしか知り得ないのかな……?~
その辺りは後々調べますか……。~
で、ちょっと調べてみたところ、縦横の切替はChangeDisplaySe...
Todayのアイテムについては、WM_SIZEでウィンドウサイズが変...
コントロールの再配置等は、WM_SIZEでやったほうがよさげです...
バックバッファ作成のために、Todayウィンドウクラスに、以下...
HDC m_hdc; // デバイスコンテキスト
HBITMAP m_hOldbmp; // ビットマップハンドル
RECT m_rect; // クライアント矩形保存用
それぞれ、表示画面と互換性のあるデバイスコンテキストを保...
バックバッファ作成前に、GetClientRectでクライアント領域を...
サイズに変更がある場合のバックバッファ作成の流れは、解放...
次に、ウィンドウのデバイスコンテキストからCreateCompatibl...
ビットマップをSelectObjectするのは、windowsx.hにSelectBit...
作り終わったら、今回作成した領域の矩形を、メンバに保存し...
解放と作成の流れは、以下の通り。~
// バックバッファ解放
void CTodayWnd::freBkBuffer( void )
{
HBITMAP hbitmap = NULL; // ビットマップハンドル
if( m_hOldbmp ){
hbitmap = SelectBitmap( m_hdc, m_hOldbmp );
DeleteBitmap( hbitmap );
m_hOldbmp = NULL;
}
if( m_hdc ){
::DeleteDC( m_hdc );
m_hdc = NULL;
}
ZeroMemory( &m_rect, sizeof( RECT ));
}
// バックバッファ作成
bool CTodayWnd::creBkBuffer( void )
{
HDC hdc = NULL; // デバイスコンテキスト
HBITMAP hbitmap = NULL; // ビットマップハンドル
RECT rect; // クライアント矩形保存用
if( NULL == m_hwnd ){
return false;
}
// クライアント矩形取得
if( !::GetClientRect( m_hwnd, &rect )){
return false;
}
if( 0 == memcmp( &m_rect, &rect, sizeof( RECT ))){ // ...
return true;
}
freBkBuffer();
// ウィンドウのデバイスコンテキスト取得
hdc = ::GetDC( m_hwnd );
if( NULL == hdc ){
goto Error;
}
// コンパチデバイスコンテキスト作成
m_hdc = ::CreateCompatibleDC( hdc );
if( NULL == m_hdc ){
goto Error;
}
// コンパチビットマップ作成
hbitmap = ::CreateCompatibleBitmap( hdc, rect.right, re...
if( NULL == hbitmap ){
goto Error;
}
// ビットマップの関連付け
m_hOldbmp = SelectBitmap( m_hdc, hbitmap );
if( NULL == m_hOldbmp ){
goto Error;
}
CopyMemory( &m_rect, &rect, sizeof( RECT ));
return true;
Error:
freBkBuffer();
if( NULL != hdc ){
::ReleaseDC( m_hwnd, hdc );
hdc = NULL;
}
return false;
}
裏画面を作り終わったら、まずはこの裏画面に、透かした背景...
このためには、TODAYDRAWWATERMARKINFOという構造体に、アイ...
そして、背景が描かれた裏画面上に、自分で好きなものを描い...
試しに、背景にテキストを書いて、それを表画面に表示する処...
プロトタイプ宣言は以下のように。~
void Today_OnPaint( HWND hwnd ); // WM_PAINT処理
ウィンドウプロシージャも追加します。~
HANDLE_MSG( hwnd, WM_PAINT, Today_OnPaint );
実際の処理は、以下の通り。~
void Today_OnPaint( HWND hwnd )
{
LPCTodayWnd lpCTodayWnd = NULL; // Todayウィンドウクラス
TODAYDRAWWATERMARKINFO tdwmi; // 透かし描画用構造体
PAINTSTRUCT ps; // PAINT構造体
HDC hdc = NULL; // デバイスコンテキスト
lpCTodayWnd = ( LPCTodayWnd )::GetWindowLong( hwnd, GWL...
if( NULL == lpCTodayWnd ){
return;
}
// バックバッファ作成
if( !lpCTodayWnd->creBkBuffer() ){
return;
}
// 裏画面に背景を描いてもらう
ZeroMemory( &tdwmi, sizeof( TODAYDRAWWATERMARKINFO ));
tdwmi.hwnd = hwnd;
tdwmi.hdc = lpCTodayWnd->getBkDC();
if( !::GetClientRect( hwnd, &tdwmi.rc )){
return;
}
if( !::SendMessage( ::GetParent( hwnd ), TODAYM_DRAWWAT...
return;
}
if( !::ExtTextOut( lpCTodayWnd->getBkDC(), 0, 0, ETO_CL...
return;
}
// 裏画面を表画面に転送
ZeroMemory( &ps, sizeof( PAINTSTRUCT ));
hdc = ::BeginPaint( hwnd, &ps );
if( NULL == hdc ){
return;
}
::BitBlt( hdc, tdwmi.rc.left, tdwmi.rc.top, tdwmi.rc.ri...
::EndPaint( hwnd, &ps );
}
これで、以下のような表示になるはずです。~
#ref(test.png,left,nowrap,てすと)
背景のデバイスコンテキストの背景透過モードをONにしていな...
テキスト描画は、TextOutがWindowsMobileでは使えないので、E...
テキストを描くくらいでしたら、これで問題ないと思いますが...
マスク画像を用意しておいて、お手軽にSRCPAINT、SRCANDを使...
とりあえず、ここまでのソースをつけておきます。~
#ref(背景透過表示ソース.zip,left,nowrap,背景透過表示ソース)
ページ名: