HILE! Messages richtig abarbeiten (Programmabsturz!)
-
Hallo.
Ich habe ein groooosses Problem:
Mittels einem Menü sende ich ein definierte Nachricht an ein FensterpDlg->SendMessage(MyMessage);
In der Fensterklasse schaue ich innerhalb der Message-Map auf die Nachricht:
ON_MESSAGE(MyMessage, doTest)
In der selben Implementierungsdatei hab ich dann die MEthode 'doTest' ausprogrammiert.
Es funktioniert soweit auch ganz gut. Starte ich hingegen die REALEASE Version klappt es auch ('doTest' wird ausgeführt); wird die Anwendung jedoch geschlossen, erhalte ich ca. 5x hintereinander eine Absturzmeldung ("Speicher bla konnte auf Speicher blabla nicht mit read zugreifen").
Kann es sein, dass ich die Nachricht noch entsprechend weiterleiten muss oder weshalb sonst stürzt das Programm ab?
Wie könnte ich das ganze Debuggen? das Passiert ja nur in der Release-Version...
-
Erstens kannst du die Debuginfos zuschalten und zweitens kannst du es erstmal mit Messageboxen versuchen.
-
estartu_de schrieb:
Erstens kannst du die Debuginfos zuschalten und zweitens kannst du es erstmal mit Messageboxen versuchen.
Jo danke für den Ansatz. Kannst du vielleicht auch noch etwas über die Message selber schreiben? Nachdem diese vom Dialog abgefangengen und verarbeitet wurde - was passiert dann damit? Irgendwie scheint ja wohl noch ein Überbleibsel diesbezüglich zu exisiteren
-
Es wäre mal interessant, wie du MyMessage definierst und was im Handler steht.
Ich habe zwei eigene Messages im Programm und keine Probleme (auch nicht in der Releaseversion).
-
estartu_de schrieb:
Es wäre mal interessant, wie du MyMessage definierst und was im Handler steht.
Also ich habe das Phänomen selbst mittels einem kleines Helloworld-Programm feststellen müssen. Kann bitte jemand mal den Code anschauen?
Es ist eine einfache Dialogklasse mit lediglich einem Button und einem Label. Klickt man auf den Button, so wird eine Message an sich selbst (also den Dialog) gesendet. Der Dialog hat die entsprechende Message im MSG_MAP und ruft demzufolge die passende Methode 'test' auf. Diese setzt das CStatic Control (Label).
In der Debug-Version klappt alles wunderbar. Die Release-Version (Alle voreingestellten Projekteinstellungen wurden nicht verändert) erlaubt lediglich das einmalige klicken auf den Button. Beim zweiten mal stürzt das Programm ab!
// MessageProblem2Dlg.cpp : Implementierungsdatei #include "stdafx.h" #include "MessageProblem2.h" #include "MessageProblem2Dlg.h" static const UINT UWM_TEST = WM_USER + 1; #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMessageProblem2Dlg Dialogfeld CMessageProblem2Dlg::CMessageProblem2Dlg(CWnd* pParent /*=NULL*/) : CDialog(CMessageProblem2Dlg::IDD, pParent) { //{{AFX_DATA_INIT(CMessageProblem2Dlg) // HINWEIS: Der Klassenassistent fügt hier Member-Initialisierung ein //}}AFX_DATA_INIT // Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CMessageProblem2Dlg::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CMessageProblem2Dlg) DDX_Control(pDX, IDC_LABEL, m_La); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CMessageProblem2Dlg, CDialog) //{{AFX_MSG_MAP(CMessageProblem2Dlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_MESSAGE(UWM_TEST, test) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMessageProblem2Dlg Nachrichten-Handler BOOL CMessageProblem2Dlg::OnInitDialog(){ CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Großes Symbol verwenden SetIcon(m_hIcon, FALSE); // Kleines Symbol verwenden return TRUE; // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten } // ------------------------------------------------------- void CMessageProblem2Dlg::OnPaint(){ if (IsIconic()) { CPaintDC dc(this); // Gerätekontext für Zeichnen SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Symbol in Client-Rechteck zentrieren 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; // Symbol zeichnen dc.DrawIcon(x, y, m_hIcon); }else{ CDialog::OnPaint(); } } // ------------------------------------------------------- HCURSOR CMessageProblem2Dlg::OnQueryDragIcon(){ return (HCURSOR) m_hIcon; } // ------------------------------------------------------- void CMessageProblem2Dlg::OnButton1(){ SendMessage(UWM_TEST); } // ------------------------------------------------------- void CMessageProblem2Dlg::test(){ static int i=0; i++; CString str; str.Format("test: %d", i); m_La.SetWindowText(str); }
Eigentlich wird die eigene Message in einem eigenen headerfile so definiert:
// system uniquely user defined window messages static const UINT UWM_FILE_OPEN = ::RegisterWindowMessage("file_open"); static const UINT UWM_FILE_CLOSE = ::RegisterWindowMessage("file_close");
...Und in der Message-Map reagiere ich entsprechend mit ON_REGISTEREDMESSAGE()
Aber da es selbst mit dem WM_USER+1 nicht geht - scheint der Hund ganz wo anders begraben zu sein.
-
die Methode test muss wohl noch die Parameter WPARAM und LPARAM besitzen.
-
Jetzt wo du es sagst... die hab ich voll übersehen.
Bau die mal mit rein, du musst sie ja nicht nutzen. Was passiert dann?
-
estartu_de schrieb:
Jetzt wo du es sagst... die hab ich voll übersehen.
Bau die mal mit rein, du musst sie ja nicht nutzen. Was passiert dann?
dann gehts
lustigerweise funktioniert es dennoch bei der debug-version.
-
In der Debugversion werden Zeiger ja mit NULL initialisiert, auch wenn du dich nicht drum kümmerst.
Vielleicht war das ein Seiteneffekt.Nur komisch, denn du nutzt die Parameter ja gar nicht.
-
Und dann ist da noch DER Klassiker:
http://www.codeproject.com/debug/survivereleasever.asp@estartu: Ich glaube, der Link war heute Morgen von Dir: Dort wird genau dieses Phänomen beschrieben (allerdings auch ohne Erklärung)
Abschnitt: Linkage Errors - Parameter Counts
-
Ups.
Naja, ich kann den nicht auswendig, weiß aber, dass der Artikel einfach klasse ist.