?
Solved

Number of  controls is limited in dialog!?..

Posted on 2010-04-10
14
Medium Priority
?
375 Views
Last Modified: 2013-11-20
Trying to place about 300 static controls(not at run time!) in dialog..
it does not allow me  more than 254 ..
any idea how to overcome this limitation..
there is nothing about limits on number of controls with VC++ 6.0 documentation.
still need to place my controls through resource editor.. not at run time
0
Comment
Question by:khlauster
  • 5
  • 4
  • 4
  • +1
14 Comments
 
LVL 19

Expert Comment

by:alb66
ID: 30317541
I found a number of forum describing you problem. I don't know why, but it seems that is impossible to add 300 controls in the same dialog with VC6.
Anyway, it seems to me that you should consider to change your interface because I think that 300 static controls are really too much for only one dialog. You can consider to use a grid, a list or some property page.
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 30325548
I do not think that you have a screen with the resolution allowing to show all 300 controls.

Anyway you planned to use a vertical/horizontal scrollers.
This is the answer for your question - you need only few controls that initially will show an info and when the user will click on the scrollers you will update the information and show a next portion of data in the same controls.
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 30488541
Is this related to your other question about splitting an image into smaller pieces, displaying the pieces in the controls and then having multiple event handlers ?

If yes then why split the image ?  (More code, worse performance)

Just display the image in one picture control, add the event handlers you require for that one control.  Then in the event handler code check where the mouse is and act as if the SMALL image had been clicked (or whatever)
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:khlauster
ID: 30578629
pgnatyuk!

Sorry can not do scroll bars for my task: GUI must remain still.. along with other multiple controls it has to contain image, which must be fragmented into 300 pieces and response to events, for example: if user clicks on some fragment I have to replace this fragment with some other bitmap ..

AndyAinscow!

Yes, this related to my other question..

Basically, if I paint or load entire bitmap I need to know a few things:
Should I load my image on static or paint one right on dialog
how to intercept where was the image clicked
how to replace the clicked fragment with another bitmap of a similar to fragment’s size

I will appreciate a code sample and points up!
Thank you for helping out, experts!
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 30584870
>>Should I load my image on static or paint one right on dialog
>>how to intercept where was the image clicked
>>how to replace the clicked fragment with another bitmap of a similar to fragment’s size
If you are going to have 300 controls, better draw these images directly on the dialog DC. You can store in an array the rectangles of your images and on mouse down/move/up events you will know where is the mouse cursor. So you can replace the image and invalidate the image rectangle. Then call UpdateWindow to update the dialog immediately.

 The attached function will draw a bitmap in a rectangle. So in OnPaint of your dialog you have CPaintDC dc declared. Calculate the size of your rectangles and call this function for each one.


BOOL DrawPicture(HDC hDC, HBITMAP hBitmap, LPRECT lpRect)
{
	if (hBitmap == NULL)
		return FALSE;
	BITMAP bitmap = { 0 };
	GetObject(hBitmap, sizeof(BITMAP), &bitmap);
	HDC hMemDC = CreateCompatibleDC(hDC);
	HBITMAP hBitmapOld = (HBITMAP)SelectObject(hMemDC, hBitmap);
	StretchBlt(hDC, lpRect->left, lpRect->top, 
		lpRect->right - lpRect->left,
		lpRect->bottom - lpRect->top, 
		hMemDC, 0, 0, bitmap.bmWidth, bitmap. bmHeight, 
		SRCCOPY);
	SelectObject(hMemDC, hBitmapOld);
	DeleteDC(hMemDC);
	return TRUE;
}

Open in new window

0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 30587322
>>Should I load my image on static or paint one right on dialog
I'd load - then the static can be easily repositioned or resized.

Button click - there is a style setting that accepts mouse actions.

Cursor - GetCursorPos to find the cursor position (look in help files for more info)
0
 

Author Comment

by:khlauster
ID: 30632634
pgnatyuk!
thank you, i'll be testing your suggestion with the DrawPicture(HDC hDC, HBITMAP hBitmap, LPRECT lpRect)

AndyAinscow!
To load bitmap on staticis seems to me as a good  idea, yet
I am not clear on how to replace the fragments of the bitmap
I would appreciate the code sample
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 30639628
>>I am not clear on how to replace the fragments of the bitmap

Would this be a permanent or a temporary replacement ?  
0
 

Author Comment

by:khlauster
ID: 30669395
this will be a a temporary replacement,
any fragmented piece of a bitmap can be replaced depending on event brought by the user
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 30697562
Then drawing directly to the dc is probably simplest.
0
 

Author Comment

by:khlauster
ID: 30724250
It does not redraw a fragment on my image..
i'm trying to use DrawPicture(..) suggested by pgnatyuk
UpdateWindow() gives me a flicker..
//////////////////////////////////////////////////////////////////
void CTestDlg::OnPaint()
{
      CPaintDC dc(this);
      CRect rect;
      GetClientRect(&rect);
      CBitmap bitmap;

      int Left  =  223;
      int Right =  503;
      int Top   =  55;
      int Bottom = 280;

      bitmap.LoadBitmap(IDB_IMG);
      DrawPicture(dc, bitmap, CRect(Left, Top, Right, Bottom));

}


void CTestDlg::InsertPic(int Col,int  Row)
{
      CPaintDC dc(this);

      CRect rect;
      GetClientRect(&rect);
      rect.NormalizeRect();
      CBitmap bitmap;

      int Left  =  223 + Col*14;
      int Right =  237 + Col*14;;
      int Top     = 55 + Row*19;
      int Bottom  = 74 + Row*19;      

      bitmap.LoadBitmap(IDB_FRAGMENT);
       DrawPicture(dc, bitmap, CRect(Left, Top, Right, Bottom));
//                   UpdateWindow();
}

void CTestDlg::OnButton1()
{
      DrawFragment(5,7);
      
}
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 30750603
Yes, of course. You may use it carefully - call InvalidateRect for the needed rectangle, have a double buffering drawing, etc.
Why you have CPaintDC in InsertPict method? CPaintDC can be used in OnPaint only. In that place you need to use CDC.
The function I posted use LPRECT as the third parameter.
It does not redraw, because you could make another mistakes too or a problem in the logic somewhere. Try to this function for one bitmap and one rectangle. Then add few more. And so on.

0
 

Author Comment

by:khlauster
ID: 30788158
pgnatyuk!

The image drawing comes out very well in the:

void CTestDlg::OnPaint()
{
CPaintDC dc(this);
……………..
bitmap.LoadBitmap(IDB_IMG);
DrawPicture(dc, bitmap, CRect(Left, Top, Right, Bottom));

}


The problem was in replacing the fragment and, so far I came out with only the following:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CTestDlg::InsertPic(int Col,int  Row, UINT nIDResource, COLORREF penColor)
{

        CClientDC dc(this);


        int Left  =  223 + Col*14;
        int Right =  237 + Col*14;;
        int Top     = 55 + Row*19;
        int Bottom  = 74 + Row*19;

        CPen mypen;
        mypen.CreatePen ( PS_DOT, 1, penColor) ;

 CPen *oldPen = dc.SelectObject ( &mypen ) ;

  //////////////////////////////////////////////////    
 CBrush mybrush (penColor) ;
 CBrush *oldbrush = dc.SelectObject ( &mybrush ) ;

 CBitmap mybitmap ;
 mybitmap.LoadBitmap(nIDResource) ;
 
 mybrush.DeleteObject( ) ;

mybrush.CreatePatternBrush ( &mybitmap ) ;
oldbrush = dc.SelectObject ( &mybrush ) ;
dc.Rectangle ( Left, Top, Right, Bottom ) ;
   
mybrush.DeleteObject( ) ;



}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
It works good except the border around repainted fragment of the bitmap..
I would appreciate if you provide code sample, which would replace the fragment of the bitmap with another bitmap and without a border..
Thanks again
0
 
LVL 33

Accepted Solution

by:
pgnatyuk earned 1200 total points
ID: 30789455
Such functions as BitBlt, StretchBlt, ... receive the coordinates in their parameters.
The algorithm is simple:
1. You need to detect the size of the source image (the small bitmap, the fragment) - GetObject.
2. You need to create a temporary DC - CreateDC
3. You need to select the source bitmap in this DC- SelectObject. This function gives an old bitmap that you need to keep in a local variable.
4. You need to detect the place in the target bitmap where you want to copy your source bitmap. For example, a rectangle.
5. You need to create a temporary DC for the the target bitmap (if you do not have something on a global level or an instance variable in your controller class). And select this target bitmap in this DC.
6. Perform BitBlt if the size of the target rectangle is the same as your source bitmap or StretchBlt if the size is different.
7. In the first temporary DC, you need to select the old bitmap.
8. You delete all temprorary object (first DC, second DC, if you created it,...)
You can use TransparentBlt if you need instead of StretchBlt or BitBlt.
It does not matter what you use - pure GDI, MFC, GDI+, the algortim is always the same.
In this thread you already have a code that works exactly as I described here. You can modify it per your purpose and show here if you think it is needed.
0

Featured Post

2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
Get the source code for a fully functional Access application shell with several popular security features that Access VBA application developers desire, but find difficult or impossible to figure out how to code. You get the source code for managi…

601 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