[Erledigt] LoadString dynamisch?



  • Hi Leute!
    Ihr kennt doch sicher alle LoadString.
    Wie kann ich einen String dynamisch laden?
    Also vorher die Länge von diesem String bestimmen.

    Ich hoffe damit kennt sich einer von euch aus.
    Danke im Voraus!



  • Stichwort FindResource und SizeofResource



  • Ist stupide ne Funktoion aus meinem Programm kopiert, aber so müsste es funktionieren. Musst es dir nur noch für dich umschreiben 😃

    void Settings::FindStringW (int iID, std::wstring &strWide)
    {
    	wchar_t		*pwchMem	= NULL;
    	wchar_t		*pwchCur	= NULL;
    	HMODULE		hModule		= NULL;
    	int			strIndex	= iID % 16;
    
    	// Current module
    	hModule = LS.hModule;
    
    	HRSRC hRes = FindResourceW (hModule, MAKEINTRESOURCEW((iID / 16) +1), MAKEINTRESOURCEW(6));
    	if (hRes != NULL)
    	{
    		pwchMem = reinterpret_cast<wchar_t*> (LoadResource (hModule, hRes));
    		if (pwchMem != NULL)
    		{
    			pwchCur = pwchMem;
    			for (int i = 0; i < 16; i++)
    			{
    				if (*pwchCur != NULL)
    				{
    					int cchString = *pwchCur;	// String length in characters
    					pwchCur++;
    
    					if (i == strIndex)
    					{
    						// String was found in string table
    						strWide.~basic_string();
    						strWide.insert (0, pwchCur, cchString);
    
    						FreeResource (pwchMem);
    						return;
    					}
    					pwchCur += cchString;
    				}
    				else
    					pwchCur++;
    			}
    		}
    	}
    	else
    	{
    		err.NewError (EXCEPTION, L"FindResource failed, Settings::FindStringW", L"%x (hModule), %i (iID), RT_STRING", 
    						hModule, iID);
    	}
    	return;
    }
    


  • Musst es dir nur noch für dich umschreiben

    Das habe ich hier bereits in fix und fertig:

    UINT GetStringLength(HINSTANCE hInst, UINT uID)
    {
        HGLOBAL hGlobal;
        LPWSTR  pwstr;
        HRSRC   hrsrc;
        UINT    uLen = 0, x;
    
        if(NULL == (hrsrc = FindResource(hInst, MAKEINTRESOURCE((uID / 16) + 1), RT_STRING)))
            return(0);
    
        if(NULL == (hGlobal = LoadResource(hInst, hrsrc)))
            return(0);
    
        if(NULL != (pwstr = (LPWSTR)LockResource(hGlobal)))
        {
            for(x = (uID % 16) + 1; x; --x)
            {
                uLen = *pwstr;
                pwstr += (uLen + 1);
            }
            UnlockResource(hGlobal);
        }
    
        FreeResource(hGlobal);
        return(uLen);
    }
    


  • Danke euch Allen!
    Habe erst mit FindResource und SizeofResource die Größe bestimmt, ein WCHAR-Array angelegt, und dann mit LoadString gefüllt.

    Ich bin vorher an FindResource gescheitert, habe nicht durch 16 dividiert und dann um 1 addiert, sondern einfach die ID 1 zu 1 übernommen.
    Ach ja: ich habe die Division durch 16 um ein Bitshift ersetzt, ist performanter.

    Sieht jetzt so aus:

    String GTCORE_API LoadStringFromStringTable(HINSTANCE hModule,
    											UINT uID)
    {
    	//Länge herausfinden	
    	DWORD dwLength= SizeofResource(hModule, FindResource(hModule,MAKEINTRESOURCEW( (uID >> 4) + 1 ),RT_STRING) );
    	if(!dwLength)
    		throw(std::runtime_error("DWORD dwLength= SizeofResource(hModule, FindResource(hModule,MAKEINTRESOURCEW( (uID >> 4) + 1 ),RT_STRING) );"));
    	WCHAR *pwcBuffer=new WCHAR[dwLength];
    
    	//String laden
    	::LoadStringW(hModule,uID,pwcBuffer,dwLength);
    	String Str(pwcBuffer);
    	delete[](pwcBuffer);
    
    	return(Str);
    }
    

    🙂 Und funktioniert!



  • ich habe die Division durch 16 um ein Bitshift ersetzt, ist performanter.

    Gemessen oder geraten? Das optimiert der Compiler doch automatisch.



  • Blaze schrieb:

    🙂 Und funktioniert!

    Schau Dir dwLength bitte einmal genauer an. Das ist never ever die Länge des Strings!



  • Ich hab das noch nie benutzt ...
    Was bitte hat das mit der Division der ResourceID durch 16 und anschließenden Addition von 1 für eine Bewandnis?



  • Hallo,

    Belli schrieb:

    Ich hab das noch nie benutzt ...
    Was bitte hat das mit der Division der ResourceID durch 16 und anschließenden Addition von 1 für eine Bewandnis?

    Diese Formel ergibt sich aus der Tatsache, dass die Zeichenketten in Resource-Dateien in 16er-Blöcken verwaltet werden, durch die Bitverschiebung wird ein Block angewählt, und weil die eigentlichen IDs pro Block mit 1 starten, muss das noch addiert werden.

    Siehe dazu auch die Ausführungen hier:

    http://blogs.msdn.com/oldnewthing/archive/2004/01/30/65013.aspx

    MfG,

    Probe-Nutzer


Anmelden zum Antworten