[erledigt] Tooltips / Statuszeilentexte aus externer Datei einlesen -> Fehlermeldung



  • Hallo zusammen!

    Erstmal muss ich sagen, dass ich was MFC angeht, noch absoluter Neuling bin, darum bitte ich im Voraus schonmal dumme Fragen oder unverständliche Formulierungen zu entschuldigen. Ich hoffe einfach, dass mir weitergeholfen werden kann und falls etwas unklar formuliert ist, dass einfach nachgefragt wird. 🙂

    Meine Frage ist, wie schon im Thema genannt, wie man die Tooltips bzw. die Statuszeilentexte einer MFC-Anwendung aus einer externen Datei einlesen kann.

    Kurz zum Grund meiner Frage:
    Ich habe die Aufgabe, eine MFC-Anwendung mit Hilfe von Visual C++ 6.0 zu übersetzen. Und zwar soll das so geschehen, dass alle Texte aus einer externen Datei eingelesen werden. Problem dabei ist, dass das Menü und die Tooltips, sowie die Statuszeile nur in der StringTable (und nirgendwo sonst im Quellcode) zur Verfügung stehen. Für die Menüstrutkur ist mir das schon ganz gut gelungen, jedoch leider noch nicht für die zugehörigen Tooltips und die Statuszeilentexte. Grund dafür ist, dass zum Beispiel dann die Textdatei, die derzeit ein vorgefertigtes Format hat (weil es die Funktion zum Einlesen schon gibt), an externe Übersetzer weitergegeben werden könnte.

    Was ich bräuchte:
    - einen Tipp, wie man die Beschriftung zu einem Wert in der StringTable auslesen kann
    und/oder
    - einen Tipp, wie ich Tooltips/Statuszeilentexte aus einer externen Datei einlesen und mit den Buttons verknüpfen kann

    Für jede Hilfe wäre ich sehr dankbar!
    Auch Rückfragen bei Unverstädnlichkeit sind gern gesehen. 😉

    Viele Grüße
    Ahalex


  • Mod

    Ich empfehle immer noch den Weg über Satelite DLLs.
    Siehe mein Artikel: http://www.mpdvc.de/artikel/MultilingualeProgramme.htm

    Ansonsten ist das nicht weiter schwer. Bau Dir zwei Handler für TTN_NEEDTEXTA und TTN_NEEDTEXTW ein in Dein CFrameWnd!

    ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, &CFrameWnd::OnToolTipText)
    	ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, &CFrameWnd::OnToolTipText)
    

    Den Code wie es die MFC macht findest Du ganz einfach in CFrameWnd::OnToolTipText in VC\atlmfc\src\mfc\winfrm.cpp



  • Danke sehr, hat mir schon weitergeholfen. 🙂

    Jetzt gibt es zwei Fehler, auf die ich leider keine Antwort gefunden habe:
    Die Funktion:

    [cpp]BOOL CMainFrame::OnDynamicTipText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
    {
      // OnNeedText should only be called for TTN_NEEDTEXT notifications!
      ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
    
      // need to handle both ANSI and UNICODE versions of the message
      TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
      TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
      TCHAR szFullText[256];
      CString strTipText; // used to hold final tool tip text before UNICODE conversion
    
      UINT nID = pNMHDR->idFrom;
      if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
        pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
      {
        // idFrom is actually the HWND of the tool
        nID = ((UINT)(WORD)::GetDlgCtrlID((HWND)nID));
      }
    
      //tooltiptext laden und übersetzen (tooltiptext kommt nach '\n')
      strTipText.LoadString(nID);
    
    [...]
    
      [b]if (pNMHDR->code == TTN_NEEDTEXTA)
        _wcstombsz(pTTTA->szText, strTipText, (sizeof(pTTTA->szText) / sizeof(pTTTA->szText[0])));
        else
        lstrcpyn(pTTTW->szText, strTipText, (sizeof(pTTTW->szText) / sizeof(pTTTW->szText[0])));[/b]
    
      *pResult = 0;
    
      // bring the tooltip window above other popup windows
      ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0
                   , SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);
    
      return TRUE;    // message was handled
    }[/cpp]
    

    Ergibt in den beiden fett markierten Zeilen folgende Fehler:
    - error C2664: '_wcstombsz' : Konvertierung des Parameters 2 von 'class CString' in 'const unsigned short *' nicht moeglich
    - error C2664: 'lstrcpynA' : Konvertierung des Parameters 1 von 'unsigned short [80]' in 'char *' nicht moeglich

    Das Problem scheint zu bestehen, weil ich Visual C++ 6.0 nutze, anstatt Visual Studio 2005 wie in meiner Vorlage. Wie kann ich das anpassen?

    Über Hilfe wäre ich hier nochmal dankbar. 🙂

    P.S.

    Martin Richter schrieb:

    Ich empfehle immer noch den Weg über Satelite DLLs.
    Siehe mein Artikel: http://www.mpdvc.de/artikel/MultilingualeProgramme.htm

    Hab ich bereits gesehen, diese Möglichkeit wurde von uns aber aus diversen Gründen ausgeschlossen/zurückgestellt.


  • Mod

    Unicode Projekt oder nicht?

    Schau Dir doch an was hier nicht stimmt... 🤡 Offensichtlich ist Dein strTipText kein Unicode String!

    Warum kopierst Du Dir den entsprechenden Text nicht aus den VC6 Sourcen?



  • Es gibt keine VC6-Sourcen dazu. 😉 (oder sie sind mir bis jetzt verborgen geblieben)
    Problem ist, dass ich den Fehler, der mit Visual Studio 2005 offensichtlich nicht auftritt, im VC6 habe und eben diesen irgendwie umgehen muss.

    Habe bereits verschiedene casts erfolglos versucht.

    Viele Grüße


  • Mod

    Hääää? Keien VC6 Sourcen dazu?
    Selber Dateiname^
    C:\Programme\Microsoft Visual Studio\VC98\MFC\SRC\WINFRM.CPP

    BOOL CFrameWnd::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
    {
    	ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
    
    	// need to handle both ANSI and UNICODE versions of the message
    	TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
    	TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
    	TCHAR szFullText[256];
    	CString strTipText;
    	UINT nID = pNMHDR->idFrom;
    	if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
    		pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
    	{
    		// idFrom is actually the HWND of the tool
    		nID = _AfxGetDlgCtrlID((HWND)nID);
    	}
    
    	if (nID != 0) // will be zero on a separator
    	{
    		// don't handle the message if no string resource found
    		if (AfxLoadString(nID, szFullText) == 0)
    			return FALSE;
    
    		// this is the command id, not the button index
    		AfxExtractSubString(strTipText, szFullText, 1, '\n');
    	}
    #ifndef _UNICODE
    	if (pNMHDR->code == TTN_NEEDTEXTA)
    		lstrcpyn(pTTTA->szText, strTipText, _countof(pTTTA->szText));
    	else
    		_mbstowcsz(pTTTW->szText, strTipText, _countof(pTTTW->szText));
    #else
    	if (pNMHDR->code == TTN_NEEDTEXTA)
    		_wcstombsz(pTTTA->szText, strTipText, _countof(pTTTA->szText));
    	else
    		lstrcpyn(pTTTW->szText, strTipText, _countof(pTTTW->szText));
    #endif
    	*pResult = 0;
    
    	// bring the tooltip window above other popup windows
    	::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
    		SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
    
    	return TRUE;    // message was handled
    }
    


  • Habs hinbekommen. Ich danke für die Hilfe. 👍


Anmelden zum Antworten