Win32:はウィンドウと同じHDCその全生涯?
-
20-09-2019 - |
質問
私の使用を許可DC外部の塗装のサーベイを行います。私のウィンドウのDCを保証する有効なのか?
私はそうとしていることか私のコントロールのデバイスコンテキスト(DC)が有効になります。
私が話:
GetDC(hWnd);
のデバイスコンテキストのコントロールの画面がでることです。
コンピュータ(Windows)を送信してくれWM_PAINTメッセージことが決まってい話 BeginPaint/EndPaint を適切に認識したことがある塗装で、社内の無効な国-地域:
BeginPaint(hWnd, {out}paintStruct);
try
//Do my painting
finally
EndPaint(hWnd, paintStruct);
end;
が呼び出しBeginPaintものを返しまっDCのPAINTSTRUCTます。このDCい すべ 塗ます。
できないかもしれませんので、何の文書によると、DC返されるBeginPaint()は同じDCうかGetDC().
特に、現在のデスクトップの組成、有効な絵を描DCを入手したいの外BeginPaint?
がなされているとは聞いている2つの方法で入手できるDC-塗装中の塗料サイクル:
dc= GetDC(hWnd);
BeginPaint(&paintStruct);
が3方ができるようバグをBorland Delphiと開発を行っています。
中 WM_PAINT 加工デルファイバイスプレジデントと考えてwParamはDCとができるように塗ります。は、MSDNのようなwParamのWM_PAINTメッセージが利用されていない。
その理由
私の本当の目標 はいうものだ持続的なGDI+グラフィックスオブジェクト 抗HDCができるよう、使用には何らかの良い舞台特徴のGDI+に依存している持続している。
中WM_PAINTメッセージの取扱いを描きたいあなたのたGDI+画像のキャンバスに入力します。以下のnieve版が非常に遅い:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
Graphics g = new Graphics(ps.hdc);
g.DrawImage(m_someBitmap, 0, 0);
g.Destroy();
EndPaint(h_hwnd, ps);
}
GDIを含む高速化を行うビットマップ、CachedBitmap.ものを使用しないで思考えが可能な給付金額:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
Graphics g = new Graphics(ps.hdc);
CachedBitmap bm = new CachedBitmap(m_someBitmap, g);
g.DrawCachedBitmap(m_bm, 0, 0);
bm.Destroy();
g.Destroy();
EndPaint(h_hwnd, ps);
}
の性能が得らのCachedBitmapが、そのプログラムの初期化:
m_graphics = new Graphics(GetDC(m_hwnd));
m_cachedBitmap = new CachedBitmap(b_someBitmap, m_graphcis);
現在の塗料サイクル:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
m_graphics.DrawCachedBitmap(m_cachedBitmap, 0, 0);
EndPaint(h_hwnd, ps);
}
を除く現地に行って信頼のDCた後、得られたプログラムinitializtionのDC私のオーバーラッピングウィンドウに申請してください。することで存続を通して:
- ファストユーザーのスイッチ
- 組成物の有効/無効
- テーマ切替
- テーマ字
見たいものではないMSDNることを保証するのと同じ直流のまま使用する特定のウィンドウの画面が存在します。
注意: 私は使用しない二重バッファリング、 したいので、良い開発を、この商品につけられたタグ.あることを意味していまダブルバッファリングが悪かったりします。
解決
例外ケースがありますが、一般にはありませんが、できれば、異なるDC毎回呼び出す GetDC
または BeginPaint
.このような努め保存状態になります。(なければならないこの業績については、DCsを作成できるwindowsまたは特定の画面インスタンスな音のようにそれが本当に必要またはいいです。)
ほとんどの時間、しかし、その樹状細胞が対応します。うに表示されるものと同じグラフィックモードでの対応ビットマップばれている場合であっても、エす。
コンクリートメッセージを伝えすることができグラフィックモードの変更など WM_DISPLAYCHANGE
や WM_PALETTECHANGED
.聞くことができたら、再現キャッシュされたビットマップ.を用いて計算で求めたものであり珍しいイベントなければいけませんの心配のパフォーマンスへの影響の再現にごキャッシュされたビットマップいたします。
使用できる必要があります通知などをテーマに変わります。そなグラフィックモード--彼らはより高いレベルコンセプト--でキャッシュされたビットマップする必要がありますの種DCます。が変更したい場合はビットマップがテーマの変更を聞くことが可能ですために WM_THEMECHANGED
しています。
他のヒント
なだけでは知ることがありません)のためには、ウィンドウの CS_OWNDC クラスです。
何となく割り当て独特のデバイスコンテキストのための各ウィンドウのクラスです。
編集
からのリンクMSDNの記事:
デバイスのコンテキストの特定の 価値アプリケーションの利用 図面をクライアントエリアの windowsの場合です。システムが必要で装置 コンテキストの各ウィンドウを表示 ができる柔軟性がどのよう システム店舗および取り扱い装置 コンテキスト
場合によってはご利用になれないコンテクストスタイル 明示的に指定され、システムを想定し 各ウィンドウ用デバイスコンテキスト から取得したプールの文脈におい のシステム。など 場合には、各ウィンドウな取得および の初期化デバイスコンテキストの前に 塗料で塗りました。
な取得するデバイスコンテキスト 各時間で塗装中 画面アプリケーションは、この指定 CS_OWNDCスタイルウィンドウのウィンドウクラスです。このクラスのスタイルを演出システム を個人デバイスコンテキスト—その は、割り当てを独自のデバイス コンテキスト各ウィンドウのクラスです。申請の必要性のみを取得する 文脈を一度に活用ですべての その後の塗装です。
Windows95/98/Meの場合:その CS_OWNDCスタイルが便利で、利用で 丁寧に、各デバイスコンテキスト 使用の大部分は64K GDI ヒープ.
のではないでしょうか例をあげてご説明用CS_OWNDCより:
#include <windows.h>
static TCHAR ClassName[] = TEXT("BitmapWindow");
static TCHAR WindowTitle[] = TEXT("Bitmap Window");
HDC m_hDC;
HWND m_hWnd;
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
switch (msg)
{
case WM_PAINT:
{
BeginPaint(hWnd, &ps);
if (ps.hdc == m_hDC)
MessageBox(NULL, L"ps.hdc == m_hDC", WindowTitle, MB_OK);
else
MessageBox(NULL, L"ps.hdc != m_hDC", WindowTitle, MB_OK);
if (ps.hdc == GetDC(hWnd))
MessageBox(NULL, L"ps.hdc == GetDC(hWnd)", WindowTitle, MB_OK);
else
MessageBox(NULL, L"ps.hdc != GetDC(hWnd)", WindowTitle, MB_OK);
RECT r;
SetRect(&r, 10, 10, 50, 50);
FillRect(m_hDC, &r, (HBRUSH) GetStockObject( BLACK_BRUSH ));
EndPaint(hWnd, &ps);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wcex;
wcex.cbClsExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wcex.hIconSm = NULL;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = ClassName;
wcex.lpszMenuName = NULL;
wcex.style = CS_OWNDC;
if (!RegisterClassEx(&wcex))
return 0;
DWORD dwExStyle = 0;
DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
m_hWnd = CreateWindowEx(dwExStyle, ClassName, WindowTitle, dwStyle, 0, 0, 300, 300, NULL, NULL, hInstance, NULL);
if (!m_hWnd)
return 0;
m_hDC = GetDC(m_hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
のCS_OWNDCフラグが ない を混同することCS_CLASSDC旗る:
割り当てを一つのデバイスコンテキストが共有する全てのwindowsのクラスです。すので授業過程の特定が可能で、複数のスレッドのアプリケーションで作成ウィンドウの同じクラスです。ることも可能で、スレッドを使用する試みのデバイスコンテキストを同時にこのシステムではスレッドを無事に終え、その描画動作します。
ドだけで の再構築 のCachedBitmap.
きの構築CachedBitmapオブジェクトに合格しなければなりませんのアドレスのグラフィックスオブジェクトのコンストラクタです。画面の場合、関連するグラフィックスオブジェクトは、そのビット深度を変更後、キャッシュに格納されたビットマップを構築し、そのDrawCachedBitmap方法に失敗しまだ復興のキャッシュされたビットマップ.また、お客様のフックに表示を変更通知メッセージの再構成し、キャッシュに格納されたビットマップです。
ると言うつもりはありませんCS_OWNDC最適なソリューションで は その一歩は、より良い解決策です。
編集
サンプルプログラムも同じ直流中に画面解像度/ビット深度を変更試験をCS_OWNDC旗しかし、このフラグを除去し、DCの異(ウインドウ7 64-bit最終)(すべ 同じ過differn OSのバージョン...がるのではなく、傷つける試験。
Edit2
この例のないコGetUpdateRectチェックの場合画面のニーズを塗りつぶしの中のWM_PAINT.このエラーになります。
を描くことができ着いずれかの窓dc喜ばします。彼らは両方有効になります。ウィンドウがないで直流れを表現できるのです。その時に呼び出すGetDC、BeginPaint内なので、を取得しました、dc、もっとも、同じ画面が表示されます。だReleaseDC(EndPaint)が行われました。同日のWindows3.1デバイスの文脈が限られ、非常に高価なシステムリソース、アプリケーションは、長年の経験を決議し、取得してからGetDCます。現在は、完全に受け入れられる作dcで画面の作成、およびキャッシュでの生活に面しています。
の"問題"は、取り扱い WM_PAINT
, のdc返されるBeginPaintするクリップを無効rectに保存されます。
いかに理解するためgdiplus.通常の場合には、オブジェクトが---選択した入dc長期の時間は、直流であるメモリdc、ウィンドウます。
各時間GetDCと呼ばれましたHDCを表す独自のデバイスコンテキストとその状態です。なので、物体の背景色、文字モード。プDCな効果状態のDC取得により異なる呼び出GetDCはBeginPaint.
システムはランダム無効HDCs取得され、クライアントは、実際には多くの作品の背景をHDCs取得される前に表示モードスイッチを継続することができます。でもビット深度を変更し、技術的には、dcの互換性のないませんので、いずれの方法を使っても、防止の申し込みを受け続けて使用hdcをblit.
とはいえ、あの時計少なくともWM_DISPLAYCHANGE、他のキャッシュDCsイプを再現します。