Resource zur Laufzeit verändern
-
Hallo,
ich habe ein kleines Problem.
Es geht dabei um die Realisierung einer Shareware.
Eine 30-Tage-Version habe ich schonmal mit Hilfe der Registry hinbekommen.
Dieses Mal geht es aber um eine 10-Start-Version.jaja, hier kann ich auch die Registry nutzen xD
aber ich hatte da eine tolle Idee:ich habe in eine String-Resource die Zahl 10 gespeichert:
#define IDS_COUNTER 500 STRINGTABLE DISCARDABLE BEGIN IDS_COUNTER "\x0A" ENDwenn das Programm startet, lese ich mit LoadString die Zeichenkette, und schaue, welchen Wert das erste Word hat.
-> ich arbeite also mit Unicode ^^ich überprüfe, ob der Wert kleiner/gleich 0 ist
-> wenn ja: das Programm wurde 10 mal verwendet, als STOP!
-> ansonsten:
das erste Word dekrementieren (-1) und wieder speichern.
Leider gelingt es mir nicht in die Resource zu schreiben.Das ist mein Code:
#if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_IA64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_X64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") #else #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif #pragma comment(lib, "comctl32.lib") #include <windows.h> #include <commctrl.h> #include <cstring> #include <string> #include <boost/lexical_cast.hpp> #define IDS_COUNTER 500 void WindowsError(HWND hWnd, std::wstring szFunction, DWORD dwError) { if (dwError == 0xFFFFFFFF) dwError = GetLastError(); wchar_t* szError = NULL; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, 0, reinterpret_cast<wchar_t*>(&szError), 32, NULL); std::wstring szOutput = L"Fehler in: " + szFunction + L"\nFehlercode: " + boost::lexical_cast<std::wstring>(dwError) + L"\nBeschreibung: " + szError; LocalFree(szError); MessageBox(hWnd, szOutput.c_str(), L"Fehler!", MB_OK|MB_ICONERROR); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) { InitCommonControls(); wchar_t szBuffer[4]; LoadString(hInstance, IDS_COUNTER, szBuffer, 4); char iCounter = static_cast<char>(szBuffer[0]); if (iCounter <= 0) { MessageBox(NULL, L"Das Programm wurde bereits 10 mal verwendet!", L"Fehler!", MB_OK|MB_ICONERROR); } else { wchar_t buf[1024]; int i = iCounter; wsprintf(buf, L"Dies ist der %d. Start des Programmes!", 11 - i); MessageBox(NULL, buf, L"Hinweis!", MB_OK|MB_ICONINFORMATION); iCounter--; wchar_t szFileName[1024]; GetModuleFileName(hInstance, szFileName, 1024); HMODULE hInst = LoadLibrary(szFileName); HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDS_COUNTER), RT_STRING); HRSRC hResLoad = (HRSRC)LoadResource(hInst, hRes); wchar_t* pResLock = reinterpret_cast<wchar_t*>(LockResource(hResLoad)); if (!pResLock) { WindowsError(NULL, L"LockResource", 0xFFFFFFFF); } else { pResLock[0] = iCounter; } UnlockResource((void*)pResLock); FreeResource(hResLoad); FreeLibrary(hInst); } return 0; }das Programm bringt immer folgende Fehlermeldung:
Fehler in: LockResource
Fehlercode: 1812
Beschreibung: Die angegebene Image-Datei enthält keinen Resourcenabschnitt.ich bin für jede Hilfe dankbar.
MfG DrakoXP
-
Du solltest vielleicht immer die Rückgabewerte der Funktionen abfragen!
Wird die rc-Datei auch zum Projekt hinzugefügt?
-
ja, die erste MessageBox funktioniert schließlich.
beim kompilieren gibts auch keine Fehler.
-
ok, jetzt kommt bei FindResource Fehler 1814
-> Resource nicht gefunden
bei LoadResource kommt Fehler 1812
-> keine Resourcen in der Image-Datei
und bei LockResource 0
-> kein Fehler
-
kann mir niemand helfen?
-
Unter Vista wirst Du damit aber Probleme bekommen, weil bei aktivierter UAC das Ändern von Programmdateien unterhalb von "C:\Program Files" nicht möglich ist.
-
2 Sachen:
1.: was bedeutet unterhalb?
alles was in C:\Program Files\ ist,
oder alles außerhalb?2.: Vista ist dumm,
für mich kommt es drauf an, ob es unter XP läuft
außerdem ist es mehr zu Testzwecken, denn im Ernstfall kann ich ja auch
die Registry nutzen bzw. eine externe Datei.es wäre jetzt schön, wenn mir noch jemand sagen könnte, wie ich das ganze zum laufen bringe,
denn aus den Fehlern werde ich nicht wirklich schlau ???
-
DrakoXP schrieb:
1.: was bedeutet unterhalb?
alles was in C:\Program Files\ ist,
oder alles außerhalb?2.: Vista ist dumm,
für mich kommt es drauf an, ob es unter XP läuft
außerdem ist es mehr zu Testzwecken, denn im Ernstfall kann ich ja auch
die Registry nutzen bzw. eine externe Datei.es wäre jetzt schön, wenn mir noch jemand sagen könnte, wie ich das ganze zum laufen bringe,
denn aus den Fehlern werde ich nicht wirklich schlau ???Deine Antworten hier verleiten mich dazu Dir gar nicht zu antworten, denn einfach nur zu behaupten "Vista ist dumm" ist in meinen Augen ignorant!
Zum Thema:
In den Resourcen sind immer 16 Strings zu einem Block zusammengefasst:
int nBlock = dwResourceId / 16 + 1;
int nNum = dwResourceId & 0x0f;Wenn du also einen einzelnen String eintragen willst, ist nBlock die Resource-ID, die zu laden ist. In einem Block sind 16 Strings so gespeichert:
Ein WORD (16bit) als Länge des Strings, danach der String als Unicode. Ist ein String nicht vorhanden, ist da nur ein WORD mit Wert 0. Die Strings sind NICHT null-terminiert.nNum gibt Dir an der wievielte String es ist.
BTW: Steht auch in der MSDN
