ID登録せずに、無料で質問できる♪ 教えて!gooアプリ>>

お世話になります。
今回お聞きしたいことは
MFCでダイアログ上にリストコントロールとスクロールバー、またはピクチャーコントロールとスクロールバーを設置した際に、スクロールバーの移動に伴って、リストコントロール内の列や、ピクチャーコントロールに表示されている画像の見えている箇所を移動させることが出来るかどうか。
です。
まだ、本格的にプログラムを作り始めてるわけではないのですが、事前にこのような動作が実現可能かどうかお聞きしたく、質問させて頂きました。
もしご存知の方がいましたら、参考になるHPや方法を教えていただければと思っています。参考になるHPがなくても、実現可能かどうかだけ教えて下さるだけでも結構ですので、宜しくお願い致します。

開発環境は
Windows CE 6.0
Visual Studio 2005
です。

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

A 回答 (2件)

>仮想リストを使用する場合に特に普通のリストと、


>プログラムを作成する点で違う箇所はありますでしょうか?
プログラム的には大きく違います。オーナードローを使用するため、
使用するイメージ、項目等の領域は自分で保持、管理しなければ
なりません。
しかし、描画の高速化、メモリ節約が出来るという点は、
大きなメリットです。

>リストコントロールだと自動でスクロールバーを表示してくれる
>みたいなのですが、現在開発している機器がタッチパネル式のため、
>自動で表示されるスクロールバーではタッチするには小さいため、
>出来れば別で大きい垂直スクロールバーを設置して動かしたいと
>思っています。
>そのようにする場合にはDlgにOnVScroll()のイベントを作成して、
>その関数内でリスト内の項目を移動させるように処理すればよい
>のでしょうか?
そういった実装を行ったことが無いので、なんともいえないので、私の予想ですが、
clistctrlのスクロールバーをfalseにするということですよね。
そうすると、スクロールエリアがないということになると思うので、
そもそも移動が出来ないと思います。
スクロールバーをtrueにして、その上に強制的に独立した
スクロールバーを配置するなら別だと思いますが。。。
普通はそんなことはしないですよね。

もしかしたら、clistctrlクラスをオーバーラップし、そこで
GetScrollBarCtrlを利用しスクロールバーのポインタを取得して、
そのポインタ経由で、スクロールバーの大きさを変更するといった
ことは、出来るかもしれません。

すべては、予想ですが。。。
    • good
    • 0
この回答へのお礼

丁寧な説明ありがとうございます。
仮想リストのメモリの節約というのは限られたメモリの組み込み機器にはかなり大きなメリットですね!!
早速調べて使ってみたいと思います。

リストのスクロールバーについては、もう少し調べてみます。
リストの標準のスクロールバーを表示させて、他に上下移動用のボタンを配置させ、そのボタンをタッチさせスクロールバーを移動させたり、キーボード操作でスクロールバーを移動させたりでもいいかなと思っていますので、その方法でも検討してみて分からなければ、もしかすればもう一度こちらに質問させて頂くかもしれません。

ご回答ありがとうございました!

お礼日時:2009/05/25 10:36

結論は出来ます。



リストコントロールの場合は特別な処理はいりません。
リストコントロールのスクロールバーを有効にして、リストにデータをセットすれば、スクロールバーを動かすと勝手に描画領域は更新されます。
ただ、組み込み系ですので、メモリー等のことを考えると仮想リストとして実装する方が無難だと思います。
ちなみに、サムネイル表示も可能です。

ピクチャーコントロールでの実装経験が無いので、具体的な実装方法はわかりませんが、最悪ピクチャーコントロールを利用しなくても、スクロールバーとメモリデバイスコンテキストを使用して、移動量を取得して、自分で描画更新をかければ実装できると思います。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
仮想リストコントロールというのがあるのですね、初耳です。
ネットで調べてみると、仮想リストコントロールというのはリストへのデータの表示が早いみたいですね。
仮想リストを使用する場合に特に普通のリストと、プログラムを作成する点で違う箇所はありますでしょうか?
リストコントロールだと自動でスクロールバーを表示してくれるみたいなのですが、現在開発している機器がタッチパネル式のため、自動で表示されるスクロールバーではタッチするには小さいため、出来れば別で大きい垂直スクロールバーを設置して動かしたいと思っています。
そのようにする場合にはDlgにOnVScroll()のイベントを作成して、その関数内でリスト内の項目を移動させるように処理すればよいのでしょうか?
重ねての質問で申し訳ございませんが、ご回答を宜しくお願い致します。

お礼日時:2009/05/22 09:24

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

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

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

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

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

QMFC - ダイアログボックスのPictureControlへの画像表示

はじめまして。
現在MFCにおいて、ダイアログ形式のアプリケーションを作成しています。環境はVisual Studio 2005になります。
内容はWebカメラからのキャプチャを行い、そのキャプチャされた画像をダイアログ上に配置したPictureControlへ表示するというものです。

キャプチャされた画像は、1チャネルのグレースケールでありunsigned char型の1次元配列で格納されています。よってビットマップとして表示するには自身で構造体BITMAPINFOを作成しなければなりません。現状以下のように作成したのですが、うまく表示されません。

画像サイズは 320×240 です。
PictureControlのIDを IDC_BITMAP と設定し、
画素情報が格納されている配列を m_pbit とします。

int i;
CWnd *pWnd = GetDlgItem( IDC_BITMAP );
CDC *Capt = pWnd->GetDC();
BITMAPINFO bmif;

bmif.bmiHeader.biBitCount   =8;
bmif.bmiHeader.biClrImportant =0;
bmif.bmiHeader.biClrUsed    =256;
bmif.bmiHeader.biCompression  =0;
bmif.bmiHeader.biHeight     =240;
bmif.bmiHeader.biPlanes     =1;
bmif.bmiHeader.biSize      =sizeof(BITMAPINFOHEADER);
bmif.bmiHeader.biSizeImage   =320*240;
bmif.bmiHeader.biWidth     =320;
bmif.bmiHeader.biXPelsPerMeter =0;
bmif.bmiHeader.biYPelsPerMeter =0;

for(i=0; i<256; i++){
 bmif.bmiColors[i].rgbBlue = i;
 bmif.bmiColors[i].rgbGreen = i;
 bmif.bmiColors[i].rgbRed  = i;
 bmif.bmiColors[i].rgbReserved = 0;
}

SetDIBitsToDevice(Capt->m_hDC, 0, 0, 320, 240, 0, 0, 0, 240, m_pbit, &bmif, DIB_RGB_COLORS);

グレースケール画像なので配列bmiColorsは全て同色としました。
また、PictureControlのTypeをオーナ描画など全てのTypeを試しましたが、表示されませんでした。

必ずPictureControlに描画しなければならないという決まりはないのですが、ダイアログボックスにビットマップを表示するにはPictureControlだと考え、それに表示するようプログラムを組みました。

画素情報(グレースケールの輝度情報)のみ既知である状態からビットマップをダイアログに表示するためには他に方法があるのでしょうか?
上記のプログラムにおける間違い、またその他の方法についてアドバイスを頂けたらと思います。

よろしくお願いいたします。

はじめまして。
現在MFCにおいて、ダイアログ形式のアプリケーションを作成しています。環境はVisual Studio 2005になります。
内容はWebカメラからのキャプチャを行い、そのキャプチャされた画像をダイアログ上に配置したPictureControlへ表示するというものです。

キャプチャされた画像は、1チャネルのグレースケールでありunsigned char型の1次元配列で格納されています。よってビットマップとして表示するには自身で構造体BITMAPINFOを作成しなければなりません。現状以下のように作成したのですが、うま...続きを読む

Aベストアンサー

 こんにちは。
 パレットサイズ(biClrUsedの数字)の分だけRGBQUADの配列を拡張して割り当てないといけません。
 正しくは、以下です。実際には、予め割り当てておくのが良いでしょう。

//割り当てる
LPBITMAPINFO pbmi = static_cast<LPBITMAPINFO>(::malloc(sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256)));

pbmi->bmiHeader.biBitCount=8;
pbmi->bmiHeader.biClrImportant=0;
pbmi->bmiHeader.biClrUsed=256;
pbmi->bmiHeader.biCompression=0;
pbmi->bmiHeader.biHeight=240;
pbmi->bmiHeader.biPlanes=1;
pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biSizeImage=320*240;
pbmi->bmiHeader.biWidth=320;
pbmi->bmiHeader.biXPelsPerMeter=0;
pbmi->bmiHeader.biYPelsPerMeter=0;

for(i=0;i<256;i++)
{
pbmi->bmiColors[i].rgbBlue=i;
pbmi->bmiColors[i].rgbGreen=i;
pbmi->bmiColors[i].rgbRed=i;
pbmi->bmiColors[i].rgbReserved=0;
}

::SetDIBitsToDevice(Capt->m_hDC, 0, 0, 320, 240, 0, 0, 0, 240, m_pbit, pbmi, DIB_RGB_COLORS);

//開放する
::free(pbmi);
--------------------------------------------------------------------------------------------------------------
強引ですが、以下の様なやり方も出来ます。

struct BMI
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD arrPalette[256];
};

//キャストする
BMI bmi;
LPBITMAPINFO pbmi = reinterpret_cast<LPBITMAPINFO>(&bmi);

//ヘッダとパレットの代入をする
pbmi->bmiHeader.biBitCount=...

//使用する
::SetDIBitsToDevice(...)

//開放は必要ない

 こんにちは。
 パレットサイズ(biClrUsedの数字)の分だけRGBQUADの配列を拡張して割り当てないといけません。
 正しくは、以下です。実際には、予め割り当てておくのが良いでしょう。

//割り当てる
LPBITMAPINFO pbmi = static_cast<LPBITMAPINFO>(::malloc(sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * 256)));

pbmi->bmiHeader.biBitCount=8;
pbmi->bmiHeader.biClrImportant=0;
pbmi->bmiHeader.biClrUsed=256;
pbmi->bmiHeader.biCompression=0;
pbmi->bmiHeader.biHeight=240;
pbmi->b...続きを読む

QVC++プログラムをつかったBMP画像の拡大縮小について

現在VC++をつかった画像を扱うプログラミングを学習中なのですが、画像データの取り扱いについてわからないことがあるため教えていただきたいです。

BMP画像をバッファに取り込んだあとで、画像の縦横を拡大縮小したデータを新たなバッファに格納したいのですが、画像を拡大縮小する方法がわかりません。いくつかのプログラムのソースを見させていただいたのですが、BITMAPINFOHEADER構造体の中のbiWidthやbiHeightの値を変えているだけのようなのです。

これらの値を変えるだけで、指定した幅と高さに変換された画像データが得られるのでしょうか?
また、それで拡大縮小されるならば、変換された画像データは輝度情報が滑らかになるように何かしらの補正が加えられていたりするのでしょうか?それとも、途中途中の輝度を単純に抜いていたりするだけなのでしょうか。
その辺の原理についても教えていただけるとうれしいです。

お手数をかけますが、よろしくお願いします。

Aベストアンサー

> 実際に拡大縮小された画像のデータ(バッファ)がどこに格納されたのかわかりません・・・。

一般的には、メモリやVRAMに載ります。取得もできますが、DIBSectionを使うと、メモリとして参照しやすいです。

> また、StretchBlt関数は、描画を目的としているようなのですが、今回の場合、
> -- snip --
> 描画は無駄な手間のように思われます。

実際の画面に表示するかにかかわらず、WindowsのAPIにおける画像の操作は原則として「DC」という概念を使います。
メモリやプリンタもDCの一種と扱われますし、必ずしも画面描画は意味しません。
ビットマップに何か書くのも、DCと関連付けてそこに描画する仕組みです。

メモリ上で拡大縮小するということは、結局のところ突き詰めれば
元画像を読んで拡大縮小した画像をそこ(メモリ上)に描画している、
ということだと思いますが、いかがでしょう。

# C言語の入出力がコンソールにもファイルにも使えるようにFILE*を使うのとかと大差ない、
# DCってのはWindowsにおける「描画先」の抽象化された概念です。

> 何かスマートな方法はないものでしょうか?

DCという概念自体はWindows GDIの根底ですから、WindowsのAPIである限り、
他を使ってもIFは違えど内部的にはDCと大差ないと思われますが。
「質問者さんにとってのスマート」が不明ですが、自前で変換処理を書くか、
完全独自処理の画像変換ライブラリを持ってくるのがスマートですか。

> 実際に拡大縮小された画像のデータ(バッファ)がどこに格納されたのかわかりません・・・。

一般的には、メモリやVRAMに載ります。取得もできますが、DIBSectionを使うと、メモリとして参照しやすいです。

> また、StretchBlt関数は、描画を目的としているようなのですが、今回の場合、
> -- snip --
> 描画は無駄な手間のように思われます。

実際の画面に表示するかにかかわらず、WindowsのAPIにおける画像の操作は原則として「DC」という概念を使います。
メモリやプリンタもDCの一種と扱われま...続きを読む

Qダイアログをスクロールさせるには

MFCでウィンドウにダイアログボックスを張り付けた時に、
ダイアログボックスの表示させたい領域よりウィンドウサイズが小さい場合、
自動でスクロールバーを表示させるようにするにはどうすればいいのでしょうか?
ダイアログで表示させたい領域を区切ってスクロール判断をさせるようにはできないのでしょうか?

Aベストアンサー

そのアプリのベースは何でしょう?
MDI/SDI/Dialogベース、ドキュメントビューを使わないタイプなのか

ダイアログボックスを貼り付けてとありますがどのように実現なさっているのでしょう

CScrollViewの派生クラスなどであれば表示域以上のクライアントウィンドウを作ればビューにスクロールバーが作成するようになると思います

たとえば CFormView(CScrollViewの派生クラス)を使うのであれば
SetScrollSizesなどのメンバーを使うことで スクロールバーの表示やコントロール位置の設定などをWindowsに任せてしまうことが可能です

QCStaticコントロールの静的イメージ描画

はじめまして、質問させてください。

VC++ 2005 MFC で開発しております。

Picture Control(DDX CStasic型)に
イメージ(外部ファイル JPG)を静的に描画させたいのですが
方法がわかりません。

お詳しい方がおられましたら、ご教授お願いいたします。

ちなみに
CImageを使用して描画はできるのですが
その場合、OnPaintをオーバーライドして
描画更新処理を書かないと一度だけ描画されて終わって
しまうと思います。

CStaic変数にロードしたら
再度ロードされるまで
ずっと描画させていたいです。

以上になります。
宜しくお願いいたします。

Aベストアンサー

SelectObjectで選択するとその時まで選択されていたデバイスハンドルを返してきます
そのハンドルを一時変数に保存しておいて描画後に戻してやるのです

CBitmap* pOld = m_dcMem.SelectObject( &m_bmpMem );
といった具合で記憶して描画処理を行います
使用後に
m_dcMem.SelectObject( pOld );
といった具合にして m_bmpMemをDCからはずします
この後
m_ctlImage.SetBitmap( m_bmpMem );
といった具合に選択してやればできると思います

CStaticのTypeはビットマップで無いとSetBitmapでイメージを表示しません

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...続きを読む

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() を使えとか書いてあるけど。

Qリストビューのスクロールバーを非表示にしたい

eMbedded Visual C++ 4.0 、MFC 、ダイアログベースでプログラミングをしています。
リストビューのスクロールバーを非表示にしてCListCtrl::Scrollを使い別のプログラムからスクロールさせたく、
「EnableScrollBarCtrl」や「ShowScrollBar」を使ってみたりしましたが非表示にできません。
リストビューのプロパティで「スクロールさせない」にチェックすると、CListCtrl::Scrollによるスクロールができなくなってしまいます。
非表示でCListCtrl::Scrollでスクロールできる方法をご存知でしたら教えてください。

なぜ別のプログラムでスクロールさせたいのかといいますと複数のリストビューを連動させてスクロールさせたいためです。
eMbedded Visual C++ 4.0はVC++6.0と似ているようですのでそのあたりに詳しい方アドバイスをください。

Aベストアンサー

 こんにちは。実験してみた所、実現できましたのでご報告いたします。

・VC++6.0, MFC, にて行いました。
・リストビューのスクロールをしないにチェックします(消したいようですので)
・単独のスクロールバー(IDC_SCROLLBAR1)をダイアログに貼り付けて、リストビューをスクロールさせています。

以下参考程度に。

void CKaiketuDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください

//テスト用のスクロールバーに対して何かされた
if(::GetDlgCtrlID(pScrollBar->GetSafeHwnd()) == IDC_SCROLLBAR1)
{
//縦の移動量を示す変数
int vScroll = 0;

//何の操作か
switch(nSBCode)
{
//下方向関係が押された
case SB_LINEDOWN:
case SB_PAGEDOWN:vScroll = -10; break;

//上方向関係が押された
case SB_LINEUP:
case SB_PAGEUP:vScroll = 10;
}

//リストビューのクライアント領域をスクロールさせる
::ScrollWindowEx(m_listCtrl.GetSafeHwnd(), 0, vScroll, 0, 0, 0, 0, SW_SCROLLCHILDREN | SW_INVALIDATE);

//リストビュー内の全てのアイテムをスクロールさせる
for(int i = 0; i < m_listCtrl.GetItemCount(); ++i)
{
POINT ptPos = {0};
//アイテムの位置を取る
m_listCtrl.GetItemPosition(i, &ptPos);

//縦方向に向かって移動量を加算する
ptPos.y += vScroll;

//アイテム位置を設定する
m_listCtrl.SetItemPosition(i, ptPos);
}
}

CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

 こんにちは。実験してみた所、実現できましたのでご報告いたします。

・VC++6.0, MFC, にて行いました。
・リストビューのスクロールをしないにチェックします(消したいようですので)
・単独のスクロールバー(IDC_SCROLLBAR1)をダイアログに貼り付けて、リストビューをスクロールさせています。

以下参考程度に。

void CKaiketuDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び...続きを読む

Q構造体の初期化方法について

こんばんわ。
何度も申し訳ありません。

VC++.NET 2003を用いてコンソールプログラミングを行っています。前回この掲示板を利用して複数回実行するプログラムを作成し、そこに構造体を用いたプログラムを作成しました。以下に概要を示します。

グローバルで構造体を宣言しているため、複数回実行を行うプログラムでは前回の値が格納されたままであると思い、毎回実行時に構造体の初期化を行いたいと思っています。

そこで、以下に示します構造体の初期化はどのように記述すればよいのでしょうか?0で初期化したいと思っています。

よろしくお願い致します。

#define MAX 2000
//グローバル
struct tag{
int Npkt;
int gettime;
int rPkt;
int lossPkt;
}rdata[MAX];

main(){
  //for文で複数回実行処理
  for(i=0;i<=5;i++){
  //ここで構造体の初期化を記述する
//例として、5回プログラムを実行する
  }
}

こんばんわ。
何度も申し訳ありません。

VC++.NET 2003を用いてコンソールプログラミングを行っています。前回この掲示板を利用して複数回実行するプログラムを作成し、そこに構造体を用いたプログラムを作成しました。以下に概要を示します。

グローバルで構造体を宣言しているため、複数回実行を行うプログラムでは前回の値が格納されたままであると思い、毎回実行時に構造体の初期化を行いたいと思っています。

そこで、以下に示します構造体の初期化はどのように記述すればよいのでしょうか?0で初...続きを読む

Aベストアンサー

★まとめ
・既に『memset』関数や、『ZeroMemory』関数の回答があるので構造体の全体、1部の
 初期化の記述例を紹介します。
・それと『#include <memory.h>』を記述しないとメモリ関係の関数が利用できません。
 『ZeroMemory』関数の場合は『#include <windows.h>』があればそのまま利用できます。

●構造体全体を初期化
ZeroMemory( rdata, sizeof(rdata) ); または、
memset( rdata, 0, sizeof(rdata) ); です。

●構造体一部を初期化
ZeroMemory( &rdata[i], sizeof(struct tag) ); または、
memset( &rdata[i], 0, sizeof(struct tag) ); です。
※rdata[i]の1データだけ初期化します。

余談:
・『ZeroMemory』関数は Win32 API と分類されていますが、実体は『memset』関数に
 『#define』されているだけです。でも、戻り値を『VOID』型にキャストされているので
 『memset』関数のリターン値を取得できません。→第一引数のアドレスが『memset』関数
 ではリターンします。
・以上。おわり。

参考URL:http://taka.no32.tk/tips/Win32/ZeroMemory.html

★まとめ
・既に『memset』関数や、『ZeroMemory』関数の回答があるので構造体の全体、1部の
 初期化の記述例を紹介します。
・それと『#include <memory.h>』を記述しないとメモリ関係の関数が利用できません。
 『ZeroMemory』関数の場合は『#include <windows.h>』があればそのまま利用できます。

●構造体全体を初期化
ZeroMemory( rdata, sizeof(rdata) ); または、
memset( rdata, 0, sizeof(rdata) ); です。

●構造体一部を初期化
ZeroMemory( &rdata[i], sizeof(struct tag) ); または、
m...続きを読む

Qピクチャーコントロールへの描画方法について

お世話になります、fujitomoです。
現在、Visual Studio2005にてC++のダイアログベースのアプリケーションを作成しており、行き詰った箇所があったため質問させて頂きました。

アプリケーションの内容としては
現在、アプリケーションで、ダイアログベース上にピクチャーコントロールを2つ設置し、それぞれに波形を描画させています。
ピクチャーコントロールへの波形の描画にはメモリデバイスコンテキストを使い、それぞれ波形描画用のCStatic派生クラスを作成し、そのクラスを
SubclassDlgItem
でメインダイアダイアログのサブクラスとし、描画間隔として、それぞれの描画クラス内で
SetTimer(1,10,NULL)
でタイマーイベントを起こし、メモリデバイスコンテキストの描画更新をしています。

ここで質問させていただきたい事なのですが、
2つのピクチャーコントロールのうち、1つのピクチャーコントロールへのみ波形描画を実行させているときはピクチャーコントロールの端から端まで描画が約7秒かかるのに対し、
2つのピクチャーコントロールの描画を同時に実行させた場合には端から端までで約11秒もかかってしまいます。
これを何とか、1つのピクチャーコントロールへの描画時間と同じ時間まで早く出来ればなと思っているのですが、どの様に工夫すれば時間短縮をさせることが出来ますでしょうか?

2つのクラスでそれぞれ10msのタイマーを動かしているのが問題なのかと思い、メインダイアログで10msのタイマーイベントを発生させ、それぞれの描画クラスに描画更新のメッセージを送信させるようにコードを変更してみたのですが、やはり同じ結果となりました。

開発環境は
Widows CE 6.0
Visual Studio 2005
です。
ご意見、ご回答をお待ちしております。よろしくお願い致します。

お世話になります、fujitomoです。
現在、Visual Studio2005にてC++のダイアログベースのアプリケーションを作成しており、行き詰った箇所があったため質問させて頂きました。

アプリケーションの内容としては
現在、アプリケーションで、ダイアログベース上にピクチャーコントロールを2つ設置し、それぞれに波形を描画させています。
ピクチャーコントロールへの波形の描画にはメモリデバイスコンテキストを使い、それぞれ波形描画用のCStatic派生クラスを作成し、そのクラスを
SubclassDlgItem
でメイン...続きを読む

Aベストアンサー

 こんにちは。
 どの様な手段で描写をしているのか、不明瞭ではありますが、思い当たる節を挙げて行くと、

(1)波形を描画する際に使用しているAPIがSetPixel()であった場合、直ちに別のAPIを使用する。このAPIの超絶的な鈍重さは曰くつきである。
(2)ビットマップを使用している場合、DIBを使用していれば、直ちにDDBへ変更する。
(3)理由無しにStretchBltを使用している場合、BitBltに変更する。
(4)描画する度にInvalidateRect()の様なAPIを呼ばない。
(5)非表示エリアは計算だけで描画しない様にする。

 と言った所でしょうか。WinCEの場合は全く当てはまらないかもしれませんので、参考程度で(其れでも(1)(2)は超絶的な速度低下の元であると思う)。

QMFCで画像を表示させているのですが、透過表示する方法がわかりません。

VC2005のMFCで画像を表示させているのですが、透過表示する方法がわかりません。

OnDraw(CDC* pDC)

で、#include <atlimage.h>として、

CImage img;
img.Load( "test.gif" );
CDC* pDCImg = CDC::FromHandle( img.GetDC() );
pDC->BitBlt( 60, 10, img.GetWidth(), img.GetHeight(), pDCImg, 0, 0, SRCCOPY );
img.ReleaseDC();


すればGIF画像が表示されましたが、このGIG画像は透過GIFですが
そのまま表示されているので、背景が黒の場合透、明部分の白が見えて
四角い枠の画像となります。

GIF透過ファイルの場合、そのまま透過になる方法や、何か手段を用いて透過をさせたいです。

Aベストアンサー

ごめんなさい GetColorTableなどは使えないようです
当方で実験したところ gifを読み込んだ時点の CImageクラス内部での表現が現在のWindowsシステムの設定に依存するようです
256色パレットモードではなく 32ビットのBMPとして取り込まれていました

したがって CDCのTrabsparentBltで行ったほうが良いでしょう
int w = img.GetWidth();
int h = img.GetHeight();
COLORREF col = img.GetPixel( 0, 0 );
pDC->TransparentBlt( 0, 0, w, h, pDCImg, 0, 0, w, h, col );

またパレットが取得できる場合の検索方法ですが
COLORREF col = img.GetPixel( 0, 0 );
RGBQUAD pal[256];
img.GetColorTable( 0, 256, pal );
int nIndex = -1;
for n = 0; n < 256; n++ ) {
  if ( ( pal[n].rgbRed == ( col & 0xFF ) ) &&
     ( pal[n].rgbGreen == ( ( col & 0xFF00 ) >> 8 ) ) &&
     ( pal[n].rgbBlue == ( ( col & 0xFF0000 ) >> 16 ) ) ) {
    nIndex = n;
    break;
  }
}
img.SetTransparentColor( nIndex );
といった具合でしょう ...
# 思いつきで投稿するとこういったポカをやります m(__)m

ごめんなさい GetColorTableなどは使えないようです
当方で実験したところ gifを読み込んだ時点の CImageクラス内部での表現が現在のWindowsシステムの設定に依存するようです
256色パレットモードではなく 32ビットのBMPとして取り込まれていました

したがって CDCのTrabsparentBltで行ったほうが良いでしょう
int w = img.GetWidth();
int h = img.GetHeight();
COLORREF col = img.GetPixel( 0, 0 );
pDC->TransparentBlt( 0, 0, w, h, pDCImg, 0, 0, w, h, col );

またパレットが取得できる場合の...続きを読む


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

人気Q&Aランキング