A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
こんにちは。
当方が知る限りではDirectDrawで出来ます(Direct3Dでは分からない)。
以下は1秒間デスクトップの中央に描写を行いますが、実際のプログラムは、1秒で終わる事は無いので、別途DirectInputを併用して、入力を待機する事になると思います。
ビットマップファイルを読み込んで、DirectDrawSurfaceに向かって送り込む際、必ず、SYSTEMメモリ側のDirectDrawSurfaceを仲介してください。
ビデオカードの種類によっては、VRAM側で出来てしまう物もあるのですが、其れを期待すると、別のビデオカードで失敗する事があります。
昔のゲームはこのような理由で、シャットダウンする物がありました。以下参考程度に。
#include<windows.h>
#include<tchar.h>
#include<ddraw.h>
#include<mmsystem.h>
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "ddraw.lib")
#pragma comment(lib, "winmm.lib")
//スレッドから参照するデータ
struct DATA
{
LPDIRECTDRAW7 pDD;
LPDIRECTDRAWSURFACE7 pDDSScreen;//デスクトップ
LPDIRECTDRAWSURFACE7 pDDSOffScreen;//VRAM側バックバッファ
LPDIRECTDRAWSURFACE7 pDDSBitmap;//SYSTEM側バックバッファ
DWORD dwDesktopWidth;
DWORD dwDesktopHeight;
};
//COMの解放
static VOID Destruct(DATA& data)
{
data.pDDSScreen->Release();
data.pDDSOffScreen->Release();
data.pDDSBitmap->Release();
data.pDD->Release();
}
//DirectDrawの作成
static LPDIRECTDRAW7 CreateDD()
{
LPDIRECTDRAW7 pDD = NULL;
::DirectDrawCreateEx(NULL, (LPVOID*)&pDD, IID_IDirectDraw7, NULL);
if(!pDD)return NULL;
pDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
return pDD;
}
//DirectDrawSurface作成(デスクトップ側)
static LPDIRECTDRAWSURFACE7 CreateScreenSurface(LPDIRECTDRAW7 pDD)
{
LPDIRECTDRAWSURFACE7 pDDS = NULL;
DDSURFACEDESC2 ddsd2 = {sizeof(ddsd2)};
ddsd2.dwFlags = DDSD_CAPS;
ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
pDD->CreateSurface(&ddsd2, &pDDS, NULL);
return pDDS;
}
//DirectDrawSurface作成(オフスクリーン側:バックバッファの事)
static LPDIRECTDRAWSURFACE7 CreateOffScreenSurface(LPDIRECTDRAW7 pDD, DWORD dwWidth, DWORD dwHeight, bool bSystem = false)
{
LPDIRECTDRAWSURFACE7 pDDS = NULL;
DDSURFACEDESC2 ddsd2 = {sizeof(ddsd2)};
ddsd2.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | (bSystem ? DDSCAPS_SYSTEMMEMORY : DDSCAPS_VIDEOMEMORY);
ddsd2.dwWidth = dwWidth;
ddsd2.dwHeight= dwHeight;
pDD->CreateSurface(&ddsd2, &pDDS, NULL);
return pDDS;
}
//ビットマップを読み込んで、SYSTEMメモリ側のDirectDrawSurfaceに送り込む
static LPDIRECTDRAWSURFACE7 CreateBitmapSurface(LPDIRECTDRAW7 pDD, LPCTSTR tstrFileName, DWORD dwWidth, DWORD dwHeight)
{
DDSURFACEDESC2 ddsd2 = {sizeof(ddsd2)};
LPDIRECTDRAWSURFACE7 pDDS = ::CreateOffScreenSurface(pDD, dwWidth, dwHeight, true);
if(!pDDS)return NULL;
//ビットマップをファイルから読む
HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, tstrFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
BITMAP bitmap;
::GetObject(hBitmap, sizeof(bitmap), &bitmap);
//ビットマップデバイスコンテキストの作成
HDC hDCMem = ::CreateCompatibleDC(NULL);
HGDIOBJ hGdiObj = ::SelectObject(hDCMem, hBitmap);
//サーフェースデバイスコンテキストの作成(ビデオカードによってはVRAMから作成出来るが、SYSTEMメモリ側で行うのが無難)
HDC hDCSurface = NULL;
pDDS->GetDC(&hDCSurface);
::StretchBlt(hDCSurface, 0, 0, dwWidth, dwHeight, hDCMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
pDDS->ReleaseDC(hDCSurface);
//ビットマップの解放
::SelectObject(hDCMem, hGdiObj);
::DeleteDC(hDCMem);
::DeleteObject(hBitmap);
return pDDS;
}
//DirectDrawSurfaceから矩形サイズを取る
static const RECT GetSurfaceRect(LPDIRECTDRAWSURFACE7 pDDS)
{
DDSURFACEDESC2 ddsd2 = {sizeof(ddsd2)};
ddsd2.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
pDDS->GetSurfaceDesc(&ddsd2);
const RECT rc = {0, 0, ddsd2.dwWidth, ddsd2.dwHeight};
return rc;
}
//スレッド
static DWORD WINAPI ThreadProc(LPVOID p)
{
DATA* pdata = (DATA*)p;
const DWORD dwStart = ::timeGetTime();
RECT rc = ::GetSurfaceRect(pdata->pDDSOffScreen);
//デスクトップの中央に来る様に座標x,yを計算する
const POINT pt = {(pdata->dwDesktopWidth - rc.right) / 2, (pdata->dwDesktopHeight - rc.bottom) / 2};
//一秒間回す
while(::timeGetTime() - dwStart <= 1000)
{
//VRAMに描写
pdata->pDDSScreen->BltFast(pt.x, pt.y, pdata->pDDSOffScreen, &rc, DDBLTFAST_WAIT);
}
return 0;
}
//お試し
int main(void)
{
DATA data = {NULL};
//デスクトップのサイズを計測する
HWND hWndDesktop = ::GetDesktopWindow();
HDC hDCDesktop = ::GetDC(hWndDesktop);
data.dwDesktopWidth = ::GetDeviceCaps(hDCDesktop, HORZRES);
data.dwDesktopHeight= ::GetDeviceCaps(hDCDesktop, VERTRES);
::ReleaseDC(hWndDesktop, hDCDesktop);
//DirectDrawの初期化
data.pDD = ::CreateDD();
data.pDDSScreen = ::CreateScreenSurface(data.pDD);
data.pDDSBitmap = ::CreateBitmapSurface(data.pDD, _T("test.bmp"), 640, 480);
data.pDDSOffScreen = ::CreateOffScreenSurface(data.pDD, 640, 480);
//SYTEM→VRAMへ複写
RECT rc = {0, 0, 640, 480};
data.pDDSOffScreen->BltFast(0, 0, data.pDDSBitmap, &rc, DDBLTFAST_WAIT);
//タイマ解像度の初期化
TIMECAPS tc = {0};
::timeGetDevCaps(&tc, sizeof(tc));
::timeBeginPeriod(tc.wPeriodMin);
//スレッドを回転させる
DWORD dwThreadID = 0;
HANDLE hThread = ::CreateThread(NULL, 0, &::ThreadProc, &data, CREATE_SUSPENDED, &dwThreadID);
::SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST);
::ResumeThread(hThread);
//スレッドが落ちてくるまで待つ
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
//デスクトップを書き直す
::InvalidateRect(NULL, NULL, NULL);
//COMの解放
::Destruct(data);
//タイマ解像度を戻す
::timeEndPeriod(tc.wPeriodMin);
return 0;
}
No.2
- 回答日時:
試していないので出来るかどうかわからないのですが、
http://hp.vector.co.jp/authors/VA012320/directx6 …
でVRAMに直接アクセス可能のようですけど、詳しく見てないので分かりません。
(DirectXを使用しているみたいです。)
何らかのライブラリを使わないと、
難しいのではないかと思われます。
英語がある程度できるのであれば、
海外(アメリカ)サイトを探してみてはどうでしょうか?
No.1
- 回答日時:
こんな感じのものでしょうか?
http://wisdom.sakura.ne.jp/system/winapi/win32/w …
もし違うなら無視してかまいません。
「別のウインドウに隠れることなく表示できて~」は、
もしかしたら出来ないかもしれません。
一応当方で試した結果出来ました。
この回答へのお礼
お礼日時:2009/05/15 23:58
回答ありがとうございます。
勉強になりました。
さらに欲を言いますと、ウインドウハンドルを持たず、VRAMに直接描画するような方法についても調べていました。メッセージフック関数に感知されない、描画したときにウインドウメッセージが流れないようにすることはできないですよね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(OS) Mac OSの操作について 2 2022/06/08 09:19
- Windows Me・NT・2000 IMEオプションが開かない 2 2023/04/07 18:04
- マウス・キーボード ロジクールのマウスでの不具合について 2 2022/10/26 12:04
- Windows 10 Windows 10の立ち上げについて 2 2022/04/17 13:36
- Windows 10 パソコンの起動時、画面が黒いままのトラブルにつきまして。 4 2022/10/02 18:02
- 画像編集・動画編集・音楽編集 gomcamの起動にブロックがかかる 1 2023/07/28 23:34
- テレビ テレビのチャンネル表示 1 2022/12/04 17:29
- オープンソース Excelファイルをデバッグしたい 4 2022/09/15 10:16
- マウス・キーボード real vnc viewer で遠隔先で操作が出来ない。 2 2023/07/24 15:00
- Windows 10 「新規作成」メニューが表示されません 2 2023/04/07 14:56
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エディットコントロール入力時...
-
プログラミングでエラーが出ま...
-
エディットボックスの背景の色...
-
エラー Run-Time Check Failur...
-
音量調節
-
Win32APIでウィンドウを中央に...
-
1~1000,1001~2000の間に素数が...
-
c言語のプログラミングでキーボ...
-
オーバーレイみたいな処理がしたい
-
「指定されたキャストは有効で...
-
DWORDの実際の型は何でしょうか
-
プログラムでの数字につく”f”の...
-
プログラミング初心者です。 Py...
-
信頼区間の1.96や1.65ってどこ...
-
C言語での引数の省略方法
-
20'(角度)の計算がわかりま...
-
エクセルで可視セルにのみ値貼...
-
「Aに対するBの割合」と「Aに対...
-
Enterキーを押されたら次の処理...
-
ある商品のロス率を5%見込み、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
音量調節
-
エラー Run-Time Check Failur...
-
Win32APIでウィンドウを中央に...
-
return文がない場合の戻り値は...
-
1~1000,1001~2000の間に素数が...
-
ダイアログプログラムでEnterキ...
-
ボタンの色(WINAPI)
-
C言語win32api、エディットボッ...
-
MessageBoxについて
-
プログラミングでエラーが出ま...
-
キャレットの現在位置の表示 (W...
-
エディットボックスの背景の色...
-
エディットコントロール入力時...
-
オーバーレイみたいな処理がしたい
-
ウィンドウのサイズ変更について
-
C#のswitch文を簡略化したいの...
-
猫でもわかるWindowsプログラミ...
-
WM_INITDIALOGのフック
-
MoveToExとLineToについて
-
【Windowsアプリ】ファイルのド...
おすすめ情報