描画ウインドの保存について – プログラミング – Home

描画ウインドの保存について
 
通知
すべてクリア

描画ウインドの保存について

固定ページ 1 / 2

TKO
 TKO
(@TKO)
ゲスト
結合: 15年前
投稿: 38
Topic starter  

パワーポイントの上に透明なウインドを作って
線や図を挿入させ表示というプログラム作っているのですが

パワーポイントで前のページに戻った時
前のページに書き込んだ情報(線,図)を再描画するため

次のページ移るたびにウインドを保存用のウインドに保存して
戻ると描画用ウインドに上書きし
表示させようとしているのですが全く反映されません

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);
で前のウインドを表示させたいのですが反映されません

描画ウインドに線などを書き込みすることはできます
よろしくお願いします


引用解決済
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 15年前
投稿: 64
 

> g_hDisplayWindow = g_annotation_slide[g_nSlideIndex];
> UpdateWindow(g_hDisplayWindow);
> で前のウインドを表示させたいのですが反映されません

その通り。反映さえrません。
ハンドルがすべての情報を保持しているわけではありませんから。
# というより、ハンドルはまさしく取っ手でしかなく、描画情報はほとんど保持して
いません。


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

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()などを使えばいいと思います。

回答になってなかったらすみません。


返信引用
TKO
 TKO
(@TKO)
ゲスト
結合: 15年前
投稿: 38
Topic starter  

回答ありがとうございます
本当に初歩的な質問ですみません

c++で開発しているのですがimgctl.dllのインポート方法が分かりません
プログラムに
#import <imgctl.dll>
と宣言し

デバッグディレクトリ下にimgctl.dllを置いているのですが
エラー fatal error C1083: タイプ ライブラリ ファイルを開けません。
'imgctl.dll': No such file or directory

というエラーが出てしまいます
本当に初歩的な質問ですみません


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 15年前
投稿: 64
 

マニュアル読みました?


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

#include imgctl.h
#pragma comment(lib, imgctl.lib)
です。
imgctl.dll と imgctl.h と imgctl.lib が必要です。


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

なんか冗長な回答をしていました。
DCを保存するだけでいいですね。


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

もう少し詳しく書きます。

1:メモリDCを作成する。
2:コピー元のウィンドウのDCをメモリDCにコピーする。
3:メモリDCをコピー先のウィンドウのDCにコピーする。
2,3のコピーはBitBlt()を使って下さい。


返信引用
TKO
 TKO
(@TKO)
ゲスト
結合: 15年前
投稿: 38
Topic starter  

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はスライド番号です

よろしくお願いします


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

サンプル書いてみました。
何にもチェックしてないので、コンパイル通らないかも。

// 裏画面構造体
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);


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

[訂正]
スペル間違い
CreateBuckBuffer()
→CreateBackBuffer()

キャストしていなかった(CreateBuckBuffer()内)
pBB->hOldBitmap = SelectObject(pBB->hMemDC, hMemBitmap);
→pBB->hOldBitmap = (HBITMAP)SelectObject(pBB->hMemDC, hMemBitmap);

一応、動作確認しました。
透明なウィンドウだとどうなるかわかりませんが・・・


返信引用
TKO
 TKO
(@TKO)
ゲスト
結合: 15年前
投稿: 38
Topic starter  

rockさんありがとうございます
プログラム
参考にさせてもらいます

すみませんが
  はどういった意味でしょうか
つまらない質問ですいません


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

iPhoneのメモ帳から貼りつけたら、変な文字が挿入されてしまいました。
無視して下さい。


返信引用
TKO
 TKO
(@TKO)
ゲスト
結合: 15年前
投稿: 38
Topic starter  

ありがとうございます

このプログラムではpBB++で次のスライドや
p--で前のスライドの書き込み情報の参照をしたらよろしいのでしょうか??


返信引用
rock
 rock
(@rock)
ゲスト
結合: 15年前
投稿: 8
 

ポインタの配列を使うと良いかと。

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]);

そんなに難しくないはずなので、頑張って下さい。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました