Re: integer divide by zero in CreateDlgIndirect()
On 24 Okt., 06:00, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Thu, 23 Oct 2008 08:45:02 -0700 (PDT), ".rhavin grobert" <cl...@yahoo.=
de> wrote:
I experience an integer divide by zero while trying to create a
modeless dialog from an mfc-dll that is called from a windowless
exe. I tried to give a step-by-step overview and hope someone
can explain what causes this error and what can be done about
it. TIA, ~.rhavin;)
=========================
==========================
====
1. windowless exe loads dll, calling InitInstance()
HINSTANCE is 0x10000000.
****
HINSTANCE is *always* 0x10000000, and it is essentially irrelevant to the=
analysis
****
OK, didnt know that. I Just wanted to give as much info as possible
2. InitInstance() registers HWND_MESSAGE-parent'ed msg-window
****
OK
****
3. Msg-window opened (only window that app has now)
****
Define "opened". I have no idea what you mean by this. Do you mean "Cre=
ated"? If so,
with what flags?
****
yep, i meant created. And it is now open. Creation is done by a
InitInstance fn called in the main dlls initinstance. looks like this:
_______________________________________________________
bool CQGUIManager::InitInstance(HINSTANCE hInstance)
{
// ... //
WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.hInstance = hInstance;
wc.lpszClassName = "GUIManager";
wc.lpfnWndProc = _WindowProc;
wc.cbWndExtra = sizeof(void*);
if (RegisterClass(&wc) == NULL)
return false;
m_hMsgWindow = ::CreateWindowEx(0, "GUIManager", NULL, 0, 0,
0, 0, 0, HWND_MESSAGE, NULL, hInstance, this);
if (m_hMsgWindow == NULL)
return false;
// ... //
return true;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4. Message send to msg-window "please open dialog (whatever)"
5. Message correctly received by msg-loop and appropriate fn called,
that looks like the following:
_______________________________________________________
void CFZGUIManager::DlgMessage()
{
CQDlgMessage* pDlg = new CQDlgMessage;
VERIFY(pDlg->Create());
// ... //
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6. Dialog allocated (new) CQDlgMessage ctor called.
7. CQDlgMessage is a public CQDialog that is a public CDialog
CQDialog has following ctor and saves its ResourceID:
_______________________________________________________
CQDialog::CQDialog(UINT nResourceID, CWnd* pParent) :
m_nResourceID(nResourceID), CDialog(nResourceID, pParent) {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7. CQDialog has a Create() fn that looks like this:
______________________________________________________
bool CQDialog::Create(CWnd* pParent)
if (pParent == NULL)
pParent = AfxGetMainWnd();
****
And where was this set? You said it was a windowless app, so unless this=
is set, and you
have not indicated that it has been, it should return NULL
****
Yes, i expect it in this scenario to return NULL. but my code should
also run if there already is a MainWnd.
if (pParent == NULL)
pParent = GetDesktopWindow();
****
Generally, you can assume that this is a mistake. Always. The very, ver=
y, very few, rare
exceptions will become obvious. I do not believe this is one of them
****
Why? In my scenario, it has to be NULL, because i dont have a main
window yet. so my code should take the desktop as curent main window,
simply becaus this create may be also called for the main window. So
its exactly the behavior i want: "If no one gives you a parent, use
MainWnd. If you currently have a MainWnd, use desktop!"
// #: * see below* //
return (CDialog::Create(m_nResourceID, pParent) != FALSE);
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8. At "#", the pParent is set to desktop, because app has no
main window (pParent = [CTempWnd hWnd=0x00010014]).
9. CDialog::Create() is called with correct RsrcID.
10. in CDialog::Create(), AfxFindResourceHandle() is called,
returning HINSTANCE 0x10000000, then FindResource() and
LoadResource() are called, both returning values != NULL
11. Now CreateIndirect() is called.
hDialogTemplate is 0x101b52b0
pParentWnd is 0x0099d5c0 (hWnd = 0x00010014, Desktop)
hInstance is 0x10000000
12. hDialogTemplate is locked (LockResource()) and another
CreateIndirect() overload is called witch calles (finally!)
CreateDlgIndirect(), where the following happens:
( a # marks my own comments ...)
______________________________________________________
BOOL CWnd::CreateDlgIndirect(LPCDLGTEMPLATE
lpDialogTemplate, CWnd* pParentWnd, HINSTANCE hInst)
{
ASSERT(lpDialogTemplate != NULL); //# -> OK
if (pParentWnd != NULL)
ASSERT_VALID(pParentWnd); //# -> OK
if (hInst == NULL) //# -> hInst !==
NULL
hInst = AfxGetInstanceHandle();
_AFX_OCC_DIALOG_INFO occDialogInfo;
COccManager* pOccManager = afxOccManager; //# ->NULL
HGLOBAL hTemplate = NULL;
HWND hWnd = NULL;
DWORD dwError = 0;
TRY
{
VERIFY(AfxDeferRegisterClass(
AFX_WNDCOMMCTLS_REG)
); //# -> OK
AfxDeferRegisterClass(
AFX_WNDCOMMCTLSNEW_REG
); //# -> seems ok
if (pOccManager != NULL)
{
//# ... is NULL, so nothing done here! ... #//
}
if (lpDialogTemplate == NULL) //# -> is != NULL
return FALSE;
// If no font specified, set the system font.
CString strFace;
WORD wSize = 0;
BOOL bSetSysFont = !CDialogTemplate::GetFont(
lpDialogTemplate, strFace, wSize);
//# -> bSetSysFont set to FALSE
//#... some stuff not called omitted here ... #//
// setup for modal loop and creation
m_nModalResult = -1;
m_nFlags |= WF_CONTINUEMODAL;
//# m_nFlags now == WF_CONTINUEMODAL;
// create modeless dialog
AfxHookWindowCreate(this); //# -> seems OK
//# ++++++++++++++++++++++++++++++++++++++++++++
//# following call (cant trace it any further) gives this message:
//# "Unhandled exeption in [myApp] (NTDLL.DLL):
//# 0xC0000094: Integer Divide by Zero"
//# ++++++++++++++++++++++++++++++++++++++++++++
hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate,
pParentWnd->GetSafeHwnd(), AfxDlgProc);
****
There are several possible causes. Since you have a "windowless" app, to=
ns of MFC
initialization have not been done. All bets are off. What was the backt=
race? WHere in
NTDLL.DLL did it fail? What were the registers? What was the instructio=
n?
I found it and it was really a div/0 in MY code, but the dbg (vc6)
showed me just some asm-instructions with a callstack consisting of 3
times "NTDLL.DLL". and nothing above.
Essentially, you have to show us your InitInstance code, and that is wher=
e you should
create a window that represents the app. Why do you not do this anyway?
=E4hm, im trying to do so. now it works, but i dont know what made my
dbg show me the wrong
callstack.
You are asking the typical "How do I get my code to work?" question, when=
the correct
question is probably something else, such as "How can I create an app tha=
t doesn't appear
in the task manager?"
No, its more like: my app is completely in dll. exe just loads dll and
starts different "flavors". empl: you start "server.exe" and dll is
started in server-mode.
But thx a lot trying to help, always appreciated.