Newsgroup: it.comp.programmare.win32
Titolo: [MFC] Access Violation su un programma dialog based

Salve,
ho trovato una bella routine che carica dei files jpg da file e li mostra su
una finestra.
Volevo utilizzarla per una prova con un progetto dialog fatto con l'app
wizard di Visual Studio, utilizzando le MFC.
Per ora la mia dialog box e' semplicissima e gestisce solo gli eventi:
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
Dentro il metodo OnInitDialog() ,  chiamo la routine
LoadPictureFile("10.jpg");
che mi carica il file .jpg e me lo mette in memoria dentro un ISStream:
***************************************************************************
Il problema arriva casualmente, o all'inizio del programma, o quando muovo
la dialog col mouse
oppure quando la copro con una finestra di un'altra applicazione e poi la
riscopro.
Mi da un bel access violation e il debug mi fa vedere che sto nella
CWinThread::PumpMessage
in corrispondenza del test:
if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
***************************************************************************
Nell'evento OnPaint() della dialog utilizzo gpPicture che e' di tipo
LPPICTURE e che e' stato caricato nella LoadPictureFile.
E disegno la jpg sulla dialog cosi':
gpPicture->Render(dc.m_hDC, 50, 50, nWidth, nHeight, 0, hmHeight,
hmWidth, -hmHeight, &rect);
dove i parametri sono tutti inizializzati.
Ecco la routine che carica il file che utilizza la OleLoadPicure:
// This function loads a file into an IStream.
void LoadPictureFile(LPCTSTR szFile)
{
   // open file
 HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0,
NULL);
 _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();
// InvalidateRect(ghWnd, NULL, TRUE);
}
Brancolo nel buio, mi studio meglio la questione e spero che qualche anima
pia mi dia qualche prezioso suggerimento.
Grazie
Maurus

 wrote in message
news:b065us$lp18j$1...@ID-125555.news.dfncis.de...
In caso vi sia d'aiuto ecco la OnPaint:
void CCardGameDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting
  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;
  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  if (gpPicture)
  {
     CPaintDC dc(this); // device context for painting
   // get width and height of picture
   long hmWidth;
   long hmHeight;
   gpPicture->get_Width(&hmWidth);
   gpPicture->get_Height(&hmHeight);
   // convert himetric to pixels
   int nWidth = MulDiv(hmWidth, GetDeviceCaps(dc.m_hDC, LOGPIXELSX),
HIMETRIC_INCH);
   int nHeight = MulDiv(hmHeight, GetDeviceCaps(dc.m_hDC, LOGPIXELSY),
HIMETRIC_INCH);
     CRect rect;
   //RECT rc;
   GetClientRect(&rect);
   // display picture using IPicture::Render
   gpPicture->Render(dc.m_hDC, 50, 50, nWidth, nHeight, 0, hmHeight,
hmWidth, -hmHeight, &rect);
  }
  //EndPaint(hWnd, &ps);
  CDialog::OnPaint();
 }
}
Maurus