VCでデスクトップ画面に、テレビのチャンネル表示のような文字を表示させたいのですが、方法がわかりません。

別のウインドウに隠れることなく表示できて、マウスでクリックできないようなものを作ることは可能でしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (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;
}
    • good
    • 0
この回答へのお礼

詳しい回答ありがとうございます。
DirectX環境構築して試してみます。

お礼日時:2009/05/18 14:27

試していないので出来るかどうかわからないのですが、


http://hp.vector.co.jp/authors/VA012320/directx6 …
でVRAMに直接アクセス可能のようですけど、詳しく見てないので分かりません。
(DirectXを使用しているみたいです。)

何らかのライブラリを使わないと、
難しいのではないかと思われます。

英語がある程度できるのであれば、
海外(アメリカ)サイトを探してみてはどうでしょうか?
    • good
    • 0

こんな感じのものでしょうか?


http://wisdom.sakura.ne.jp/system/winapi/win32/w …
もし違うなら無視してかまいません。

「別のウインドウに隠れることなく表示できて~」は、
もしかしたら出来ないかもしれません。
一応当方で試した結果出来ました。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
勉強になりました。
さらに欲を言いますと、ウインドウハンドルを持たず、VRAMに直接描画するような方法についても調べていました。メッセージフック関数に感知されない、描画したときにウインドウメッセージが流れないようにすることはできないですよね。

お礼日時:2009/05/15 23:58

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLPCWSTRとchar

質問なのです・・・

現在、私は[Visual Stdio.Net 2005]を使って、C++のプログラミングをしようと思いまして、今日参考書を見てやってみたのですが、

charの配列を使って、文字列を格納しそれを使おうとしたら、LPCWSTRのキャストが必要というエラーがでました。
参考書だと普通に通るらしいのですが・・・Visual Stdio.Net 2003と2005の違いなのでしょか?わかる方教えていただけませんでしょうか??

Aベストアンサー

補足です。
2005デフォルトのUNICODEを変更する方法は
プロジェクト->プロパティ->構成プロパティ->全般 の中にある
文字セットを[Unicode 文字セットを使用する]から[マルチバイト文字セットを使用する]
に変更することで可能です。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

QcharからLPTSTRへの変換方法

リストコントロールにchar型の変数の値を数値として表示させたいのですが、charからLPTSTRへの洗練された変換方法がよくわからないです。

char tempChar;
CString tempString;
tempString.Format("%s", tempChar);
LPTSTR lpsz = new TCHAR[tempString.GetLength()+1];
_tcscpy(lpsz, tempString);

こんなプログラムを考えてみたのですが、汚いような気がします。もっと簡単で洗練された変換方法はないのでしょうか?

Aベストアンサー

wsprintfを使ってはどうでしょうか?

char tmpChar = 100;//表示する数値
TCHAR buf[5];
wsprintf(buf, "%d", tempChar);

QC#で構造体の配列を持った構造体を使いたいのですが

C#で構造体の配列を持った構造体を使いたいのですが
Cならば
struct xyz {
struct abc _abc[32];
int index;
};
struct abc {
int a;
int b;
int c;
};

struct xyz _xyz[8];
xyz[0]._abc[3].b = 1;

のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません
うまくやる方法をどなたかご存知ないでしょうか

Visual Studio 2005行った場合
コンパイルで
構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するには、次元指定子を変数の識別子の前に指定します。固定サイズ バッファ フィールドを宣言するには、フィールド型の前に fixed キーワードを使用します
となり

fixed をつけると

固定サイズ バッファの型は次のうちの 1 つでなければなりません: bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float または double

となってしまいます

C#で構造体の配列を持った構造体を使いたいのですが
Cならば
struct xyz {
struct abc _abc[32];
int index;
};
struct abc {
int a;
int b;
int c;
};

struct xyz _xyz[8];
xyz[0]._abc[3].b = 1;

のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません
うまくやる方法をどなたかご存知ないでしょうか

Visual Studio 2005行った場合
コンパイルで
構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するに...続きを読む

Aベストアンサー

C# では、配列は「単なる連続したメモリ領域」ではなくて「添字によってオブジェクトを格納できるオブジェクト」であることに注意しなくてはいけません。つまり、C では配列は一種の構造体でしたが、C# では配列は参照型のオブジェクトです。
よって、C のように予めサイズを固定しておくということは基本的にできません。配列の大きさは配列のインスタンスが作られるときに動的に決まります。

C# では、参照型のオブジェクトを構造体のメンバにすることはあまりありません。null 値の扱いが面倒だからです。
また、C# では構造体の大きさは大きくとも 20 バイト程度までにします。C# では基本的に「構造体へのポインタ」はありません。巨大な構造体をそのまま扱うのはメモリの使い方の観点からいって非効率的です。

今回の件では、構造体ではなくクラスにするのがよいかと思われます。

Q構造体の代入と比較

構造体のコピーは以下のようで正しいと思いますが、

struct A {
int a;
};

struct x, y;

x.a=1;
y = x;

構造体の比較は
if (x != y)ではいけないのでしょうか?

構造体に限らずクラスも同じ考えでしょうか?

Aベストアンサー

★軽くアドバイス
・回答者No.3さんの
>if (memcmp(&x, &y, sizeof(struct A)) != 0)
 この方法はちょっと注意が必要です。
 アライメントに気をつけましょう。
・代入の方は古いCコンパイラでは無理なことがあります。
 最近のコンパイラなら問題はありません。

Qダイアログ内コントロールの位置取得について

いつもお世話になっております。

ダイアログ内に配置されているコントロールの位置の取得方法について
ご教授頂きたく質問させていただきました。

私が試したところGetWindowRect( コントロールハンドル, &rc );
とするとありえないぐらい大きな座標が帰ってきます。

上記の方法ではうまくいきません。
ご教授よろしくお願いいたします。

Aベストアンサー

>http://msdn.microsoft.com/ja-jp/library/cc364604.aspx
より
>クライアント座標はクライアント領域の左上端からの相対座標なので、左上端の座標は常に (0,0) となります。
となっているため
>GetClientRectでダイアログ内の相対位置を取れます。
は間違っていました。

>もしかしたら便利な関数が存在するのでしょうか?
ないのかなぁと。
かわりにこんな関数を作っておくとか。

BOOL GetDlgItemRect(HWND hDlg, int nIDDlgItem, RECT* rct)
{
  BOOL bRet = FALSE;
  HWND hWnd = GetDlgItem(hDlg, nIDDlgItem);
  if (hWnd != NULL)
  {
    bRet = GetWindowRect(hWnd, rct);
    {
      bRet = ScreenToClient(hDlg, rct);
    }
  }
  return bRet;
}

>http://msdn.microsoft.com/ja-jp/library/cc364604.aspx
より
>クライアント座標はクライアント領域の左上端からの相対座標なので、左上端の座標は常に (0,0) となります。
となっているため
>GetClientRectでダイアログ内の相対位置を取れます。
は間違っていました。

>もしかしたら便利な関数が存在するのでしょうか?
ないのかなぁと。
かわりにこんな関数を作っておくとか。

BOOL GetDlgItemRect(HWND hDlg, int nIDDlgItem, RECT* rct)
{
  BOOL bRet = FALSE;
  HWND hWnd = GetDlgIt...続きを読む

QCStringからchar*への型変換について教えてください。

以前の質問に

int型 → CString型/char型

がありましたが、

CString型をchar*型に変換する方法を
教えていただければありがたいです。

MSDNで「LPCTSTRキャスト」が説明されていましたが、
例が載ってないのでよくわかりませんでした。

よろしくお願いします。

Aベストアンサー

目的にもよりますが一時的にchar配列として使いたいならCString::GetBuffer()が利用できます。
char配列としての利用が終わったらCString::ReleaseBuffer()する必要がありますが。

直接CString内の文字列を扱う必要があるならCString::operator LPCTSTRで文字列ポインタが得られます。
ただし、CStringオブジェクトをいじると無効ポインタなる可能性があるので気をつけてください。

MSDNのMicrosoft Foundation Classリファレンス→CString→クラスメンバで確認してください。

QUpdateData( FALSE); による文字列データの表示更新(VC++6.0)

VC++の超初心者です.

UpdateData( FALSE );
を用いてエディットボックスの文字列の表示の更新を
試みているのですが,たとえば,以下のコードのようにボタンをクリックした際に文字列表示の更新を複数回行おうとするとうまくいきません.
具体的には一回目のUpdateData( FALSE );が反映されず二回目のUpdateData( FALSE );のみ反映されるという症状です.

なおm_mojiretsuはCstring型でエディットボックスのDDX用の変数です.

void CMyDlg::OnButton1()
{
DWORD p;

m_mojiretsu=_T("mojirstu1");
UpdateData( FALSE );

/*5秒の待ち*/
p=timeGetTime();
while(1){if((timeGetTime()-p)>5000) break;}

m_mojiretsu=_T("mojirstu1\r\nmojirstu2");
UpdateData( FALSE );

}


何か別の処理を行わなければいけないのでしょうか.
どこかに根本的なミスがあるのでしょうか.

VC歴3日程度で,右も左も分からず大変困っております.よろしくお願いします.

VC++の超初心者です.

UpdateData( FALSE );
を用いてエディットボックスの文字列の表示の更新を
試みているのですが,たとえば,以下のコードのようにボタンをクリックした際に文字列表示の更新を複数回行おうとするとうまくいきません.
具体的には一回目のUpdateData( FALSE );が反映されず二回目のUpdateData( FALSE );のみ反映されるという症状です.

なおm_mojiretsuはCstring型でエディットボックスのDDX用の変数です.

void CMyDlg::OnButton1()
{
DWORD p;

m_mojiretsu=_T("mojirst...続きを読む

Aベストアンサー

m_mojiretsu=_T("mojiretsu1");
UpdateData(FALSE);
UpdateWindow(); // <- これを追加

/*5秒の待ち*/
...

とすれば、ひとまず期待どおりの動作になると思います。

# こうするよりは、OnButton1() では変数を書き換えるべしと言う
# 自前のコマンドメッセージを投げるだけで、すぐに戻った方が
# お行儀は良いのですが...
# そこいらへんは追々調べたり試したりしてみて下さい。

QVC++のエディットボックスの非表示

VC++で、ダイアログを作りました。
エディットボックスを置いているのですが、
このエディットボックスは始めは非表示(入力を受け付けない)にするため、
このエディットボックスのプロパティにある
"Disable"をtrueにして"Visible"もtrueにしました。

そこまではよかったのですが、
「入力」ボタンを押すと、エディットボックスが白く表示され、入力を受け付けるというようにしたいのですが、
エディットボックスのプロパティを変更する関数というのはあるのでしょうか?

いろいろ検索などをしているのですが、方法がわかりません。よろしくお願いします。

Aベストアンサー

以前、CWndクラスを使用してくださいと回答したものです。
説明がたりなくてすみません。
コントロールの親クラスは、CWndなので操作関数が使えます。


ボタン1を押すとテキスト1が活性化
void CAboutDlg::OnBnClickedButton1()
{
CWnd* pWnd = GetDlgItem(IDC_EDIT1);
pWnd->EnableWindow(TRUE);
}
こんな感じです。コントロールIDを指定して、他のコントロールの
オブジェクトハンドルも取得可能です。

QC#にて別クラスの関数を使いたい

C#にて、別クラスの関数を使用する方法を教えてほしいです。

下記のような、構造体を受け取るメソッドを作りました。

*****************************
private struct MyPoint
{
public int x;
public int y;
}

private void proc1(MyPoint pt)
{
MessageBox.Show("座標:" ; pt.x + "," + pt.y + "実行結果");
}

private void button1_Click(object sender ,System.EventArgs e)
{

MyPoint pt;
pt.x = 10;
pt.y = 20;
proc(pt);
}
*****************************

別のフォームのクラスから、proc1を呼び出したいのですが、やり方がわかりません。
どうか、教えてください。

Aベストアンサー

同じ定義をしたとしても別の名前空間に書いた構造体は同一とはみなされません。

呼び出し先クラスでの構造体を private では無く、public で宣言して下さい。

呼び出し元では、

MyClass.MyPoint pt;

のようにして実体を作ります。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報