Win2000 SP4 VC++2005 Win32APIで開発を行っています。
また、まだプログラムを初めて1ヶ月でWin32が少しわかってきた程度でMFCはさっぱりです。
ここで示さなければ行けない情報を示しきれていないかもしれませんが質問させてください。
現在ある製品のSDKを用いてアプリを作ろうとしているのですが
そのSDKのサンプルプログラムがMFCでしか用意されていないため
Win32アプリにMFCのコードが混在するという状況になっています。
(既存のWin32アプリに機能追加しようとしているため)
コンパイルは通るのですが
POSITION pos;
pos =::AfxGetApp()->GetFirstDocTemplatePosition();
↑が実行されると
appui2.cppの
POSITION CWinApp::GetFirstDocTemplatePosition() const
{
if(m_pDocmanager == NULL)
云々
}
↑の部分でメモリのアクセス違反が発生します。
この次の処理としてはあたらしくウインドウを作ってそこに描画するようなプログラムに
なっています。
ちなみにウインドウの作成はWin32で行っていますがMDIの指定はしていません。
試しにpos=0として次に進んでみましたがアクセス違反は出ないものの新しいウインドウ
が生成されることはありませんでした。
pos =::AfxGetApp()->GetFirstDocTemplatePosition();
に相当するような別のプログラムやアクセス違反が出ないように書き直すにはどうしたら
いいでしょうか?
よろしくお願いします。
無茶だな
mfcアプリじゃないから
そもそもドキュメントビューなんて必要なのか?
たぶん誤魔化そうとするくらいならいらない処理
必要ならmfcアプリ作るといい
pos=
の部分はサンプルプログラムからひっぱってきたまんまなんです。
なのでほかのコードで代用できるものがあればおしえていただきたいな、と思っています。
おっしゃるとおりMFCで作れればいいのですが現在あるWin32のプログラムに機能追加した
いと考えているので
MFCにする場合はそのプログラムをMFCに移植する作業というのが発生するわけです・・・。
そしておそらくこの部分さえコードが通れば作成中のプログラムがほとんど完成するので
はないかと思います。
(他の部分は問題なく動作するため)
「GetFirstDocTemplatePosition() 」はMFC独自の「ドキュメント ビュー形式」
(でよかったでしょうか?)で使う方法です。
SDKにはないと思います。
まぁーMFCはSDKを使いやすくしたものですから、SDKで同じ機能のものを作れない
ことはないと思いますが。
僕も分かりませんし、かなり難しいと思います。
修正です
>で使う方法です。
で使うMFC独自の関数です。
追記
あと、何のためにMFCアプリを追加しなければいけないのか理由を書いてもらえると、
SDKでどうするのかアドバイスできるかもしれません。
#include <afxwin.h>
を宣言しているのでほかのMFCコードは動いている(?)と思います。
追加したい機能はほとんどMFCのサンプルプログラムから引っ張ってきていますが
問題は今のところトピックの部分だけで、ここをコメントアウトすることで
他の部分は動いています。
MFCを追加する理由ですが・・・
大学で今ある実験システムにカメラシステムを追加しようとしています。
そしてそのカメラシステムを購入したのですが、
カメラを制御するプログラムを作ろうしてつまずいています。
カメラシステムに付属していたソフトのSDKを使って
今まであった実験システムの制御プログラムにカメラを制御する機能を追加しようとして
いるわけです。
そして具体的にはあと必要なのはカメラのプレビュー画面だけなのです。
問題のところはWM_CASE云々で関数が呼び出され、一行一行進む中で
新しいウインドウが作成されてそこにプレビュー映像が表示されるようです。
posが
pos =::AfxGetApp()->GetFirstDocTemplatePosition();
で取得されたあとに
CDocTemplate* pTemplate;
pTemplate = ::AfxGetApp()->GetNextDocTemplate(pos);
CDocument* pDoc = pTemplate->OpenDocumentFile(NULL);
とウインドウが生成されていっているようです。
pos=0としたときはアクセス違反が発生せずに実行できたので
posになにか値を与えてあげればそれでいいような気もします。
(もちろんウインドウは生成されませんでしたが)
どこまで情報を出すべきなのかわかっていません。
小出しにしているようで本当に申し訳ありません。
ひっぱてきてる部分は
「MFCのドキュメントアーキテクチャを利用している場合に
その機能を利用する方法」
部分であって、
「カメラ画像をビューに出す」
とは無関係に近いです
たとえば
>CDocument* pDoc = pTemplate->OpenDocumentFile(NULL);
OpenDocumentFileなんかは、ウィンドウを生成する命令ではありません
ドキュメントアーキテクチャにおいて
ドキュメントを開く目的であり、その一環でウィンドウが開いてるだけ
MFCを無理やり通すことより
WIN32でビューを出す方法を勉強したほうが
近道だと思います。
ハードインタフェースはUSBかな?
>>rinさん
>OpenDocumentFileなんかは、ウィンドウを生成する命令ではありません
>ドキュメントアーキテクチャにおいて
>ドキュメントを開く目的であり、その一環でウィンドウが開いてるだけ
それはまったく知りませんでした。ただウインドウを作成しているだけではないのですね
もしよろしければWin32でビューを取得する方法を解説しているHPなどがあれば
おしえていただけませんか?
検索した限りでは発見することができませんでした。
>>経験者さん
ギガビットイーサネットを使ったカメラです。
rinさんに教えていただいたことで少しどうなってるのかわかってきました。
また小出しになってしまいました。本当に申し訳ありません。すべて書きます。
//表示用ウインドウを,カメラ数分開く
CDocTemplate* pTemplate;
POSITION posView;
POSITION pos;
pos =::AfxGetApp()->GetFirstDocTemplatePosition();
if(pos != NULL)
{
pTemplate = ::AfxGetApp()->GetNextDocTemplate(pos);
if(pTemplate)
{
for(UINT n = 0; n < m_pCaptures->GetCaptureCount(); n++)
{
//ドキュメントをクリエイト
CDocument* pDoc = pTemplate->OpenDocumentFile(NULL);
//ビューを取得
posView = pDoc->GetFirstViewPosition();
CView* pView = pDoc->GetNextView(posView);
//キャプチャーオブジェクトのセット
((CSample1View*)pView)->SetRdCapture(m_pCaptures->GetCapture(n));
}
}
}
ちなみにここでm_pCapturesというのはそれまでの流れで
カメラ関連の設定データを格納しているようです。(カメラSDKのもの)
SetRdCaptureはキャプチャーオブジェクトのセットをする関数です(カメラSDKのもの)
GetCaptureで接続されているカメラの個数を数えています(これもカメラSDK)
CSample1View以下にプレビューウインドウに対する操作(マウスクリックなど)への
反応を示すプログラムが書かれています。
こちらはなんとか再利用したいと考えています(労力的に)
CSample1Viewでは
void CSample1View::OnDraw(CDC* pDC)
{
// TODO: この場所にネイティブ データ用の描画コードを追加します。
if(m_pCapture)
m_pCapture->OnDraw(FALSE);
}
とされておりここで描画されているようです。
重ね重ね情報を小出しにしてしまい申し訳ありません。
まえがき
MFCなしは最近全くしていないのでよく覚えてないので間違ったこと書くかも。
動作確認せずに回答することが多い。
MFCなしでMFC使うということなので何が起こるかわからん。
俺は今VC++2005を使用してない。
> m_pCaptures->GetCaptureCount()
カメラ複数台に対応しているということかな?
あなたのアプリもカメラ複数台に対応するのですか?
グローバル変数使うことにする。
俺の説明が楽だから。
const int max_capture_count = 10; // これを超えるキャプチャは無視
int capture_count = 0;
HWND g_hView[max_capture_count] = {0};
CSample1View * g_pView[max_capture_count] = {0};
CDocument * g_pDocument[max_capture_count] = {0};
あなたのプログラムのどこかビューを作成するところで
Win32APIで普通にウィンドウを作るか。
for(UINT n = 0; n < m_pCaptures->GetCaptureCount(); n++)
{
//ドキュメント
このあたり私にはわかりません
//ビューを取得
このあたり私にはわかりません
//キャプチャーオブジェクトのセット
((CSample1View*)pView)->SetRdCapture(m_pCaptures->GetCapture(n));
}
MFCじゃないから自動ではウィンドウを作ってくれないのでどうするか?
普通にWin32Apiでウィンドウ作るか。
ウィンドウプロシージャってどんなんだか忘れた。
以下は俺の空想
for(UINT n = 0; n < m_pCaptures->GetCaptureCount(); n++)
{
g_pView[n] = new CSample1View;
CreateWindow(このあたりはあなたが作る);
}
つづく
つづき
俺の空想なので正しいか知らない。
>#include <afxwin.h>
>を宣言しているのでほかのMFCコードは動いている(?)と思います。
あなたのプログラムのメッセージループが動いていて
MFCのメッセージループは機能していないはず。
このサンプルCSample1Viewがドキュメントを必要としているのか俺は知らないから
CDocumentについては無視しとく。
RegisterClassとかウィンドウプロシージャやウィンドウ作成はあなたが行うこと。
ウィンドウプロシージャを仮名WndProcとする。
LRESULT WndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
if(Msg == WM_CREATE)
{
g_hView[capture_count] = hWnd;
}
}
これはビューが複数ある場合、どのhWndのとき、どのg_pView[hoge]がわかるように。
と思ったが、STLのマップを使った方が楽だな。
ビューが複数ないなら必要ない。
以下面倒なのでビューはg_pViewひとつしかない前提で話を進める。
--省略--
case WM_CREATE:
{
g_pView->m_hWnd = hWnd;
return g_pView->OnCreate((LPCREATESTRUCT)lParam);
}
break;
case WM_PAINT:
{
HDC hdc=BeginPaint(hWnd,&ps);
CDC cdc;
cdc.Attach(hdc);
g_pView->OnPaint(&cdc);
cdc.Detach();
EndPaint(hWnd,&ps);
}
break;
--省略--
でも、やっぱ不安だなあ。
CSample1View内にMFCを必要とする処理があるかどうか俺には分からんから。
MDIじゃないってことはSDIってことであり複数カメラに対応していないってことなら
> for(UINT n = 0; n < m_pCaptures->GetCaptureCount(); n++)
これはまずいね。
> ちなみにここでm_pCapturesというのはそれまでの流れで
> カメラ関連の設定データを格納しているようです。(カメラSDKのもの)
> SetRdCaptureはキャプチャーオブジェクトのセットをする関数です(カメラSDKのもの)
> GetCaptureで接続されているカメラの個数を数えています(これもカメラSDK)
この辺のコードを見た限り、CSample1Viewで必要としているのはm_pCapturesのデータ
であり、CDocTemplateやCDocumentは必要ないように思われる。ただサンプルではその
データをドキュメント側に置くようになっているのでそのデータを取得している。
MarkedOneさんの方ではこのm_pCapturesのデータをどのように管理するかをちゃんと
設計する必要があるだろう。
> CSample1View以下にプレビューウインドウに対する操作(マウスクリックなど)への
> 反応を示すプログラムが書かれています。
> こちらはなんとか再利用したいと考えています(労力的に)
CSample1ViewはCViewかCViewの派生クラスから派生されたのもだろうから、やはり
ドキュメント-ビューアーキテクチャが分かっていないと再利用はむずかしいだろう。
いずれにせよサンプルプログラムの内容を理解せずに再利用なんか無理。
まずは各々の関数が何をやっているのか理解すること。再利用はそれから。
> もしよろしければWin32でビューを取得する方法を解説しているHPなどがあれば
> おしえていただけませんか?
根底としてMFCを使わないのであれば、
ここでいうビューなんてものはMFCの中にしかないので、
(突き詰めていけばWin32でいうHWNDのラッパにすぎない)
非MFCのWin32でそんなものは取れないし、仮に無理やりとっても、
MFCはMFCの枠の中で動いてますから、部品だけそのまま持ってきても、
まともに動かないので意味がないわけですが。
MFC->Win32の移植というのは、MFCのコードから使えるものを抜き出しつつ、
MFCが隠してくれていたコードをさらけ出す作業になるわけです。
「ビューを取る」というのは多分、方向性としては危険。
「電子機器をばらして部品から別の機器を組み立てる」ような行為ですので、
各部品の規格も知らない人間にはできないと思ったほうがよいです。
> いずれにせよサンプルプログラムの内容を理解せずに再利用なんか無理。
> まずは各々の関数が何をやっているのか理解すること。再利用はそれから。
で、あと大前提としてそのSDKがMFCに依存してないかの確認は大事。
もしどっかで依存してたら、初心者には移植できない可能性も…。
・まず、SDKの資料で、MFC非依存でも動くことを確認する。
そして、もしプログラム自体の学習が目的でないなら、
・SDKの提供元に、非MFCでのサンプルがもらえないか交渉する
なども検討してはどうでしょうか?
ベンダと、お願いの仕方によっては、非MFC版のサンプルをくれるとか、
少なくともなんらかヒントをくれるとかはありえると思うのですが。
# ベンダ次第ですが、たいてい最初の一回の質問くらいは、
# 無償でもなんらかヒントくらいくれたりしますので、
# 巧く聞いてみてください。
# もしくは、場合によっては、有償のテクサポに金を積むとか…。
# MFC依存のSDKなのだとしたら「無理」といわれるか、
# 「お客様での移植のヒントだけ提示されて終わるか、
# 受託開発などを提案されるか、等がありえると思いますが、
# SDK自体が非依存なのだとしたら、(分かってる人には)
# そんなに難しい移植とも思えず…。