Nach Migration auf VS 2017: LoadToolBar(..) hat einen Haltepunkt ausgelöst



  • Hallo,

    hier leider meine nächsten Schwierigkeiten mit der Migration.

    Immer, wenn LoadToolBar(ID) aufgerufen wird, bleibt die Anwendung im Debugger stehen.
    Datei: afxext.inl, Codezeile 98 (aus den Tools von VS2017)

    // CToolBar
    _AFXEXT_INLINE BOOL CToolBar::LoadToolBar(UINT nIDResource)
    	{ return LoadToolBar(MAKEINTRESOURCE(nIDResource)); }    // hier ist die Fehler-Marke
    _AFXEXT_INLINE BOOL CToolBar::LoadBitmap(UINT nIDResource)
    	{ return LoadBitmap(MAKEINTRESOURCE(nIDResource)); }
    

    Die Fehlermeldung lautet dann : "MyPrg.exe hat einen Haltepunkt ausgelöst"

    Dazu noch mein Quellcode, in dem das ausgelöst wird: (in VS2005 alles OK)

    if(!m_wndCommandBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE |   CBRS_ALIGN_TOP | CBRS_TOOLTIPS) || 
       !m_wndCommandBar.LoadToolBar(iToolBar))
    

    Die Anwendung kann man aber dann weiterlaufen lassen, ohne dass ein Fehler auftritt.
    Und es passiert nur im Debugger, das Release läuft.
    Nachfolgend passiert dies dann immer, wenn "LoadToolBar(..)" aufgerufen wird.

    In den Einstellungen sind alle "c++ Exeptions" eingestellt
    und bei den "win32 Exeptions" eigentlich nur wirkliche Fehler.
    Also die selben, wie zuvor in VS2005.

    Weiss hier jemand Rat?

    Grüsse
    Helmut

    Hab gerade Update 15.5 auf VS2017 ausgeführt:
    Nun läufts ein paar Schritte weiter.
    Fehlermeldung nun in "bartool.cpp", Zeile 433 ( Aufruf von "VERIFY ..." )

    BOOL CToolBar::AddReplaceBitmap(HBITMAP hbmImageWell)
    {
    	// need complete bitmap size to determine number of images
    	BITMAP bitmap;
    	VERIFY(::GetObject(hbmImageWell, sizeof(BITMAP), &bitmap));
    
    	// add the bitmap to the common control toolbar
    	BOOL bResult;
    	if (m_hbmImageWell == NULL)
    	{
             ...
    


  • Die Bitmap ist nicht da oder kann nicht geladen werden...



  • Hallo Martin,

    danke für die Antwort.
    Leider ist es die einzige.

    Aber es ist leider nicht die Lösung.
    Eine fehlende Bitmap hätte sich ja durch ihr Fehlen bemerkbar gemacht.
    Und die Anwendung funktioniert ja einwandfrei, wenn man dem Debugger einfach "Weiter" befiehlt.
    Und das Release Binary muckt an diesen Stellen gar nicht auf!
    Und unter dem VS2005 geht das auch.

    Ich habe allerdings vor längerer Zeit dort eine modifizierte Toolbar eingesetzt, die mir 24 Bit Farbtiefe erlaubt.
    Das hatte ich einfach noch vergessen, zu erwähnen.
    Leider weiss ich nimmer, wie dieses Projekt, ich göaube aus "CodeProject.com, hiess.

    Eigentlich wäre ich schon zufrieden, wenn ich diese Fehlermeldung in den Einstellungen deaktivieren könnte.
    Das habe ich auch versucht. Aber die gibt es dort einfach nicht.

    Grüsse
    Helmut



  • Noch eine Ergänzung:
    Gerade eben habe ich festgestellt, dass der Resourcen Editor einen Fehler bringt.
    Anscheinend wurde das Projekt dann wohl nicht vollständig migriert.

    Die Fehlermeldung verweist ausserdem auf eine ältere Version von Visual Studio. Sie lautet:
    "C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\prsht.h(0)"
    "error RC2247:SYMBOL name too long"

    Es gibt zwar einen Knopf, über den man den Code bearbeiten können sollte,
    aber leider schliesst er nur das Meldefenster.

    Und wie bekomme ich dieses Problem gelöst?



  • Wenn GetObject fehlschlägt muss es ja einen Grund haben...
    Lass Dir den Errocode anzeigen.
    Ich vermute hbmImageWell ist NULL, also liegt der Fehler einen Level tiefer.

    Ersetz die Bitmap mit was einfacherem...

    Mit der anderen Meldung kann ich nichts anfangen.

    Ansonsten nimm die Neuen CMfc Klassen... aus MFC Next da hast Du 24bit Unterstützung, Alphablending etc.



  • Danke Martin,

    Ja, "hbmImageWell" ist NULL.
    Beim Programmstart läuft es einmal durch "CToolBar::SetBitmap(HBITMAP hbmImageWell)" durch.
    Dort meckert dann die "ASSERT" Anweisung.
    Aber ich weiss leider nicht mit was einfacherem ich die Bitmap ersetzen soll.
    Ich habe nichts Anderes.

    Es gibt ja keinen wirklichen Error Code. Nur das, was ich schon geschrieben habe.
    Und es passiert auch nicht wirklich ein Fehler.
    Es ist nur unmöglich, die Anwendung zu debuggen, wenn man bei jeder Aktion dreimal auf "Weiter" klicken muss.
    Und ich kann die Meldung nicht abschalten!

    Und die RC2247 Meldung gibt es schon in anderen Foren, für die Umstellung von einer älteren VS-Version auf VS 2008.
    Aber die dortigen Lösungsansätze kann ich nicht auf das jetzige Problem übertragen.

    Das Ganze sieht dann nach einer längeren Unternehmung aus.
    Für die letzliche Umstellung auf eine neue Entwicklungsumgebung muss ich sicher die neuen MFC-Klassen nehmen.
    Die Info war schon mal wichtig, für später.

    Momentan wollte ich eigenlich nur die neuen Analysemöglichkeiten für den Heap nutzen,
    um nach einem anderen Fehler zu suchen.
    Aber diese Tools verstehe ich leider noch nicht. (Dauert wohl auch länger)

    Also gebe ich mich wieder meiner Verzweiflung hin.

    Aber danke
    Grüsse
    Helmut



  • Was bezweckst Du damit?
    SetBitmap(NULL) ist nicht nötig!
    LoadBitmap wirft doch die alten Infos raus?
    Alle Funktionen verwenden am Ende AddReplaceBitmap...

    Ist keine Bitmap bisher da, wird die neue gesetzt.
    Ist eine da wird die alte ersetzt...

    Als Id wird einfach das handle selbst benutzt...

    Du hast den Sourcecode!

    Ansonsten (ich wiederhole mich):
    Schmeiß den alten CToolBar raus und nimm CMFCToolBar! Der kann auch mehr als 16-Farben



  • Bzgl. RC2247.

    Deine Symbole, die der RC-Preprozessor benutzt sind einfach zu lang.
    Welche Header benötigst Du denn wirklich in der RC-Datei.

    Alles was Du nicht brauchst in einen #ifndef RC_INVOKED einschließen

    Beispielö für eine #stdafx.h

    #ifndef RC_INVOKED
    
    #include <afx.h>			// MFC core and standard components
    #include <oledb.h>			// OLEDB Header
    #include <afxwin.h>         // MFC core and standard components
    ....
    #endif 
    
    // Hier kommt alles was der RC benötigen könnte
    
    #include "xyzWinIDs.h"
    
    #define ID_XYZ_LAST 4711
    #define USE_32BPP_ARGB_BITMAPS
    #define UI_SCALE_COMBOBOXES
    ...
    

    Vielleicht musst Du hier nur was in der RC2 Datei auslagern.

    Evtl. solltest Du einen zweiten Thread aufmachen. Macht das diskutieren einfacher!



  • Meine StdAfx.h sieht folgendermassen aus:

    #if !defined(AFX_STDAFX_H__08D6FC5F_6098_4F9A_B912_8EDF6187CD93__INCLUDED_)
    #define AFX_STDAFX_H__08D6FC5F_6098_4F9A_B912_8EDF6187CD93__INCLUDED_
    
    #undef WINVER 
    #define WINVER 0x0601 
    #undef _WIN32_WINNT 
    #define _WIN32_WINNT 0x0601
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #define VC_EXTRALEAN		// Selten verwendete Teile der Windows-Header nicht einbinden
    #include <afxwin.h>         // MFC-Kern- und -Standardkomponenten
    #include <afxext.h>         // MFC-Erweiterungen
    #include <afxdisp.h>        // MFC Automatisierungsklassen
    #include <afxdtctl.h>		// MFC-Unterstützung für allgemeine Steuerelemente von Internet Explorer 4
    #include <commctrl.h>       // gehört zu untenstehendem pragma für "comctl32.lib"
    #ifndef _AFX_NO_AFXCMN_SUPPORT
    #include <afxcmn.h>			// MFC-Unterstützung für gängige Windows-Steuerelemente
    #endif // _AFX_NO_AFXCMN_SUPPORT
    
    #include "CDialogFortschritt.h"
    
    #include <objidl.h>
    #include <gdiplus.h>
    using namespace Gdiplus;
    #pragma comment (lib,"Gdiplus.lib")
    
    // Use v6 ComCtl32 Windows Common controls - without this line two different versions were loading
    #pragma comment(lib, "comctl32.lib")
    #pragma comment(linker,"\"/manifestdependency:type='win32' \
    name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
    processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.
    
    #endif // !defined(AFX_STDAFX_H__08D6FC5F_6098_4F9A_B912_8EDF6187CD93__INCLUDED_)
    

    Für das "SetBitmap(..)" kann ich nichts.
    Das wird von "m_wndCommandBar.CreateEx(..)" aufgerufen. Einmal eben, beim Erzeugen.

    Ich verwende die "XTrueColorToolBar" aus "cocdeproject.com" von
    Hans Dietrich.

    Aber was alles müsste ich aus der StdAfx.h mit dem "RC_INVOKED" alles rausnehmen?



  • Bzgl RC-Invoke Alles!

    Bzgl. CToolBar::CreateWindowEx. Nö. Dort wird nicht SetBitmap aufgerufen?
    Meines Erachtens wird CToolBar::SetBitmap in der ganzen MFC nicht aufgerufen...

    Ersetze diese Bitmap, mal mit einer Standard 16 Farben Bitmap!



  • Stimmt!
    Ich bin in der Zeile verrutscht.
    Es wird "CToolBar::AddReplaceBitmap(..)", Zeile 433 in bartool.cpp,
    Anweisung: "VERIFY(::GetObject(hbmImageWell, sizeof(BITMAP), &bitmap));"
    aufgerufen.
    Und "hbmImageWell" ist NULL.

    RC2247:
    Aber leider hat das "#ifndef RC_INVOKED" in der StdAfx.h nicht geholfen,
    den Resource-Editor dazu zu bringen, die .rc-Datei zu öffnen.

    Zu lange Namen, Bezeichner, Pfade,... gehören in die Zeit von MS-DOS 1985,
    aber nicht in 2017.



  • Du musst herausfinden welche include Datei es ist...



  • ... dann muss ich das wohl aufgeben.
    oder auf ein funktionierendes Visual Studio warten ...

    .. zumal das momentan nicht der Fehler ist, der meine Arbeit blockiert.

    Trotzdem vielen Dank



  • elmut19 schrieb:

    ... dann muss ich das wohl aufgeben.
    oder auf ein funktionierendes Visual Studio warten ...

    .. zumal das momentan nicht der Fehler ist, der meine Arbeit blockiert.

    Also ich hatte noch nie solche Probleme. Sende mir doch mal dein RC Datei und die resource.h, wenn das kein Geheimnis ist.



  • Vielen Dank, Martin.
    Das Angebot nehme ich gerne an.



  • Zumindest das RC2247 Problem der Migration wäre nun gelöst.

    Martin war so hilfsbereit, sich die Resource-Dateien anzusehen.
    Dabei hatte er bemerkt, dass es in meinem Projekt eine Datei

    "newres.h" ( bei mir seit 2004 vorhanden und unverändert ) gibt.

    Diese enthielt nur einige "#define" Anweisungen, die allerdings in den neuen Visual Studios schon integriert sind.
    Ich habe die "#include"´s auf diese Datei aus meiner ".rc" Datei rausgenommen und kann den Resource Editor nun im VS2017 öffnen.

    Und Dank VS2017 sind die guten alten Zeiten wieder zurück, wo man während des
    Build-Vorgangs mal kurz zum Einkaufen gehen konnte! (gegenüber VS2005)

    Und die ToolBar zickt im Debugger immernoch rum.

    Danke nochmal
    Grüsse Helmut



  • Callstack von dem ToolBar Problem bitte mal... 😉



  • Der Callstack vom ersten Halt der Toolbar:

    > mfc140ud.dll!CToolBar::AddReplaceBitmap(HBITMAP__ * hbmImageWell) Zeile 433 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadBitmapW(const wchar_t * lpszResourceName) Zeile 407 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadToolBar(const wchar_t * lpszResourceName) Zeile 382 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadToolBar(unsigned int nIDResource) Zeile 98 C++ Nichtbenutzercode. Symbole wurden geladen.
    Titan2.exe!CMainFrame::CreateToolBar(int bOldDesign) Zeile 166 C++ Symbole wurden geladen.
    Titan2.exe!CMainFrame::OnCreate(tagCREATESTRUCTW * lpCreateStruct) Zeile 272 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CTitanCeApp::InitInstance() Zeile 642 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Zeile 26 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen

    Dann klicke ich im Debugger auf weiter.
    Dann kommt gleich nochmal ein solcher Halt:

    > mfc140ud.dll!CToolBar::AddReplaceBitmap(HBITMAP__ * hbmImageWell) Zeile 433 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadBitmapW(const wchar_t * lpszResourceName) Zeile 407 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadToolBar(const wchar_t * lpszResourceName) Zeile 382 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadToolBar(unsigned int nIDResource) Zeile 98 C++ Nichtbenutzercode. Symbole wurden geladen.
    Titan2.exe!CMainFrame::LoadToolBar(int iToolBarNew, int iToolBarOld, int bIsOldDesign) Zeile 228 C++ Symbole wurden geladen.
    Titan2.exe!CTitanCeApp::SwitchToolbars(CBaseAnlage * pAnlage, CViewTitanCe * pView, int bBedingung, int bOldDesign, int bDoSwitch) Zeile 481 C++ Symbole wurden geladen.
    Titan2.exe!CTitanCeApp::On_Update_Buttons(CCmdUI * pCmdUI) Zeile 633 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CMainFrame::OnCmdMsg(unsigned int nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo) Zeile 486 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CTitanCeApp::UpdateToolbar() Zeile 953 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CMainFrame::OnCmdMsg(unsigned int nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo) Zeile 486 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CTitanCeApp::Run() Zeile 141 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!wWinMain(HINSTANCE
    _ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Zeile 26 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen

    Ebenfalls wieder auf "Weiter" und in der Anwendung über Toolbar-Button die nächste Programmebene anwählen:

    > mfc140ud.dll!CToolBar::AddReplaceBitmap(HBITMAP__ * hbmImageWell) Zeile 433 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadBitmapW(const wchar_t * lpszResourceName) Zeile 407 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadToolBar(const wchar_t * lpszResourceName) Zeile 382 C++ Nichtbenutzercode. Symbole wurden geladen.
    mfc140ud.dll!CToolBar::LoadToolBar(unsigned int nIDResource) Zeile 98 C++ Nichtbenutzercode. Symbole wurden geladen.
    Titan2.exe!CMainFrame::LoadToolBar(int iToolBarNew, int iToolBarOld, int bIsOldDesign) Zeile 228 C++ Symbole wurden geladen.
    Titan2.exe!CTitanCeApp::Liste(unsigned short wWas, unsigned short wSelectPos, unsigned short wLogSelect) Zeile 703 C++ Symbole wurden geladen.
    Titan2.exe!CTitanCeApp::GrafikReadVerzeichnisAuswahl(int bIncludeBackup, int bGrafikArchivAktiv, int bComesFromEinstellungen) Zeile 1822 C++ Symbole wurden geladen.
    Titan2.exe!CTitanCeApp::Grafik(int bGrafikArchivAktiv) Zeile 2260 C++ Symbole wurden geladen.
    Titan2.exe!CTitanCeApp::BenutzerAbfrage_Grafik() Zeile 350 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CMainFrame::OnCmdMsg(unsigned int nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo) Zeile 486 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CBarTool::OnLButtonUp(unsigned int nFlags, CPoint point) Zeile 151 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!CTitanCeApp::Run() Zeile 141 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen
    Titan2.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Zeile 26 C++ Symbole wurden geladen.
    [Externer Code] Frame mit Anmerkungen

    Und so geht das dann immer weiter.



  • Dann trace mal in den ersten Fall rein, ab CreateToolBar.
    Da muss doch was fehlen, wenn AddReplaceBitmap einen ASSERT liefert!
    Mit der Bitmap stimmt dann doch was nicht...



  • Danke Martin,

    ich werde da nochmal genauer durchgehen.
    Ich werde vor allem versuchen, an der Stelle auf die neuen Microsoft Toolbar-Klassen zu wechseln.
    So kann ich auch unnötigen Code abbauen.
    Die neuen Klassen scheinen ja nun das zu können, was ich brauche.

    Momentan habe ich kurzzeitige eine andere Baustelle, die mich wohl noch
    den Grossteil dieser Woche in Anspruch nehmen wird.

    Vielen Dank nochmal für die Hilfe.
    Es hat mich um Einiges weitergebracht.
    Grüsse
    Helmut



  • Ich habe nochmals nachgesehen.
    Habe auch den Grund für diesen Haltepunkt gefunden, der tatsächlich gar kein Fehler ist.

    Allerdings weiss ich nicht, wie man das lösen kann.

    Folgendes:
    Neues VS, also auch überarbeitete Systemfunktionen.
    Und über den Aufruf von LoadToolBar(..) kommt man auch bald in das MFC-Zeugs.

    In der Datei bartool.cpp gibt es die Function AfxLoadSysColorBitmap(..).
    Diese hat sich geändert!

    Alt (VS2005):

    HBITMAP AFXAPI
    AfxLoadSysColorBitmap(HINSTANCE hInst, HRSRC hRsrc, BOOL bMono)
    {
    	HGLOBAL hglb;
    	if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
    		return NULL;
    
    	LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
    	if (lpBitmap == NULL)
    		return NULL;
    

    Neu (VS2017)

    HBITMAP AFXAPI
    AfxLoadSysColorBitmap(HINSTANCE hInst, HRSRC hRsrc, BOOL bMono)
    {
    	HGLOBAL hglb;
    	if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
    	{
    		return NULL;
    	}
    
    	LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
    	if ((lpBitmap == NULL) || (lpBitmap->biBitCount > 8))
    	{
    		return NULL;    // Hier ist dann Schluss
    	}
    

    Da meine Bitmaps nun mal 24 Bit benötigen, steigt mein Programm an dieser Stelle mit der Abfrage auf 8 Bit aus!

    Wie schitzophren sind die denn bei MS?
    Nun kann man endlich die Toolbars in 24 Bit Farbtiefe bearbeiten.
    aber man darf sie nicht verwenden!
    Zumindest nicht in der CToolBar-Klasse.

    Oder hat man bei MS vielleicht durch irgend welche Aufruf Parameter doch die Möglichkeit geschaffen,
    den TrueColor Mode anzugeben? Im Create(..) vielleicht?

    Vielleicht weiss da jemand Rat?

    Grüsse
    Helmut