Re: display array in a frame wnd



First, you have to create an app that is suitable for displaying an image. There are
several options:

A CDialog-based app, with a CStatic control in which the image is displayed

An SDI app, where the image is displayed in the view.

An MDI app, where the image is displayed in the view.

The details differ slightly in how you do this, but ultimately, there is an OnPaint
handler for the subclassed CStatic in the dialog or an OnDraw handler for the
CView-derived class in your SDI or MDI app. All your drawing logic belongs in the
OnPaint/OnDraw handler.

There would never be a need to create a frame window; it is not at all clear why such code
would be written. Such code is automatically generated by the AppWizard.

There is no reason to do a DestroyWindow, or create a new window, to do the display; the
window is already there. An approach which does not make this assumption is probably the
wrong approach.

In an SDI app or MDI app there is already a status bar, menus, and toolbars. There is an
MSDN article on how to add toolbars and status bars to a dialog-based app, but for this
project, it strikes me that an SDI or MDI app would be the correct choice. Since all the
"future enhancements" you think you want are already present, and cost you zero effort,
there is no reason to take some macho I-have-to-write-everything-myself approach. Such an
attitude is counterproductive, and not even sensible. I think the fundamental failure you
have made here is in not using the correct tools to create an app, instead thinking you
have a chance of doing this from scratch. Such an approach is usually doomed; very few
MFC programmers would adopt such an approach, and the ones who do are usually very
sophisticated MFC programmers. This is *never* a viable approach for a beginner, no
matter what bizarre book you are using that suggests it could possibly make sense. It is
just an inappropriate approach, and should be instantly scrapped.

So start over. Create either an MDI or SDI app, copy code across, make sure ALL drawing
is done in the OnDraw handler of the CView-derived class. There is no need to create new
windows, so the approach that requires creating and destroying windows should be
abandoned.
joe

On Wed, 5 Sep 2007 17:12:20 +0200, "J-F Portala" <jfportala@xxxxxxx> wrote:

I thank you for your answer.

When I make image processing, I have to display results.

p1 , p2 , p3 are pointers on IplImage*

I would like to create a function where I can give a title and the image
pointer to get a window with the image in it.
****
This suggests you want an MDI app, and you would use OpenDocument to get a document and
view.
****

// here is what I want to do
display("image source",p1) ;
process(p1,p2) ;
display("first result",p2) ;
process(p1,p3) ;
display("second result",p3) ;

In the lib opencv I use, I just have to do
cvNamedWindow("source image",0) ;// create window
cvShowImage("source image",p1) ; // display window
****
No. OpenDocument to create a document, then set the pointer p1 in the document, and call
UpdateAllViews. The OnDraw handler will draw the image. You have made the problem vastly
more complicated than it needs to be.
****

cvDestroyWindow("source image") ; // to detroy it

The window can be used in all the program thanks to the name "source image".
****
I don't even understand this sentence. What does the caption have to do with anything?
****

It is very easy but the problem is that I want in the future to add a status
bar and also a menu to the window, and I think it is easier to
create window through MFC than modifying existing code of the lib.
This window can be created anywhere in the program.
****
OpenDocument does this.
joe
****


"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> a écrit dans le message de
news: vn8td3heqr95ruls37bdeohgs0pkatkmol@xxxxxxxxxx
First, did you create this program using the Wizards? If not, it is hard
to tell what is
going on. Is it MDI, SDI, or what?

My application is SDI.(without view).
Generally, I see no reason to be creating a frame window at all; this is
normally done for
you by the wizards, and you should be working in a view window.

Many bugs below,,,
On Wed, 5 Sep 2007 10:52:57 +0200, "J-F Portala" <jfportala@xxxxxxx>
wrote:

Hi,
I am using opencv wich is an image processing lib.
I would like to display in a CFrameWnd, images represented by an
array.(IplImage format)
pImg is the IplImage*
****
It appears that you are using an ImageInfo * structure, so why did you not
say this? An
LPIImage format is nothing more than a pointer to an IImage, which does
not have any of
the fields you are using.
****

I have some difficulties to display the array.

First , I create CFramWnd,
CFrameWnd* pw ;
pw = new CFrameWnd() ;
pw->Create("NULL,"test") ;
pw->ShowWindow(SW_SHOW) ;
****
And why are you creating a CFrameWnd? You should not be doing this at
all, but if you
need to create one for some obscure reason, you definitely need to
subclass it and create
an instance of your subclass. But I think this is a mistake.
I would like to display a window anywhere (it could be just for debugging a
special image processing algorithm)
that is the reason why I have created a CFrameWnd when I need it.

Note that if you are NOT using the wizards, you need to restart the
project, creating the
project using the AppWizard. It makes no sense to create an application
like this unless
you are ABSOLUTELY CERTAIN you know EXACTLY what you are doing, and in
this case it is
clear that you do not understand basic Windows programming. Until you do,
do not attempt
to create programs other than using the wizards. (After using MFC for
over 12 years, I
would not consider doing building a program other than with the wizards,
since it would
only be a waste of my time or be cheating my clients by taking their money
under false
pretenses).
You are right. I am working with visual C++ for several years but
I was using before matrox library, where I could make a link between an
image buffer and a CFrameWnd created in the beginning of the program.
I have added menu and status bar to the CDisplayWnd (subclass of CFrameWnd)
That is the reason why I have chosen CFrameWnd
but I am not familiar with bitmap, palette and device context.

****
I get the window.

then
//Initialize the BMP display buffer
BITMAPINFO* bmi;
BITMAPINFOHEADER* bmih;
RGBQUAD* palette;
unsigned int buffer[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256];

****
Why are you declaring an unsigned int array whose size is based on BYTE
counts? LPBYTE
buffer would make sense, or dividing the size value by sizeof(int), but
this creates an
array four times larger than what you need.
****
bmi = (BITMAPINFO*)buffer;
bmih = &(bmi->bmiHeader);
memset(bmih, 0, sizeof(*bmih));
****
Using ::ZeroMemory would be a better choice
****
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = pImg->width;
bmih->biHeight = pImg->height;
bmih->biPlanes = 1;
bmih->biCompression = BI_RGB;
bmih->biBitCount = 8 * pImg->nChannels;
palette = bmi->bmiColors;
*****
What is pColor? where does it come from? where is it initialized?
pColor is pImg, I have changed the name to make it more comprehensive (I use
generally 8bits image in grey levels)
but I have forgotten to replace pColor.
*****
if (pColor->nChannels == 1)
{
for( int i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen =
palette[i].rgbRed
= (BYTE)i;
palette[i].rgbReserved = 0;
}
}

CPaintDC dc(pw);
****
This makes no sense. A CPaintDC is declared ONLY in the OnPaint handler,
which is where
all this code belongs, yet you seem to imply this code is done somewhere
else, such as in
the place where you are creating the frame window. But why are you
drawing in a frame
window and not a view? Why is this not in an OnPaint handler?
I explained it above ( perhaps cView is more adapted) but can I attach a
status bar and a menu.

The code I have tested was obtained during my researches on internet.
****
CDC* pDC = &dc;
*****
Get rid of this line. It makes ABSOLUTELY NO SENSE WHATSOEVER! There is
absolutely no
reason to introduce a gratuitous pointer variable that contributes nothing
to the program,
and merely decreases the readability of the code. There is not a single
sane reason this
variable should exist.
*****

int res = StretchDIBits(
pDC->GetSafeHdc(), //dc
****
Why not use
::StretchDIBits((HDC)dc, ...)
why introduce a meaningless pointer variable that serves no useful
purpose, only to call a
method that makes no sense? Or you could have written
::StretchDIBits(dc.m_hDC, ...)
but GetSafeHdc doesn't make sense here. And if you DID want to write it,
you would have
written
dc.GetSafeHdc()
instead of using a meaningless pointer variable that serves no purpose
whatsoever.
****
0, //x dest
0, //y dest
int(pImg->width), //x dest dims
int(pImg->height), //y dest dims
0, // src x
0, // src y
pImg->width, // src dims
pImg->height, // src dims
pImg->imageData, // array of DIB bits
(BITMAPINFO*)bmi, // bitmap information
DIB_RGB_COLORS, // RGB or palette indexes
SRCCOPY); // raster operation code

// Update Window, force View to redraw.
pw->RedrawWindow(
****
So your comment says UpdateWindow, but your call is RedrawWindow....

Since this would be in the OnPaint handler of the CFrameWnd-derived class,
or better
still, in the OnPaint handler of the view class, this call would have no
meaning. Since
you appear to be doing this somewhere else, it cannot possibly work,
because the CPaintDC
is meaningless.
****
NULL, // handle to window
NULL, // update rectangle
RDW_INVALIDATE // handle to update region
);

I have no display of my image.
Where is the problem ?
****
You used a CPaintDC outside an OnPaint handler, you did painting outside
an OnPaint
handler.

Start over. Create a document/view application, put the initialization in
the
OnInitialUpdate handler, put the drawing code in the OnPaint handler of
the view.
joe
****
Thank you for your help

Jeff

Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: display array in a frame wnd
    ... I have to display results. ... The window can be used in all the program thanks to the name "source image". ... CFrameWnd* pw; ... Why is this not in an OnPaint handler? ...
    (microsoft.public.vc.mfc)
  • Re: display array in a frame wnd
    ... An SDI app, where the image is displayed in the view. ... There would never be a need to create a frame window; ... I better prefered to reuse display provided with the librairy opencv, ...
    (microsoft.public.vc.mfc)
  • Re: Layered Windows in VMWare and Terminal Services
    ... I know that the display change is causing a repaint (a couple or three, ... to function in the app for the lifetime of the app. ... I used Spy++ to get all the messages sent to the window during a mode change ... the VGA display driver and you change, ...
    (microsoft.public.win32.programmer.gdi)
  • Re: display array in a frame wnd
    ... An SDI app, where the image is displayed in the view. ... There would never be a need to create a frame window; ... I better prefered to reuse display provided with the librairy opencv, ...
    (microsoft.public.vc.mfc)
  • Re: Popup window blocking in XP Service Pack 2
    ... > I have a web app that has a legitimate use for pop up windows. ... > I also use it later to display a pdf application form. ... If I display it in the main window then I would have to ...
    (microsoft.public.dotnet.framework.aspnet)