Thread: LPPICTURE and painting to a control.

  1. #1
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    LPPICTURE and painting to a control.

    I have a question regarding LPPICTURE and painting in a contol in a dialog.

    My question, how do I clear the picture in a dialog (erase for the next picture to get drawn? I thought I could do it like so:
    Code:
    ....
    InvalidateRect(hctrl, NULL, true);
    UpdateWindow(hctrl);
    This code seems to have no effect.

    Here is screen shot #1 followed by screen shot #2.

    How do I go about clearing the control before rendering a new pict?

    This is how I render the picture: (code from cprog, code guru and code project):
    Code:
    gpPicture->Render(hdcCtrl, rect.left, rect.top, rect.right, rect.bottom, 0, hmHeight, hmWidth, -hmHeight, &rc);
    ReleaseDC( hctrl, hdcCtrl );
    gpPicture->Release(); 
    }
    Thank you.


    Edit:
    It seems like I always have trouble trying to research programming questions on MSDN. Always a bunch of non-existent links:
    http://msdn.microsoft.com/en-us/libr...8VS.90%29.aspx

    A whole page of links that don't work!
    Last edited by Bajanine; 09-10-2010 at 01:25 PM.
    Favorite Quote:

    >For that reason someone invented C++.
    BLASPHEMY! Begone from my C board, you foul lover of objects, before the gods of C cast you into the void as punishment for your weakness! There is no penance for saying such things in my presence. You are henceforth excommunicated. Never return to this house, filthy heretic!



  2. #2
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    Here is the function:

    When I select two pictures in a row with the 'Browse for Picture' button I get the second picture overlapping the previous picture as the picture shows in my previous post.

    Here is the link to the code I am trying to implement:Easy way to display Gif’s, Ico’s, JPEG’s and BMP’s on your window « bits and bytes

    I am certain I had this code working as it should before. So there is probably something really obvious I have messed up!


    Code:
    case IDC_SELECT_PICTURE:
    			// choose picture.
    			if (!GetFolderSelection(NULL, pPath2Pic, TEXT("Please select a picture.")))
    			{
    				MessageBox(NULL, "You must select a picture.", "Error!", MB_OK);
    				break;
    			}
    
    			// Setup and display the picture.
    			{
    				hFile = CreateFile(Path2Pic, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    				//DWORD dw = GetLastError(); 
    				_ASSERTE(INVALID_HANDLE_VALUE != hFile);
    
    				// get file size
    				DWORD dwFileSize = GetFileSize(hFile, NULL);
    				_ASSERTE(-1 != dwFileSize);
    
    				LPVOID pvData = NULL;
    				// alloc memory based on file size
    				HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
    				_ASSERTE(NULL != hGlobal);
    
    				pvData = GlobalLock(hGlobal);
    				_ASSERTE(NULL != pvData);
    
    				DWORD dwBytesRead = 0;
    				// read file and store in global memory
    				BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
    				_ASSERTE(FALSE != bRead);
    				GlobalUnlock(hGlobal);
    				CloseHandle(hFile);
    
    				LPSTREAM pstm = NULL;
    				// create IStream* from global memory
    				HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
    				_ASSERTE(SUCCEEDED(hr) && pstm);
    
    				// Create IPicture from image file
    				if (gpPicture)
    					gpPicture->Release();
    				hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
    				_ASSERTE(SUCCEEDED(hr) && gpPicture); 
    				pstm->Release();  
    
    				// Retrieve dc and scale picture to fit control.
    				{
    					hctrl = GetDlgItem(hdlg, IDC_XSECTION);	// set hctrl to picture holder.
    					GetClientRect(hctrl, &rc);	//coordinates of the control client area.
    
    					hdcCtrl = GetDC( hctrl );
    					hmWidth = 0;
    					hmHeight = 0;
    					gpPicture->get_Width(&hmWidth);
    					gpPicture->get_Height(&hmHeight); 
    					WinRatio = (float(rc.right) / float(rc.bottom));
    					PictRatio = (float(hmWidth) / float(hmHeight));
    
    					if(WinRatio > PictRatio)
    					{
    						int width;
    
    						rect.bottom = rc.bottom;
    						rect.top = rc.top;
    						width = (int)(PictRatio * rc.bottom);
    						diff = (rc.right - width) / 2;
    						rect.right = width;
    						rect.left = diff;	
    					}
    					else
    					{
    						int height;
    
    						rect.right = rc.right;
    						rect.left = 0;
    						height = (int)(float(rc.right) / PictRatio);
    						diff = int((float(rc.bottom) - float(height)) / 2.0);
    						rect.bottom = height;
    						rect.top = diff;
    					}
    				}
    				gpPicture->Render(hdcCtrl, rect.left, rect.top, rect.right, rect.bottom, 0, hmHeight, hmWidth, -hmHeight, &rc);
    				ReleaseDC( hctrl, hdcCtrl );
    				gpPicture->Release(); 
    			}
    			// End: Setup and display the picture.
    			break;
    		}
    		break;
    Favorite Quote:

    >For that reason someone invented C++.
    BLASPHEMY! Begone from my C board, you foul lover of objects, before the gods of C cast you into the void as punishment for your weakness! There is no penance for saying such things in my presence. You are henceforth excommunicated. Never return to this house, filthy heretic!



  3. #3
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396
    Just in case anyone else has this problem I figured it out, I just invalidated the entire dialog and everything works as I wanted.
    Favorite Quote:

    >For that reason someone invented C++.
    BLASPHEMY! Begone from my C board, you foul lover of objects, before the gods of C cast you into the void as punishment for your weakness! There is no penance for saying such things in my presence. You are henceforth excommunicated. Never return to this house, filthy heretic!



  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    EDIT:
    As a whole screen redraw fixes the issue I think you are missing a call to repaint the control.

    You can calc the offset from the windows top left corner to the controls top left corner and then only repaint the image control if the paint is slow (assuming that your paint only redraws the invalidated area in the PAINTSTRUCT, not the entire dialog's client rect).

    Code:
    POINT ptCtrl = {rc.left,rc.top};
    ClientToScreen(hctrl, ptCtrl);//convert the controls top left to screen coords
    
    ScreenToClient(hdlg, ptCtrl); //convert back into the dlg's client coords
    
    RECT rcRedraw={ptCtrl.x, ptCtrl.y, rc.right + ptCtrl.x, rc.bottom + ptCtrl.y}; //create the area to redraw
    
    InvalidateRect(hdlg, &rcRedraw, false); //redraw only the control
    UpdateWindow(hdlg); //bypass OS msg queue and post to callback



    I would try painting the whole of the controls DC white before rendering the image.

    The image only appears to redraw the area of the control it covers, not the whole control (so you need to ensure that the control is blank before you render another image).


    Code:
    hdcCtrl = GetDC( hctrl );
    
    //fill control white to erase previous image
    FillRect(hdcCtrl, &rc, GetStockObject( WHITE_BRUSH) );
    
    hmWidth = 0;
    [note: not written using a compiler, let alone tested...]
    Last edited by novacain; 09-18-2010 at 10:59 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  5. #5
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396
    Thanks novacain, I should have thought of that.
    Favorite Quote:

    >For that reason someone invented C++.
    BLASPHEMY! Begone from my C board, you foul lover of objects, before the gods of C cast you into the void as punishment for your weakness! There is no penance for saying such things in my presence. You are henceforth excommunicated. Never return to this house, filthy heretic!



Popular pages Recent additions subscribe to a feed