|
Hi,
I've SDI application with this code in CMainFrame::OnCreate() (only snippet)
__m_wndDiscBar1.CreateEx(this, TBSTYLE_WRAPABLE|TBSTYLE_FLAT | TBSTYLE_TOOLTIPS |TBSTYLE_LIST, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_TOOLTIPS|CBRS_SIZE_DYNAMIC,CRect(0,0,0,0));
__m_wndDiscBar1.type=1;
__m_wndDiscBar1.Update(false);
__m_wndDiscBar1.SetFont(getFontLW());
__m_wndDiscBar2.CreateEx(this, TBSTYLE_WRAPABLE|TBSTYLE_FLAT | TBSTYLE_TOOLTIPS |TBSTYLE_LIST, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_SIZE_DYNAMIC,CRect(0,0,0,0));
__m_wndDiscBar2.type=2;
__m_wndDiscBar2.Update(false);
__m_wndDiscBar2.SetFont(getFontLW());
__m_wndDoubleDiscBar.Create(this,0);
__m_wndDoubleDiscBar.ModifyStyle(0,CBRS_ALIGN_LEFT);
__m_wndDoubleDiscBar.AddBar(&m_wndDiscBar2,NULL,NULL,RBBS_NOGRIPPER|RBBS_FIXEDS
IZE);
__m_wndDoubleDiscBar.AddBar(&m_wndDiscBar1,NULL,NULL,RBBS_NOGRIPPER|RBBS_FIXEDS
IZE);
m_wndDiscBar1/2 are classes derived from CToolBar. m_wndDoubleDiscBar is CReBar instance.
Problem is in this function, which is called from CMyView::OnSize() (I have two CListViews divided by splitter)
CMainFrame::ChangeDlgBar(int cx, int dx)
{
__CReBarCtrl& RCtrl = m_wndDoubleDiscBar.GetReBarCtrl();
__REBARBANDINFO rb;
__rb.cbSize=sizeof(REBARBANDINFO);
__// THIS IS PROBLEM FUNCTION
__RCtrl.GetBandInfo(0,&rb);
__rb.cx=width;
__rb.wID=0;
__rb.fMask=RBBIM_SIZE|RBBIM_ID;
__rb.fStyle=RBBS_FIXEDSIZE|RBBS_NOGRIPPER;
__RCtrl.SetBandInfo(0,&rb);
__RCtrl.MinimizeBand(0);
.
.
}
Here is call stack:
KERNEL32! 77ec8d34()
KERNEL32! 77ec88f9()
COMCTL32! 77b9e2d5()
USER32! 77e3a244()
USER32! 77e16b21()
USER32! 77e16b44()
CWnd:efWindowProcA(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 1053, unsigned int 1, long 1239272) line 1006 + 19 bytes
CWnd::WindowProc(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 1053, unsigned int 1, long 1239272) line 1586 + 19 bytes
CControlBar::WindowProc(CControlBar * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 1053, unsigned int 1, long 1239272) line 480 + 14 bytes
CReBar::WindowProc(CReBar * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 1053, unsigned int 1, long 1239272) line 321 + 14 bytes
AfxCallWndProc(CWnd * 0x00000000 {CWnd hWnd=???}, HWND__ * 0x00230560, unsigned int 1053, unsigned int 1, long 1239272) line 218
AfxWndProc(HWND__ * 0x00230560, unsigned int 1053, unsigned int 1, long 1239272) line 368
USER32! 77e3a244()
USER32! 77e16362()
USER32! 77e168a4()
CReBarCtrl::GetBandInfo() line 157 + 38 bytes
CMainFrame::ChangeDlgBar(int 0, int 1) line 858
CHinfoFileView2::OnSize(unsigned int 0, int 397, int 391) line 384
CWnd::OnWndMsg(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 5, unsigned int 0, long 6260016, long * 0x0012eac4) line 1964
CWnd::WindowProc(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 5, unsigned int 0, long 25624973) line 1585 + 27 bytes
AfxCallWndProc(CWnd * 0x00000000 {CWnd hWnd=???}, HWND__ * 0x003d042e, unsigned int 5, unsigned int 0, long 25624973) line 218
AfxWndProc(HWND__ * 0x003d042e, unsigned int 5, unsigned int 0, long 25624973) line 368
USER32! 77e3a244()
USER32! 77e16362()
USER32! 77e14c1a()
USER32! 77e1dd30()
USER32! 77e3a244()
USER32! 77e16b21()
USER32! 77e16b44()
CWnd:efWindowProcA(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 71, unsigned int 0, long 1240824) line 1006 + 19 bytes
CWnd::WindowProc(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 71, unsigned int 0, long 1240824) line 1586 + 19 bytes
AfxCallWndProc(CWnd * 0x00000000 {CWnd hWnd=???}, HWND__ * 0x003d042e, unsigned int 71, unsigned int 0, long 1240824) line 218
AfxWndProc(HWND__ * 0x003d042e, unsigned int 71, unsigned int 0, long 1240824) line 368
USER32! 77e3a244()
USER32! 77e14730()
USER32! 77e174b4()
NTDLL! 77f91a7f()
COMCTL32! 77b59ddf()
COMCTL32! 77b55af5()
COMCTL32! 77b5b24d()
USER32! 77e3a244()
USER32! 77e16b21()
USER32! 77e16b44()
CWnd:efWindowProcA(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 11, unsigned int 1, long 0) line 1006 + 19 bytes
CWnd::WindowProc(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 11, unsigned int 1, long 0) line 1586 + 19 bytes
AfxCallWndProc(CWnd * 0x00000000 {CWnd hWnd=???}, HWND__ * 0x003d042e, unsigned int 11, unsigned int 1, long 0) line 218
AfxWndProc(HWND__ * 0x003d042e, unsigned int 11, unsigned int 1, long 0) line 368
USER32! 77e3a244()
USER32! 77e16362()
USER32! 77e168a4()
CWnd::SetRedraw() line 120 + 33 bytes
CHinfoFTPDoc::listFiles(CListCtrl * 0x11136980 {CHinfoFileView2 hWnd=0x003d042e}, const char * 0x00000000, int 0, CMyFileView * 0x11136980 {CHinfoFileView2 hWnd=0x003d042e}, int 0) line 993
CHinfoFileView2::OnInitialUpdate() line 259
CWnd::OnWndMsg(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 868, unsigned int 0, long 6320368, long * 0x0012fbc8) line 1825
CWnd::WindowProc(CWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 868, unsigned int 0, long 0) line 1585 + 27 bytes
AfxCallWndProc(CWnd * 0x00000000 {CWnd hWnd=???}, HWND__ * 0x003d042e, unsigned int 868, unsigned int 0, long 0) line 218
CWnd::SendMessageToDescendants(HWND__ * 0x004d052e, unsigned int 868, unsigned int 0, long 0, int 1, int 1) line 2309
CWnd::SendMessageToDescendants(HWND__ * 0x0027045e, unsigned int 868, unsigned int 0, long 0, int 1, int 1) line 2318 + 21 bytes
CFrameWnd::InitialUpdateFrame(CFrameWnd * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), CDocument * 0x1113fdc8 {CHinfoFTPDoc}, int 1) line 753
CDocTemplate::InitialUpdateFrame(CDocTemplate * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), CFrameWnd * 0x11181188 {CMainFrame hWnd=0x0027045e}, CDocument * 0x1113fdc8 {CHinfoFTPDoc}, int 1) line 332
CSingleDocTemplate::OpenDocumentFile(CSingleDocTem
plate * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), const char * 0x00000000, int 1) line 205
CDocManager::OnFileNew(CDocManager * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int)) line 829
_AfxDispatchCmdMsg(CCmdTarget * 0x00640cf8 class CHinfoFTPApp theApp, unsigned int 57600, int 0, void (void)* 0x005b7670 CWinApp::OnFileNew(void), void * 0x00000000, unsigned int 12, AFX_CMDHANDLERINFO * 0x00000000) line 88
CCmdTarget::OnCmdMsg(CCmdTarget * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), unsigned int 57600, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 302 + 24 bytes
CWinApp::ProcessShellCommand(CWinApp * const 0x004700a0 CHinfoFileView2::OnSize(unsigned int, int, int), CCommandLineInfo & {CCommandLineInfo}) line 31 + 23 bytes
CHinfoFTPApp::InitInstance() line 377 + 12 bytes
AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00133feb, int 1) line 39 + 7 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00133feb, int 1) line 30
HINFOFTP! WinMainCRTStartup + 224 bytes
KERNEL32! 77ea847c()
[/php]
I went deeper for the cause of the access violation and found possible problem in this code:
LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
__// special message which identifies the window as using AfxWndProc
__if (nMsg == WM_QUERYAFXWNDPROC)
____return 1;
__// all other messages route through message map
__CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
__ASSERT(pWnd != NULL);
__ASSERT(pWnd->m_hWnd == hWnd);
__return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
}
because CWnd::FromHandlePermanent(hWnd) returns NULL. But hWnd is valid (or at least the same value as I could see imediately after CReBar::Create() being finished)
But what's most confusing for me - this access violation only appears when I build release build with debug info (For Edit And Continue). When I build release build without debug info or when I build debug info, no access violation happens.
I'm really out....
Could someone help me?
I will appreciate any suggestion.
|
|
|
|
|
s_k wrote:
__REBARBANDINFO rb;
__rb.cbSize=sizeof(REBARBANDINFO);
__// THIS IS PROBLEM FUNCTION
__RCtrl.GetBandInfo(0,&rb);
try
_REBARBANDINFO rb;
::ZeroMemory(&rb, sizeof(REBARBANDINFO));
__rb.cbSize=sizeof(REBARBANDINFO);
|
|
|
|
|
IT WORKS!!
I thank you so much!
Anyway, if you answered me this question, I would be even more happy: How is it possible that neither in debug version nor in release version without debug info no access violation appeared? Maybe I would understand difference between debug and clean release version, but what the heck is difference between, we can say, two DEBUG versions?
Thank you again, AlexO, I really appreciate your help!
|
|
|
|
|
It is very common error in debug vs. release. The problem is debug memory allocation it usually initializes memory to 0 or 0xcdcdcdcd.
Release memory is not initialized so values are random. Example:
DWORD dwSize; //not that is not initialized
SomeFunction(&dwSize);//note dwSize is in/out parameter
the example above might work in debug but will blow up in release.
|
|
|
|
|
I don't understand.
dwSize is just local variable. Its address (as passed to SomeFunction()) will be always valid, won't be? Of course SomeFunction() mustn't do something like this:
TCHAR* s = new TCHAR[dwSize];
because dwSize was not initialized, but the code you posted itself is valid as long as I don't know SomeFunction() code...
|
|
|
|
|
no, I did not mean address. Imagine that inside that function you have soemthing like
int SomeFunction(DWORD* dwSize, char* actualBuffer)
{
if(*dwSize > 0)
{
char* pCopy = new char[*dwSize];
::memcpy(pCopy, actualBuffer, *dwSize);//this is where error will manifest itself if you forgot to initialize dwSize, in release dwSize could be anything, in debug it would probably be zero so we never come here
...
}
...
}
P.S. Real scenario is usually more complex but idea is the same
|
|
|
|
|
Yes, I understand now, that's what I thought could really cause problems...
|
|
|
|
|
A few things I'd try:
1) Always test functions succeed. In particular CreateEx(), Create() etc.
2) In CMainFrame::ChangeDlgBar() add:
ASSERT_VALID( this );
ASSERT( ::IsWindow( m_hWnd );
ASSERT( ::IsWindow( m_wndDoubleDiscBar.m_hWnd ) );
__CReBarCtrl& RCtrl = m_wndDoubleDiscBar.GetReBarCtrl();
ASSERT_VALID( &RCtrl );
ASSERT( ::IsWindow( RCtrl.m_hWnd );
Neville Franks, Author of ED for Windows. Free Trial at www.getsoft.com
|
|
|
|
|
Thanks Neville! Fortunately, AlexO has already found the cause of the problem - I have to call ::ZeroMemory to zero REBARBANDINFO structure. Never thought this may be reason for CWnd::FromHandlePermanent() to return NULL...
|
|
|
|
|
Yes I saw Alex's post just after I sent mine. Initialization issues like this can be hard to track down and the outcome can vary depend on what crap happens to be being set. Bottom line is your back in business.
Neville Franks, Author of ED for Windows. Free Trial at www.getsoft.com
|
|
|
|
|
In debug mode build, the linker assigns bogus size storage for each block. When you accidentally forgotten to delete or deinitialize some component. The extra size storage in each other block can still cater as it had not touched the actual content. But once the linker had swicthed to release mode. All the storage blocks were optimise to it supposing size. When you have crossing action in your code, straight up a access violation will pop up.
I read this in one of codeproject article. Can't remember the title already but hope this helps.
|
|
|
|
|
I know I probably forgot to call a default class member when building some message handler or another but this is really aggravating.
I have a dialog based app and the app exits if you hit the enter key.
I really wish it didn't do this.
Could anyone help?
|
|
|
|
|
The enter key activates the default button of the dialog which is usually the Ok button..
John
|
|
|
|
|
John M. Drescher wrote:
The enter key activates the default button of the dialog which is usually the Ok button..
Thanks - I'm an idiot. That's the first thing I thought of, and I know it is true from so many other apps and is just a Windows basic user-level thing but I totally forgot about that and was mixing it up with the space bar ala the currently active control.
I guess I will change the control ID for the button. :sheepish grin:
|
|
|
|
|
tnolley wrote:
I guess I will change the control ID for the button.
Changing the control ID won't solve your problem. The most simple way is to override CDialog::OnOK(). You might want to override CDialog::OnCancel() as well, in case you don't want the dialog to get closed when you hit the escape key.
CMyDialog::OnOK(){ return; }
// Afterall, I realized that even my comment lines have bugs
When one cannot invent, one must at least improve (in bed).-My latest fortune cookie
|
|
|
|
|
|
What's the quickest way (in terms of programming time) to display an image (jpg, tif, bmp or gif) ? I thought about simply using a WebBrowser2 control, but wanted to ask here as imaging is something I've never got into so there might be a more accepted method of doing this.
Cheers,
Tom Archer
Inside C#, Extending MFC Applications with the .NET Framework
It's better to listen to others than to speak, because I already know what I'm going to say anyway. - friend of Jörgen Sigvardsson
|
|
|
|
|
Unless you want to study the JPEG file format and write a decoder by hand, you are better off using an image library.
I have had great results using the Victor Image Library. It is free for 30 days while you evaluate it.
It is available at:
http://www.catenary.com
The demo version of VIC32.DLL is available free for download. The commercial version of VIC32.DLL costs $499 and is included with any application that uses the VIC library. Although I would certainly pay for it if you planned on releasing software developed with it. If for whatever reason you didn't get the chance to fully evaluate it during the 30 days, (sday you got hit by a car and spent 29 days in the hospital) you could either change your system clock or do a web search for VIC32.DLL
|
|
|
|
|
No can do. This is for a chapter demo on reading BLOB data with ADO.NET. Therefore, I don't want to force the reader to have to download or install 3rd party products.
Cheers,
Tom Archer
Inside C#, Extending MFC Applications with the .NET Framework
It's better to listen to others than to speak, because I already know what I'm going to say anyway. - friend of Jörgen Sigvardsson
|
|
|
|
|
I forgot where I found this snippet.
You can use it in a subclassed CStatic you draw on the CDialog
in Sub Classed CStatic header
public:
void LoadPictureFile(LPCTSTR szFile);
virtual ~CSubClassStatic();
protected:
LPPICTURE gpPicture;
protected:
//{{AFX_MSG(CSubClassStatic)
afx_msg void OnPaint();
//}}AFX_MSG
in Sub Classed CStatic implementation File
#define MAX_LOADSTRING 100
#define HIMETRIC_INCH 2540
#define MAP_LOGHIM_TO_PIX(x,ppli) ( ((ppli)*(x) + HIMETRIC_INCH/2) / HIMETRIC_INCH )
void CSubClassStatic::OnPaint()
{
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);
RECT rc;
GetClientRect(&rc);
// display picture using IPicture::Render
gpPicture->Render(dc.m_hDC, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
}
// TODO: Add your message handler code here
}
void CSubClassStatic::LoadPictureFile(LPCTSTR szFile)
{
// open file
HANDLE hFile = CreateFile(szFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
// get file size
DWORD dwFileSize = GetFileSize(hFile, NULL);
if (-1 == dwFileSize) return;
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();
if (gpPicture)
{
CPaintDC dc(this);
// 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);
}
InvalidateRect(NULL, TRUE);
}
|
|
|
|
|
I kind of forgot what this actually was, it's using the (OLE I believe?), IPicture interface to load the file/type automatically
|
|
|
|
|
|
Use OleLoadPicturePath() to get an IPicture interface, then IPicture::Render() to draw it. You could also use the shell's IExtractImage interface to generate a thumbnail, but doing so takes about 30 lines of code.
--Mike--
"Big handwavy generalizations made from a position of deep ignorance is one of the biggest wastes of time on the net today.
-- Joel Spolsky
Ericahist | Homepage | RightClick-Encrypt | 1ClickPicGrabber
|
|
|
|
|
|
Either Michael's way, or using GDI+
Graphics g(hdc);
Image img(imageFileName);
g.DrawImage(x, y, &img);
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|