Solved

How do I display multiple child windows in a main parent window

Posted on 2006-07-24
72
526 Views
Last Modified: 2013-11-20
Hi I hope someone can help me I have an application that captures multiple video images. At present I can capture each video camera separatly in a window but I want to display all the video camera images together in one parent window.
At the moment I capture each video camera by runing a thread each time the thread process the raw video image it creates a new window and display the video image in that window. So for example I can capture 16 cameras at once so each time the thread executes one pass the thread calls a function and process the video data opens a window untill all 16 windows are created and then just display cam1 ,cam2 etc.. in there open windows so now I need to place these 16 child windows in one parent window and also not display them in the task bar can anyone help
Thanks
Nigel
0
Comment
Question by:nchannon
  • 36
  • 28
  • 8
72 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
There is an MFC sample (MTMDI) that has multiple child windows in a parent, each child window having its own thread.
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
i'm not sure how you are executing your threads.. but you need to redesign your application to include a window class that displays a video window; then you can create multiple instances of that class.

for example.. your application has a main window CVideoMainDlg.. with a child window that shows a video image, CVideoFrameDlg. you can then declare 16 objects of the CVideoFrameDlg class.

in practice, the code might look something like this;

// CVideoMainDlg implementation

#include "VideoFrameDlg.h" // include the class header for the video window class
#define MAX_CAMERAS 16 // the number of windows we might want to display

CVideoFrameDlg videoWindows[MAX_CAMERAS]; // multiple instances of the window class we can show or hide

..

BOOL CVideoMainDlg::OnInitDialog() {
int i;

for (i = 0; i < MAX_VIDEOS; i++)
videoWindows[i].Create(IDD_VIDEOFRAMEDLG, this); // initialise each child window with the dialog template

}

..

// here we've gotten notification to create a new window for a camera.
void CVideoMainDlg::OnCreateNewVideoWindow(int videoWindowIndex) {
videoWindows[videoWindowIndex].ShowWindow(SW_SHOW);
}

///////////////////////////////

sorry it's a bit vague but i guess i can help you further if i can see more of your application's internal workings. your CVideoFrameDlg will need to handle the processing of images, etc indepentantly of the CVideoMainDlg class. this way, you can process each of the 16 instances independantly.
0
 

Author Comment

by:nchannon
Comment Utility
Hi snyp I looked at MFC sample MTMDI but it is not what I am looking for, You seem to understand what I m trying to do great, I understand your basic sample but yes I will need a bit more help from you if thats ok. From your sample you are creating one dialog IDD_VIDEOFRAMEDLG and just creating multiple instances of it didnt try it that way what I have been trying to do is create from a main MFC Dialog a Child window lets say 800x600 by using the function create() so far no problem I have created a pointer from my mainDlg and called the POPUP window with the paint functions and other functions etc, like MainDisplay *m_Display = new MainDisplay(); so m_Display->Create(NULL,"Main Video View",POPUP,rc,NULL,0); this of course creates my main preview window but my problem begins when I now need to place for example 16 child windows inside the main popup window and be able to reference them. So for example I can load 16 separate windows each with its own camera view from a 16 Channel capture card what I have done is loaded the windows with the video image and then I show them at the run state of the capture driver and all works but only been able to do this is a separate popup window and not inside a main parent popup. My aim is I need to load all the video instance let say 16 windows into there own dialog window and hide them at setup the 16 dialogs need to be positioned into the main popup window evenly and into any grid box I want I mean by grid box is the main video window that holds the 16 dialog windows has a grid 4x4 thats 4 windows accross and 4 down, I have the grid pattern working fine and can display any number of grids so a 32 grid window is 6 x 6 squares on the screen. So if I want to put camera window 6 inside grid window 2 for example I need to tell dialog 6 that it must display in grid box 2 in the main popup window. I hope I have not confused you so far but this is what I must acheave. Can I send you my code via email you will get a better idea on what I am doing
Nigel
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
unfortunately we can't take it to e-mail because of the experts-exchange terms & conditions, even if it would mean helping you much quicker. i'm sorry

first things first, a couple of questions;
- are you using Visual C++ for your project?
- is your project dialog or document based?

let's start though with your child windows.

to make things much easier, i'd recommend you create a simple dialog window to use as your camera child window. if your main window is 800 x 600, and you want to create a grid of 4x4 windows, use your resource editor to make sure the child window is about the right size.

also, make sure the child window has the style WS_CHILD set; this will prevent another button on the taskbar and also give us greater flexibility.

if you create an array of 16 instances of the dialog as in my last example, and then initialise them with the dialog template, hiding/showing them and positioning them is easy with ShowWindow() and MoveWindow(). making a camera child window appear in whichever grid place you want is just a case of setting it's position (either with MoveWindow() or SetWindowRect()) and then showing it with ShowWindow().

i'd create a simple array that holds the top-left position of each place in the grid, and then you can get the relevant window coordinates to use with MoveWindow depending on where you want to place it
0
 

Author Comment

by:nchannon
Comment Utility
Hi thanks for the prompt reply thanks for helping me out here shame about the email policy
Ok first of all I am using Visual Studio C++ 2003 and I am using dialog based.
So my main app opens a dialog full screen and holds all the controls like buttons etc.. and is called CaptureDlg.cpp & .h
I then have created a class file called CWindowControl both related files WindowControl.cpp & .h
So
#include "WindowControl.h"
BOOL CaptureDlg::OnInitDialog()
{
RECT rc={0,0,0,0};
CWindowControl* m_WindowControl = new CWindowControl();

int height;
int width;
width = rc.right=800;
height = rc.bottom=600;
m_WindowControl->Create(NULL,"Main Window",WS_VISIBLE | WS_OVERLAPPEDWINDOW,rc,NULL,0,0);//Main window that holds the child wndows
m_WindowControl->MoveWindow(22,25,width,height,1);//positions main window that holds the child windows
m_WindowControl->ShowWindow(SW_SHOW);
m_WindowControl->SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE);

return TRUE;
}
ok now WindowControl.h
#define DISPALY_MAX_RECT                  64
#define DISPALY_MAX_CHANNEL            64


typedef struct _DISPALY_SPLIT_CONF{
      ULONG      uNumRects;
      SIZE      szBoundSize;
      RECT      rcRect[DISPALY_MAX_RECT];
      
} DISPALY_SPLIT_CONF;



typedef struct _DISPALY_SPLIT_INFO{
      DISPALY_SPLIT_CONF            scSplitConf;
      RECT                        rcOverlaySrcRect;
      ULONG      aChannel[DISPALY_MAX_CHANNEL];
} DISPALY_SPLIT_INFO;

    CString m_szClassName;
    BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext);

                CPen         m_PenBorder;
      BOOL      m_IsRcCreated;
      CFont      m_FontChannelName;
      afx_msg void OnPaint();
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
       

ok now WindowControl.cpp

DISPALY_SPLIT_CONF const view_16={
      16,
      {4,4},
      {
            {0,0,1,1},
            {1,0,2,1},
            {2,0,3,1},
            {3,0,4,1},

            {0,1,1,2},
            {1,1,2,2},
            {2,1,3,2},
            {3,1,4,2},

            {0,2,1,3},
            {1,2,2,3},
            {2,2,3,3},
            {3,2,4,3},

            {0,3,1,4},
            {1,3,2,4},
            {2,3,3,4},
            {3,3,4,4},
      }
};

DISPALY_SPLIT_CONF const view_36={
      36,
      {6,6},
      {
            {0,0,1,1},
            {1,0,2,1},
            {2,0,3,1},
            {3,0,4,1},
            {4,0,5,1},
            {5,0,6,1},

            {0,1,1,2},
            {1,1,2,2},
            {2,1,3,2},
            {3,1,4,2},
            {4,1,5,2},
            {5,1,6,2},

            {0,2,1,3},
            {1,2,2,3},
            {2,2,3,3},
            {3,2,4,3},
            {4,2,5,3},
            {5,2,6,3},

            {0,3,1,4},
            {1,3,2,4},
            {2,3,3,4},
            {3,3,4,4},
            {4,3,5,4},
            {5,3,6,4},

            {0,4,1,5},
            {1,4,2,5},
            {2,4,3,5},
            {3,4,4,5},
            {4,4,5,5},
            {5,4,6,5},

            {0,5,1,6},
            {1,5,2,6},
            {2,5,3,6},
            {3,5,4,6},
            {4,5,5,6},
            {5,5,6,6},
      }
};

DISPALY_SPLIT_CONF const* views[2] = {
      &view_16,
      &view_36,
};

DISPALY_SPLIT_INFO g_SplitInfo;
BOOL CWindowControl::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
      m_szClassName=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,LoadCursor(NULL,IDC_ARROW));
      return CreateEx(WS_EX_TOOLWINDOW   ,m_szClassName,lpszWindowName,dwStyle,rect,pParentWnd,NULL,NULL);
      
}

void CWindowControl::OnPaint()
{
      CPaintDC dc(this); // device context for painting
      
      // TODO: Add your message handler code here
      RECT rect;
      GetClientRect(&rect);
      CBrush brush(RGB(0, 0, 0));
      dc.FillSolidRect(&rect, RGB(0,0,0));

      dc.SetBkColor(RGB(0,0,0));
    g_SplitInfo.scSplitConf = *(views[1]);// change to 0 for 16 4x4 grid
      if (m_IsRcCreated) {

            dc.SelectObject(m_PenBorder);
            dc.SelectObject(m_FontChannelName);
            dc.SelectObject(brush);

            CBrush* pOldBrush = (CBrush*)dc.SelectObject(brush);
            CFont* pOldFont = (CFont*)dc.SelectObject(m_FontChannelName);
            CPen* pPen = (CPen*)dc.SelectObject(m_PenBorder);

            
            HBRUSH hOldBrush = (HBRUSH )dc.SelectObject(brush);
            HFONT hOldFont = (HFONT)dc.SelectObject(m_FontChannelName);
            HPEN hPen = (HPEN)dc.SelectObject(m_PenBorder);

            double gridX = (double)(rect.right-rect.left)/g_SplitInfo.scSplitConf.szBoundSize.cx;
            double gridY = (double)(rect.bottom-rect.top)/g_SplitInfo.scSplitConf.szBoundSize.cy;
     
            for(DWORD j=0;j<g_SplitInfo.scSplitConf.uNumRects;j++){
                  RECT rc = g_SplitInfo.scSplitConf.rcRect[j];
                  dc.Rectangle((int)(rc.left*gridX),(int)(rc.top*gridY),(int)(rc.right*gridX),(int)(rc.bottom*gridY));
                        }

            dc.SelectObject(hPen);
            dc.SelectObject(hOldFont);
            dc.SelectObject(hOldBrush);
            
      }

}

int CWindowControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
      if (CWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
      
      // TODO: Add your specialized creation code here
      
      m_PenBorder.CreatePen(PS_SOLID,0,RGB(213,215,145));
      m_IsRcCreated = TRUE;
      m_FontChannelName.CreateFont(
                                                      17,                        // nHeight
                                                      0,                         // nWidth
                                                      0,                         // nEscapement
                                                      0,                         // nOrientation
                                                      FW_BOLD,                              // nWeight
                                                      FALSE,                     // bItalic
                                                      FALSE,                     // bUnderline
                                                      0,                         // cStrikeOut
                                                      ANSI_CHARSET,              // nCharSet
                                                      OUT_DEFAULT_PRECIS,        // nOutPrecision
                                                      CLIP_DEFAULT_PRECIS,       // nClipPrecision
                                                      DEFAULT_QUALITY,           // nQuality
                                                      DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
                                                      "FixedSys");                 // lpszFacename
      //ChildWindows();

      return 0;
}

Ok this should be enough for you to recreate what I have on my side this will after your initial dialog opens create the main video window that holds the 16 child windows a 32 6x6 grid be displayed in the main window and to place 16 child windows into the grid and also have them resize them selves if you select 16 4x4 grid by changing g_SplitInfo.scSplitConf = *(views[1]); to g_SplitInfo.scSplitConf = *(views[0]);  as there will be several different layout views to select from. I would like if we can create the child windows from WindowControl.cpp
Thanks
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
first, may i ask why you are creating another window when you reach CaptureDlg::OnInitDialog()?
CaptureDlg isn't initialised or shown at all, as you aren't calling CDialog::OnInitDialog() before returning.. it seems you're doing all the work that that could be done for you.

to create child windows from CWindowControl::OnCreate(), first make a dialog template in the resource editor that each video window will use, and make sure it is a WS_CHILD (dialog properties). then create a CDialog derived class called CVideoWindow (or whatever you like).

then add the header file and a member array to your CWindowControl class header;

///////////////////////

#include "VideoWindow.h"

..

public:
..
CVideoWindow m_videoWindows[MAX_VIDEO_WINDOWS]; // sorry, not sure how you're defining this
..

///////////////////////

at runtime, create them from CWindowControl::OnCreate()

///////////////////////

int i;

for (i = 0; i < MAX_VIDEO_WINDOWS; i++) {
m_videoWindows[i].Create(IDD_VIDEO_WINDOW, this);
}

/////////////////////////

if you want to show all the video windows as soon as the application starts, carry on positioning and showing all the windows right after they've been created..

///////////////////////////

for (i = 0; i < MAX_VIDEO_WINDOWS; i++) {
m_videoWindows[i].MoveWindow(DISPALY_SPLIT_CONF.rcRect[i]);
m_videoWindows[i].ShowWindow(SW_SHOW);
}

//////////////////////////////

because each video window is a seperate CDialog object, you can handle input messages and processing of each individual window by overriding messages and creating functions in the CVideoWindow class.

let me know if this fits into your app
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
I think you should still study the MTMDI sample.
MFC isn't thread safe and there can be problems with having a window in one thread being directly updated by another thread (sounds similar to your requirements).  The sample should help you with that.

ps.
Don't forget - an MDI child frame is a child of another window, if you only want it to appear at one location and one size then it should not be much work to make it do so (position and size when you create the window, then stop the default windows behaviour when the user tries to reposition/resize).
0
 

Author Comment

by:nchannon
Comment Utility
Great it works, Ok how do I control the size of the dialogs as they need a border but when I set them to use a thickborder my grid line ends up under the dialogs. I can set the left and top edge of each dialog by reducing them it by -3 but not the right and bottom of the box so half my grid appares but not the other.
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
you should be able to set any type of frame for a child dialog. i'd personally make one without a titlebar and a thin frame.. can you set these in vc's resource editor?
0
 

Author Comment

by:nchannon
Comment Utility
I can set the frame ok and it displays fine but but I then can no longer see the grid lines unless I set the dialog to thin
0
 

Author Comment

by:nchannon
Comment Utility
The dialogs are automatically sized to the grid sizes which is what is ment to happen but I now need to make dialogs approx 3 pixels less than the grid sizes. So if the grid is set to 36 6x6 the dialogs will fit just nicely inside the grids the same if I select 16 4x4 grid at the moment the dialogs are the same size as the grids
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ahh ok.. you need to adjust the values in your RECT arrays..

just shift the 'bottom' and 'right' members by a value of three. that might take a bit of work if you do it manually..
if you don't mind a quick-fix, before you call MoveWindow() on your OnCreate(), just add another line quick;

for (i = 0; i < MAX_VIDEO_WINDOWS; i++) {
DISPALY_SPLIT_CONF.rcRect[i].bottom -= 3;
DISPALY_SPLIT_CONF.rcRect[i].right -= 3;

m_videoWindows[i].MoveWindow(DISPALY_SPLIT_CONF.rcRect[i]);
m_videoWindows[i].ShowWindow(SW_SHOW);
}
0
 

Author Comment

by:nchannon
Comment Utility
Ok Im not having much joy now
DISPALY_SPLIT_CONF.rcRect[i].bottom -= 3; wont work I have to use

double gridX = (double)(rect.right-rect.left)/g_SplitInfo.scSplitConf.szBoundSize.cx;
double gridY = (double)(rect.bottom-rect.top)/g_SplitInfo.scSplitConf.szBoundSize.cy;
      for(DWORD j=0;j<g_SplitInfo.scSplitConf.uNumRects;j++){
      RECT rc = g_SplitInfo.scSplitConf.rcRect[j];
      //m_videoWindows[i].MoveWindow(DISPALY_SPLIT_CONF.rcRect[i]);
       videoWindows[j].MoveWindow((int)(rc.left*gridX+2),(int)(rc.top*gridY+2),(int)(rc.right*gridX-3),(int)(rc.bottom*gridY-3));
       videoWindows[j].ShowWindow(SW_SHOW);
}

then my dialogs disply correctly by using +2 and -3 the fist dialog fits between the first grid line but not the rest
any ideas
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ok.. not entirely sure of gridX and gridY.. but the idea here is;

each window, move along an X position of the grid
unti maximum X {
all windows down one Y grid pos
start again from first X grid pos
}

it's difficult to test the mathematics without stepping through it myself with a debugger.. but see if the loop structure implements well at least

/////////////////////

double gridX = (double)(rect.right-rect.left)/g_SplitInfo.scSplitConf.szBoundSize.cx;
double gridY = (double)(rect.bottom-rect.top)/g_SplitInfo.scSplitConf.szBoundSize.cy;

int thisWinX = (int)(rc.left*gridX+2);
int thisWinY = (int)(rc.top*gridY+2);
int thisWinWidth = (int)(rc.right*gridX-3); // constant
int thisWinLength = (int)(rc.bottom*gridY-3); // constant

RECT rc = g_SplitInfo.scSplitConf.rcRect[j];

int winI = 0;

for(DWORD j=0;j<g_SplitInfo.scSplitConf.uNumRects;j++){

if (winI++ >= MAX_VIDEO_SCREENS_X) { // reached 4 screens across?
winI = 0; // start X iterator

thisWinY += (int)(rc.top*gridY+2); // down one Y grid
thisWinX = (int)(rc.left*gridX+2); // start again from first X grid
}

videoWindows[j].MoveWindow(thisWinX, thisWinY, thisWinWidth, thisWinLength); // set coordinates for this window
thisWinX += (int)(rc.left*gridX+2); // move along one X grid

videoWindows[j].ShowWindow(SW_SHOW);
}
0
 

Author Comment

by:nchannon
Comment Utility
Ok this may help to solve the problem what is happening is dialog 1 is placed ok in grid 1 the first in the top left corner of the window. then dialog 2,3 and 4 only changes top and bottom of dialog 2,3 and 4 to fit within the grid. the left of dialog 2 also and moved to fit in the grid bit the right of dialof 2 is still attached to 3 and 3 is still atached to 4.
Dialog 4 top,left and right are ok but bottom is still connected to 8 and 8 is still connected to 12
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
// when declared;

int thisWinX = (leftmost pixel of dialog one)
int thisWinY = (topmost pixel of dialog one)
const int thisWinWidth = (the width of any of the dialogs)
const int thisWinLength = (the height of any of the dialogs)

// then during the loop, MAX_VIDEO_SCREENS_X is the number of video screen dialogs going across (presumably 4?)

if (winI++ >= MAX_VIDEO_SCREENS_X) {
winI = 0;

thisWinY += (one row down)
thisWinX = (leftmost pixel of dialog one)
}

etc.movewindow(etc, etc);
thisWinX += (one row across);

////////////

the actual lengths of the windows and positions, i don't have access to, without having your window and grid to see.
that's the concept though.

an idea to debug from scratch;

- only show dialog 1, and get it's length and position the way you want it
- show dialog 1 and dialog 2, and increment the X coordinate for dialog 2's X; so you know what to add for 3 and 4
- show dialog 1, dialog 2, and dialog 5, and increment the Y coordinate for dialog 5's Y; so you know what to add for 6, 7, and 8.
0
 

Author Comment

by:nchannon
Comment Utility
Ok something strang going on I have steped though the loop one by one the values for
int thisWinX = (int)(rc.left*gridX+2);
int thisWinY = (int)(rc.top*gridY+2);
int thisWinWidth = (int)(rc.right*gridX-3); // constant
int thisWinLength = (int)(rc.bottom*gridY-3); // constant
are all perfect for the entire loop I have 5 pixels space between left,top,right,bottom in every dialog so in thereroy my movewindow should move to each cord with each pass though of the loop but it is not doing this the dialogs are not being painted on the screen corectly with in the grids.
The cords for the windows are as follows
the first four dialogs acrros the screen
dialog 1 = left 2, top 2, right 206, bottom 155
dialog 2 = left 211, top 2, right 416,bottom 155
dialog 3 = left 421, top 2, right 625, bottom 155
dialog 4 = left 630, top 2, right 835, bottom 155
Next row of four
dialog 5 = left 2, top 160, right 206, bottom 313
and so on but they are not being painted with these cords on the screen

0
 

Author Comment

by:nchannon
Comment Utility
Ok I have just found what is happening to the dialogs
what I did is incremented the top by 12 so I could see what each dialog was doing like this
videoWindows[j].MoveWindow(thisWinX,thisWinY+winI,thisWinWidth,thisWinLength);
     // thisWinX += (int)(rc.left*gridX+2); // move along one X grid
      videoWindows[j].ShowWindow(SW_SHOW);
     winI=winI+12;
What is happening in dialog 1 is being painted corectly with its coords dialog 2 is being painted with double the length for right so if the right for dialog 1 = 206 the right for dialog 2 is being painted with coord value 412 and dialog three seems to be getting the value 618
strange as when I step though with the debuger the values are what they should be
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
the coordinates you give to MoveWindow() are one-per-pixel as far as i can remember.. maybe someone can correct me..

what type of measurement are you making to get 412?
0
 

Author Comment

by:nchannon
Comment Utility
ok sorry should be 410 this is the length of two dialog boxs together each dialog should be 205 in width but the second dialog box is being painted the length of two dialog boxs even though the coords are the length of one passed to movewindow I cant see where this is being doubled to make my dialog twice the length
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
it doesn't sound right that your windows are only 205 pixels in width.. are your video-camera images 320x240?
0
 

Author Comment

by:nchannon
Comment Utility
I havent even got as far to display the video into the dialogs yet  Im still trying to lay my dialogs corectly on the screen first.
My camera sizes will be PAL 366 x 288 for display but I will also need to resize them to fit the dialogs corectly as well but one step at a time
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ok well.. if you take a screenshot of dialog 1.. and load it into mspaint or whatever you can use for image editing.. how many pixels wide?

if the dialog is 205 pixels wide.. it looks like MoveWindow takes parameters in some other kind of unit that isn't in pixels and we'll need to rethink what we do with the parameters we pass to it. but i'm pretty sure the parameters are one-per-pixel

otherwise it'll be a case of taking measurements in a different way, of where we want the dialogs to go
0
 

Author Comment

by:nchannon
Comment Utility
the dialog is 205 x 155 pixels
0
 

Author Comment

by:nchannon
Comment Utility
ok I see what is happening with the other dialogs but this shouldnt happen with movewindow(), when the loop passes for the second time we get the coords for the second dialog left=2 right=416 bottom=155 and top=2 so our movewindow function should move the second dialog to these coords but its not what is happening is the dialog is being painted with the width value of 416 pixels not positioned to the coord 416 the same is happening with the third dialog
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ok.. MoveWindow() isn't doing what i thought it did, try dividing the values by two?
0
 

Author Comment

by:nchannon
Comment Utility
ok did that but it positioned the dialogs all over the place
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ok try setting them manually again

- only show dialog 1, and get it's length and position the way you want it
- show dialog 1 and dialog 2, and increment the X coordinate for dialog 2's X; so you know what to add for 3 and 4
- show dialog 1, dialog 2, and dialog 5, and increment the Y coordinate for dialog 5's Y; so you know what to add for 6, 7, and 8.
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
basically;

you call MoveWindow() for dialog 1. it's where you want it.
then call MoveWindow() for dialog 2 so it's where you want it

calculate the sums between those two windows.

apply the difference with a multiplier for dialog 3 and 4

then do the same starting over with dialog 5, except to get the difference of the Y coordinate.
0
 

Author Comment

by:nchannon
Comment Utility
the coordinates are being passed corectly but for some reason MoveWindow is doing strange things should I set the size of the dialog first before I call movewindow?
0
 

Author Comment

by:nchannon
Comment Utility
ok Im going to call it a night I will be back first thing in the morning thanks
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
movewindow() sets the size and position at the same time;

http://msdn.microsoft.com/library/en-us/dv_wceatl4/html/ealrfCWindowcolcolMoveWindow.asp?frame=true

Parameters
x
Specifies the new position of the left side of the window.
y
Specifies the new position of the top of the window.
nWidth
Specifies the new width of the window.
nHeight
Specifies the new height of the window.

or;
lpRect
Long pointer to a RECT structure that contains the client coordinates of the rectangle to be removed from the update region. If this parameter is NULL, the entire client area is removed.
bRepaint

maybe it would just be best to set each window position manually instead of using a loop. at least you have some control over where your windows are going, and you can deal with them one-by-one. always helps me if i discover things by stepping through them anyway
0
 

Author Comment

by:nchannon
Comment Utility
Hi now I see what MoveWindow is doing if I manualy set nWidth & nHeight the dialogs all position ok but I can't set these statically because the end user can select several different view windows depending on how many cameras they have connected or what type of view they want.
When set to 16 channel 4x4 then staticaly setting the dialog size is fine but if the user selects 36 6x6 then the dialogs decrease in size and nWidth and nHeight change so I need to work out the maths to dynamicall change these two sizes according to the users selection.
Ok example of what I mean:
if the user has 16 cameras connected but choose to 10 grid layout then we will have the first 10 cameras diplayed but the display will be
Dialog 1 nWidth=310 nHeight=410
the rest of the Dialogs will be nWidth=155 nHeight=205
taking the rest of the area of the parent window I hope you understand what I mean
0
 

Author Comment

by:nchannon
Comment Utility
Ok I have the dialog problem sorted by doing this
 int thisWinX = (int)(rc.left*gridX+2);
            int thisWinY = (int)(rc.top*gridY+2);
            int thisWinWidth = (int)(rc.right*gridX-2); // constant
            int thisWinLength =(int)(rc.bottom*gridY-2); // constant
            int width, height;
            width = thisWinWidth - thisWinX;
            height  = thisWinLength      -  thisWinY;
            videoWindows[j].MoveWindow(thisWinX,thisWinY,width,height);
Now to diplay the video in the correct dialog
           
0
 

Author Comment

by:nchannon
Comment Utility
Hi ok I have the dialogs workinf fine and I am also capturing each video channel but I am unable to pass the video and paint it into the correct dialog what is the corerct way of doing this
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
The MTMDI sample might help you there.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:nchannon
Comment Utility
I am having trouble passing the video to the client windows. My clients are created from a loop like this
      for(DWORD j=0;j<g_SplitInfo.scSplitConf.uNumRects;j++){
                  RECT rc = g_SplitInfo.scSplitConf.rcRect[j];
videoWindows[j].Create(NULL,NULL,WS_CHILD |WS_THICKFRAME,rc,this,j,0);
}
For this example I have created 16 Child dialogs and I now need to paint each of them with the video images.

to get the raw video image and convert it into a bitmap I have created a function like this:
void VideoDisplayWindow::DrawCaptureStream( LPBYTE _lpStream, CAPTUREDATA_INFO _tCaptureDataInfo)
{

       m_pRGB888 = (LPBYTE)new BYTE[720 * 576 * 3 + sizeof(BITMAPINFOHEADER)];
      LPBITMAPINFOHEADER pbih = (LPBITMAPINFOHEADER)m_pRGB888;

    pbih->biSize            = sizeof(BITMAPINFOHEADER);
    pbih->biWidth            = (DWORD)_tCaptureDataInfo.ImageSize.cx;
    pbih->biHeight            = -(LONG)_tCaptureDataInfo.ImageSize.cy;
    pbih->biPlanes            = 1;
    pbih->biBitCount      = 24;
    pbih->biCompression = (DWORD)BI_RGB;
    pbih->biSizeImage      = (DWORD)pbih->biWidth*pbih->biHeight*3;
    pbih->biXPelsPerMeter      = 0L;
    pbih->biYPelsPerMeter      = 0L;
    pbih->biClrUsed                  = 0L;
    pbih->biClrImportant      = 0L;
      
      YUV422ToRGB888( (DWORD)_lpStream,
      (DWORD)(m_pRGB888 + sizeof(BITMAPINFOHEADER)),
      _tCaptureDataInfo.dwCaptureImageLen );

      
      HDC   hdc = ::GetDC(hwnd);


      //FillRect( hdc, &rcClient, (HBRUSH)GetStockObject(BLACK_BRUSH) );
            RECT rect;
            ::GetClientRect(hwnd,&rect);
      
    StretchDIBits(  hdc,
                    0,
                    0,
                    (int)_tCaptureDataInfo.ImageSize.cx,
                    (int)_tCaptureDataInfo.ImageSize.cy,
                   0,
                   0,
        (int)_tCaptureDataInfo.ImageSize.cx,
                    (int)_tCaptureDataInfo.ImageSize.cy,
                   
                    (LPBYTE)(m_pRGB888 + sizeof(BITMAPINFOHEADER)),
                    (LPBITMAPINFO)(m_pRGB888),
                    DIB_RGB_COLORS,
                    SRCCOPY
                 );
            }
      ::ReleaseDC(hwnd, hdc);
      
delete[] m_pRGB888 ;
m_pRGB888 = NULL;
//      return 0;
}

Each camera raw video image is passed to this function from a thread each thread contains video data the video image is being displayed on the screen but it is just displayed in the top left corner of my application with each camera image ontop of the other how do I paint it in each dialog
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
How do you link an image to a display dialog?  (This function, I think, needs to be a member of your display dialog.  Is the thread getting the image created from the display dialog?)
0
 

Author Comment

by:nchannon
Comment Utility
The Thread is getting the raw image from a API call to hardware then it is passed to the function DrawCaptureStream(...) this part works fine but I need to pass the video data to each of the dialogs that have been created, but i am not sure how to identify which dialog is which and how to pass the video to the correct dialog.
For example the first thread passed is camera 1 so I need to then pass this data to dialog 1 and so on any ideas
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
I think you need some sort of logic like this.
Request view from camera X
Create and position window to show images from X
Start thread to read images from camera (now you pass some sort of ID to the thread eg the handle of the window that will display the image).

Now when the thread has an image to display it can post a message DIRECTLY to the window that is to display it.  (One window = one thread = one camera)
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
ps. I've not read most of the comments from snyp - if this duplicates a prior suggestion then I apologise.
0
 

Author Comment

by:nchannon
Comment Utility
yes but I am unsure on how to find the handle of each window. I have the camera ID from each thread so I can reference what thread is what but just not sure how to pass it the the correct window
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
each window is an indivual CDialog object. you can write functions in the cass CVideoWindow to deal with input
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
GetSafeHwnd()
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
for example;

void CWindowControl::OnVideoNotify() would be wherever your application is getting it's message to start video..

void CWindowControl::OnVideoNotify(int numCamera) {
videoWindows[numCamera].InitVideo()
}

in your CVideoWindow class, declare and definine the InitVideo() function to deal with setting up a display.
if your CWindowControl class is getting the data, pass the data from the CWindowControl class to whichever CVideoWindow object you want to display with.

this method isn't dealing with threads, but rather one single thread (your applocation) with multiple display windows (CVideoWindow instances)
0
 

Author Comment

by:nchannon
Comment Utility
Hi can you give me a sample as I am not sure how to do this all dialogs are now working perfect thanks and video is being display but layered ontop of eachother in the corner of the screen
0
 

Author Comment

by:nchannon
Comment Utility
here is the function that displays the raw video and paints it on screen
void VideoDisplayWindow::DrawCaptureStream( LPBYTE _lpStream, CAPTUREDATA_INFO _tCaptureDataInfo)
{
//      m_tCaptureDataInfo = _tCaptureDataInfo;
       m_pRGB888 = (LPBYTE)new BYTE[720 * 576 * 3 + sizeof(BITMAPINFOHEADER)];
      LPBITMAPINFOHEADER pbih = (LPBITMAPINFOHEADER)m_pRGB888;

    pbih->biSize            = sizeof(BITMAPINFOHEADER);
    pbih->biWidth            = (DWORD)_tCaptureDataInfo.ImageSize.cx;
    pbih->biHeight            = -(LONG)_tCaptureDataInfo.ImageSize.cy;
    pbih->biPlanes            = 1;
    pbih->biBitCount      = 24;
    pbih->biCompression = (DWORD)BI_RGB;
    pbih->biSizeImage      = (DWORD)pbih->biWidth*pbih->biHeight*3;
    pbih->biXPelsPerMeter      = 0L;
    pbih->biYPelsPerMeter      = 0L;
    pbih->biClrUsed                  = 0L;
    pbih->biClrImportant      = 0L;
      
      YUV422ToRGB888( (DWORD)_lpStream,
                              (DWORD)(m_pRGB888 + sizeof(BITMAPINFOHEADER)),
                              _tCaptureDataInfo.dwCaptureImageLen );

      
      HDC   hdc = ::GetDC(hwnd);


                        //FillRect( hdc, &rcClient, (HBRUSH)GetStockObject(BLACK_BRUSH) );
            RECT rect;
            ::GetClientRect(hwnd,&rect);
      
      
                 StretchDIBits(  hdc,
                    0,
                    0,
                    (int)_tCaptureDataInfo.ImageSize.cx,
                    (int)_tCaptureDataInfo.ImageSize.cy,
                    0,
                    0,
                               (int)_tCaptureDataInfo.ImageSize.cx,
                    (int)_tCaptureDataInfo.ImageSize.cy,
                   
                    (LPBYTE)(m_pRGB888 + sizeof(BITMAPINFOHEADER)),
                    (LPBITMAPINFO)(m_pRGB888),
                    DIB_RGB_COLORS,
                    SRCCOPY
                 );
            }
      ::ReleaseDC(hwnd, hdc);
      
delete[] m_pRGB888 ;
m_pRGB888 = NULL;
//      return 0;
}
this function is in the same class the creates the child dialogs
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
in your call to VideoDisplayWindow::DrawCaptureStream() you need to refer to a CVideoWindow's hwnd and dc instead of the CWindowControl dc and hwnd..

a couple of easy changes are;

CDC *vidCDC = videoWindows[SELECTED_WINDOW].GetDC();
HDC hdc = vidCDC->m_hDC;

RECT rect;
videoWindows[SELECTED_WINDOW].GetClientRect(&rect);

// this line's near the end of the function

videoWindows[SELECTED_WINDOW].ReleaseDC(vidCDC);
0
 

Author Comment

by:nchannon
Comment Utility
ok execution stops at this point
CDC *vidCDC = videoWindows[cam1].GetDC();
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
should be
CDC *vidCDC = videoWindows[0].GetDC();

or
CDC *vidCDC = videoWindows[1].GetDC();

or whichever child dialog you want to use, it's an array remember!
0
 

Author Comment

by:nchannon
Comment Utility
yes I know if theres 16 cameras only then the array size is also 16 cam1 has the value 1 . an assertion error was throwen so I told the debug window to ignore it then my system crashed
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ok.. click 'retry' instead if ignore. what assertion is failing?
0
 

Author Comment

by:nchannon
Comment Utility
Unhandled Exception at 0x7c28e898(mfc71d.dll) in Capture.exe: User Breakpoint

this is the error I get clicking retry
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
need to see what the assertion is.. can you single-step into it instead?
CDC *vidCDC = videoWindows[1].GetDC();
0
 

Author Comment

by:nchannon
Comment Utility
_AFXWIN_INLINE CDC* CWnd::GetDC()
      { ASSERT(::IsWindow(m_hWnd)); return CDC::FromHandle(::GetDC(m_hWnd)); }

file afxwin2.inl
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
have you created and shown this particular child dialog before calling DrawCaptureStream()?
0
 

Author Comment

by:nchannon
Comment Utility
yes the dialogs are created firsts before any threads are started I thought this my self and just checked my code to make sure and yes the dialogs get created first
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
i can't understand why your dialog has no window handle..

can you please set up a couple of breakpoints..

one at videoWindows[j].Create() when you create your dialogs
another at videoWindows[].GetDC() in VideoDisplayWindow::DrawCaptureStream

at both points.. check videoWindows[].m_hWnd isn't zero or NULL.
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
Just in case (pseudo code)
CDlg* pDlg = new CDlg(...);   //Memory for window assigned, window NOT created
pDlg->Create(...);  //at this point the window and handle should exist
0
 

Author Comment

by:nchannon
Comment Utility
ok check videoWindows[].m_hWnd gets a new value everytime it passes though the loop so thats ok
BUT
at VideoDisplayWindow::DrawCaptureStream videoWindows[].m_hWnd is 0x000000
0
 

Author Comment

by:nchannon
Comment Utility
videoWindows[j].Create()  is ok sorry new value everytime it passes though the loop
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ok.. how are you pointing to your array videoWindows from the class VideoDisplayWindow?

using extern videoWindows[]?
or CVideoWindow *videoWindows[]?
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
also.. what type of object is VideoDisplayWindow?
0
 

Author Comment

by:nchannon
Comment Utility
ok it works now my head is melted but thanks very much

I moved VideoDisplayWindow videoWindows[128]; from VideoDisplayWindow.h to VideoDisplayWindow.cpp but why didn't it work from the header file?
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
ah i get you.

possibly you have more than one array of type videoWindows[]? if you declared a whole new array in your header file it would just be a copy of new objects, rather than the objects which we were dealing with before.

the videoWindows[] array of objects need to be declared outside of the VideoDisplayWindow class. a better place to put them would be in your main dialog, as an array of members..

#include "VideoDisplayWindow.h"
class CWindowControl
public:
VideoDisplayWindow videoWindows[128];

..

then refer to that array as a member of your CWindowControl object every time you want to do something with a video display child dialog.

when you're processing your images from within the VideoDisplayWindow class, in your DrawCaptureStream function.. refer to the window dc and hwnd as this->GetDC() and this->m_hWnd. this is so each instance of your many child dialogs is controlled independantly.

a good way of thinking though is.. if it ain't broke, don't fix it. you can clean up how you want to do things some other time.

do you have a screenshot by the way? it'd be cool to see what's happened so far
0
 

Author Comment

by:nchannon
Comment Utility
yea have a screen shot how do i get it to you cant email it to you
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
can you upload it somewhere and post a link here?
0
 

Author Comment

by:nchannon
Comment Utility
No worries Ill put it up on my FTP site for you and send you the link I think this might of been worth more than 500 points thanks very much for your help.
I still have a few more questions about resizing the images you dont mind hanging in there to help me do you.
I would like to leave it till monday or tuesday if that ok going kitesurfing for the weekend clear the cobwebs
0
 
LVL 2

Expert Comment

by:snyp
Comment Utility
that's cool mate. it's good to help someone out =)
0
 

Author Comment

by:nchannon
Comment Utility
Hi snyp
here is a link to the results of what you help me on
www.pythonsecurity.net/sampsplitscreen.zip
if you are there could you also help with a resize issue with the image in the dialog I have it resizing ok as you will see from the screen shot but my colour depth when I reduce the image goes all splochy as you will see in the smaller dialogs in the screen shot
0
 
LVL 2

Accepted Solution

by:
snyp earned 500 total points
Comment Utility
hey man it's looking good =)

digital imaging isn't really anything i know about though.. you'll be better off creating a specific question to get it dealt with more quickly. plus, i spent so much time on this page, my girlfriend thinks i'm having an affair with you. i told her you're not my type but she won't listen >=|

i'll add you to my msn at work in a couple of weeks mate.
0
 

Author Comment

by:nchannon
Comment Utility
Cheers mate I sorted the problem after a little research just needed to add a function SetStretchBltMode(hdc,4); this sorted the resize and pixels of the image
we don't want to upset the misses life isnt worth it greaf.
Ill sign of now and thanks for all the help and see you on MSN soon
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now