[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