パワーポイントの上に透明なウインドを作って
線や図を挿入させ表示というプログラム作っているのですが
パワーポイントで前のページに戻った時
前のページに書き込んだ情報(線,図)を再描画するため
次のページ移るたびにウインドを保存用のウインドに保存して
戻ると描画用ウインドに上書きし
表示させようとしているのですが全く反映されません
HWND g_hDisplayWindow; // 描画用ウィンドウのハンドル
HWND g_annotation_slide[20]; //各スライドのアノテーションデータ保存用
この二つがそれぞれのウインドハンドルで
以下のように描画用ウインドを生成しています
hWnd = CreateWindowEx(
WS_EX_LAYERED,
szClassName,
DisplayWindow,
//WS_OVERLAPPEDWINDOW,
WS_OVERLAPPED | WS_POPUP,
0,
0,
Size.x,
Size.y,
NULL,
NULL,
hInstance,
NULL
);
g_hDisplayWindow = hWnd;
ShowWindow(g_hDisplayWindow, nCmdShow);
UpdateWindow(g_hDisplayWindow);
SetWindowPos(g_hDisplayWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
そして次のスライドに移るときに
g_annotation_slide[g_nSlideIndex]=g_hDisplayWindow;//ウインドを保存
前のスライドに戻ると
g_hDisplayWindow = g_annotation_slide[g_nSlideIndex];
UpdateWindow(g_hDisplayWindow);
で前のウインドを表示させたいのですが反映されません
描画ウインドに線などを書き込みすることはできます
よろしくお願いします
> g_hDisplayWindow = g_annotation_slide[g_nSlideIndex];
> UpdateWindow(g_hDisplayWindow);
> で前のウインドを表示させたいのですが反映されません
その通り。反映さえrません。
ハンドルがすべての情報を保持しているわけではありませんから。
# というより、ハンドルはまさしく取っ手でしかなく、描画情報はほとんど保持して
いません。
DIBデータを保持すればいいと思います。
imgctl.dllを使うと簡単にできます。
void SaveDIB(HDIB *phDIB, HWND hWnd)
{
HDC hDC = GetDC(hWnd);
RECT Rect;
GetClientRect(hWnd, &Rect);
// DIBデータを保存(※DCtoDIB()はimgctl.dllの関数)
*phDIB = DCtoDIB(hDC, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom -
Rect.top);
ReleaseDC(hWnd, hDC);
}
描画はDIBtoDCex2()などを使えばいいと思います。
回答になってなかったらすみません。
回答ありがとうございます
本当に初歩的な質問ですみません
c++で開発しているのですがimgctl.dllのインポート方法が分かりません
プログラムに
#import <imgctl.dll>
と宣言し
デバッグディレクトリ下にimgctl.dllを置いているのですが
エラー fatal error C1083: タイプ ライブラリ ファイルを開けません。
'imgctl.dll': No such file or directory
というエラーが出てしまいます
本当に初歩的な質問ですみません
マニュアル読みました?
#include imgctl.h
#pragma comment(lib, imgctl.lib)
です。
imgctl.dll と imgctl.h と imgctl.lib が必要です。
なんか冗長な回答をしていました。
DCを保存するだけでいいですね。
もう少し詳しく書きます。
1:メモリDCを作成する。
2:コピー元のウィンドウのDCをメモリDCにコピーする。
3:メモリDCをコピー先のウィンドウのDCにコピーする。
2,3のコピーはBitBlt()を使って下さい。
rockさんありがとうございます
現在
次のスライドに移ると
PostMessage(g_hDisplayWindow, WM_COMMAND, ID_ANNOTATIONSAVE, NULL);
//スライドを保存
PostMessage(g_hDisplayWindow, WM_COMMAND, ID_ALLCLEAR, NULL);
//すべての書き込みを消す
PostMessage(g_hDisplayWindow, WM_COMMAND, ID_ANNOTATIONLODE, NULL);
//書き込み情報をロード
UpdateWindow(g_hDisplayWindow)
描画ウインドウの更新
関係ないところは省きましたが
だいたいこのような手順でプログラムを作成したのですが反映されません
ID_ANNOTATIONSAVEの中身は
hDC = GetWindowDC(hWnd);//現在のウインドウのデバイスコンテキスト取得
hmdc_save[g_nSlideIndex] = CreateCompatibleDC(hDC);
BitBlt( hmdc_save[g_nSlideIndex], 0, 0, SizeX, SizeY, hDC, 0, 0, SRCCOPY );
//各スライドのデバイスコンテキストに保存
ReleaseDC(hWnd, hDC);
ID_ANNOTATIONLODEの中身は
hDC = GetDC(hWnd);
BitBlt(hDC , 0, 0, SizeX, SizeY, hmdc_save[g_nSlideIndex], 0, 0, SRCCOPY );
//各スライドのデバイスコンテキストをコピー
ReleaseDC(hWnd, hDC);
hmdc_save[20]は書き込み情報保存用のデバイスコンテキスト
g_nSlideIndexはスライド番号です
よろしくお願いします
サンプル書いてみました。
何にもチェックしてないので、コンパイル通らないかも。
// 裏画面構造体
typedef struct tagbackbuffer
{
HDC hMemDC;
HBITMAP hOldBitmap;
POINT Size;
} BACKBUFFER;
// 裏画面構造体を作成
BACKBUFFER* CreateBuckBuffer(HWND hWnd)
{
BACKBUFFER* pBB = (BACKBUFFER*)calloc(1, sizeof(BACKBUFFER));
HDC hDC = GetDC(hWnd);
RECT Rect;
GetClientRect(GetDesktopWindow(), &Rect);
pBB->hMemDC = CreateCompatibleDC(hDC);
HBITMAP hMemBitmap = CreateCompatibleBitmap(hDC, Rect.right, Rect.bottom);
pBB->hOldBitmap = SelectObject(pBB->hMemDC, hMemBitmap);
return pBB;
}
// 裏画面構造体を破棄
void DestroyBackBuffer(BACKBUFFER* pBB)
{
HBITMAP hMemBitmap = (HBITMAP)SelectObject(pBB->hMemDC, pBB->hOldBitmap);
DeleteObject(hMemBitmap);
DeleteDC(pBB->hMemDC);
free(pBB);
}
// ウィンドウのクライアント領域を裏画面構造体にコピー
void CopyToBackBuffer(BACKBUFFER *pBB, HWND hWnd)
{
HDC hDC = GetDC(hWnd);
RECT Rect;
GetClientRect(hWnd, &Rect);
pBB->Size.x = Rect.right;
pBB->Size.y = Rect.bottom;
BitBlt(pBB->hMemDC, 0, 0, pBB->Size.x, pBB->Size.y, hDC, 0, 0, SRCCOPY);
ReleaseDC(hWnd, hDC);
}
// 裏画面構造体をウィンドウのクライアント領域にコピー
void CopyToWindow(HWND hWnd, BACKBUFFER* pBB)
{
HDC hDC = GetDC(hWnd);
RECT Rect;
GetClientRect(hWnd, &Rect);
StretchBlt(hDC, 0, 0, Rect.right, Rect.bottom, pBB->hMemDC, 0, 0, pBB->Size.x, pBB->Size.y,
SRCCOPY);
ReleaseDC(hWnd, hDC);
}
// 使い方
BACKBUFFER* pBB;
// 初期化(WM_CREATEぐらいのタイミングで)
pBB = CreateBackBuffer(hWnd);
// ウィンドウを裏画面にコピー
CopyToBackBuffer(pBB, hWnd);
// 裏画面をウィンドウにコピー
CopyToWindow(hWnd, pBB);
// 解放(WM_CLOSEぐらいのタイミングで)
DestroyBackBuffer(pBB);
[訂正]
スペル間違い
CreateBuckBuffer()
→CreateBackBuffer()
キャストしていなかった(CreateBuckBuffer()内)
pBB->hOldBitmap = SelectObject(pBB->hMemDC, hMemBitmap);
→pBB->hOldBitmap = (HBITMAP)SelectObject(pBB->hMemDC, hMemBitmap);
一応、動作確認しました。
透明なウィンドウだとどうなるかわかりませんが・・・
rockさんありがとうございます
プログラム
参考にさせてもらいます
すみませんが
はどういった意味でしょうか
つまらない質問ですいません
iPhoneのメモ帳から貼りつけたら、変な文字が挿入されてしまいました。
無視して下さい。
ありがとうございます
このプログラムではpBB++で次のスライドや
p--で前のスライドの書き込み情報の参照をしたらよろしいのでしょうか??
ポインタの配列を使うと良いかと。
BACKBUFFER* pBB[20];
// 初期化
for(int i = 0;i < 20;i++)
pBB[i] = CreateBackBuffer(hWnd);
// 解放
for(int i = 0;i < 20;i++)
DestroyBackBuffer(pBB[i]);
// 例:ウィンドウを7番目の裏画面にコピー
CopyToBackBuffer(pBB[7], hWnd);
// 例:13番目の裏画面をウィンドウにコピー
CopyToWindow(hWnd, pBB[13]);
そんなに難しくないはずなので、頑張って下さい。