2016-03-18 12 views
1

私はVisを書いています。スタジオダイアログアプリケーションを使用して、ダイアログから表示する必要がある小型LCDグラフィックスディスプレイを含む機器を遠隔操作することができます。 V.Studioダイアログエディタは、缶詰ソリューションを提供していないようです。私がやったことは、援助よりもむしろWindowsプログラマーであるからです:ダイアログ内のGDIグラフィック

  • ダイアログに編集コントロールが追加されました。 LCD用画像の更新が到着すると
  • は、エディットコントロール上のピクセルを設定する
  • コールGDI関数をCClientDCを作成

値これはbletcherousようだが、画像が到着したときに作業を行います。明らかに、ダイアログが再描画されたときにイメージを再描画しません。このコードは、再描画のために画像データを保存しますが、ダイアログが再描画されたときに画像の再描画機能を呼び出す場所を見つけようとしません。

  • ダイアログの最後のステートメントとして再描画呼び出しを追加すると、OnPaint()関数がイメージを作成しますが、OnPaint()が返されたときにすぐに消去されます。
  • OnPaint()でカスタムWM_DRAWLCD_MESSAGEを転記したときと同じ結果 - 画像は作成されますが、消去されます。
  • フレームワークがEndPaint()を呼び出すように見えないため、そこにイメージを再描画できません。

2つの質問
1.この目的を達成するための一般的な受け入れ方法はありますか?
2.そうでない場合、ダイアログが再描画されたときに、コードはどこで再描画機能を呼び出すことができますか?

@zeromus:LCD Image 私の "トースター"は、ダイアログアプリケーションに接続されていて、とてもうまく通信しています。問題のLCDイメージは、オペレータが使用するために機械に取り付けられたLCDパネルの内容です。私が遠隔診断をしているときは、画像の下にあるダイアログボタンのコントロールをクリックして、コントロール/ステータス操作を実行し、応答を見ることで、すべてのマシン機能を他の手段で複製するのではなく、簡単になります。対話が一番上にある限り、ものは期待どおりに機能します。ダイアログが一番上に残っていない場合、上に戻すとイメージは復元されません。ビットマップを作成するデータとコードは、CEditコントロールの一部ではありません。したがって、質問は(1)ダイアログアプリケーションでビットマップされたイメージを表示および復元する(静的イメージを表示するのではなく)、ウィザードで承認された方法はありますか?(2)そうでない場合は、ダイアログコードダイアログの再描画中に私のビットマップ描画関数の呼び出しでスプライスするには?ありがとう!

+1

解決策は単純です:あなたのダイアログクラスにメンバーとして 'CBitmap'オブジェクトを追加します。データが到着するたびに、ビットマップデータを更新し、更新をトリガーするために 'InvalidateRect'を呼び出します。あなたの 'OnPaint'ハンドラでは、単純にビットマップをレンダリングします。ダイアログリソースにプレースホルダが必要な場合は、不可視の静的コントロールを使用します。あなたはMFCウィザードの使用にすべて没頭しているので、2つのステップを取り戻すことを検討する必要があります: '1' Windows APIを学び、' 2' MFCプリプロセッサマクロを深く知りましょう。いずれかの手順をスキップすると、MFCはWindowsプログラミングを大幅に難しくします。 – IInspectable

答えて

0

私はMFCを使用していませんでした.netがリリースされて以来、私はあなたが時間とコピーに戻って行くことをお勧めします。Windowsでこれを行う通常の方法は、コンテンツを含むCBitmap LCDの次に、OnPaintに描画するだけです。ダイアログに直接表示するのが最も簡単です。 Windowsでは、OnPaintですべての図面を作成することになっていますが、準備が整うまでに必要な作業をすべて行うことができます。編集コントロールの関与は、おそらく何かを助けることはできません。

MFCであってもウインドウに物を描くのに不合理なステップが必要なので、私はテストコードを貼り付けます。これはMFCのベテランを怒らせるかもしれませんが、それは仕事をやり遂げたり、同じオブジェクトライフタイムマネジメントをしたりします。すべてが非常に難しいので微妙なバグが含まれているかもしれませんが、ビットマップをペイントする原則が示されています。結局のところダイアログの背景に描画している場合は、 "erasebackground"イベントで行うこともできますが、わかりません。

//create bitmap with updated contents 
bmp = new CBitmap(); 
bmp->CreateCompatibleBitmap(this->GetDC(), 100,100); 
__int32* buf = (__int32*)malloc(100*100*4); 
int r=rand(),g=rand(),b=rand(),a=255; 
for(int y=0;y<100;y++) for(int x=0;x<100;x++) buf[y*100+x] = b|(g<<8)|(r<<16)|(a<<24); 
bmp->SetBitmapBits(100*100*4,buf); 
free(buf); 

//when painting 
CPaintDC dc(this); 
CDC bitmapDC; 
bitmapDC.CreateCompatibleDC(&dc); 
bitmapDC.SelectObject(bmp); 
dc.BitBlt(0,0,100,100,&bitmapDC,0,0,SRCCOPY); 
+0

'malloc'と' new'を混在させるのは難しいです。互換性のあるビットマップを作成し、ビット深度を無視するのはバグです。スキャンラインアライメントを考慮していないこともバグです。 'WM_ERASEBKGND'メッセージハンドラで' CPaintDC'を使うことを提案するのは間違っています。多くの間違った情報の中に隠されている有用な情報はほとんどありません。 – IInspectable

+0

@IInspectableは、現代のディスプレイでは32ビットであることが保証されていない 'CreateCompatibleBitmap'のビットマップですか?ここでの正しい使用法は 'bmp-> CreateBitmap(100,100,1,32、buf)'でなければなりません。しかし、モニターが32ビットをサポートしていなければ、それは同じ問題です。 –

+1

@BarmakShemirani: 'CreateCompatibleBitmap'は、提供されたデバイスコンテキストと互換性のあるビットマップを返します。これは*デバイス独立*ビットマップと同じではありません。正しい使用法は、互換性のあるビットマップを使用し、要求されたビット深度を使用してコードを実装することです。 – IInspectable

0
Here's what's working for me: 

Add two member variables to the dialog class: 

    CImage m_lcdImage; 
    CStatic m_lcdStatic; 

In the init dialog callback: 

    m_lcdStatic.Create("Static", 
    WS_CHILD | WS_BORDER | WS_VISIBLE | SS_BITMAP | SS_CENTERIMAGE, 
    CRect(<rectangle coordinates>), this); 

    m_lcdImage.Create(<bitmap extent + color depth>); 
    m_lcdStatic.SetBitmap(HBITMAP(m_lcdImage)); 
    drawLCD(); 

Add member function drawLCD() called in init or when bitmap changes: 

{ 
    // 
    // app-specific m_lcdImage.SetPixel() calls 
    // to update the bitmap 
    // 

    m_lcdStatic.InvalidateRect(NULL); 
} 
関連する問題