mist -> Verzweiflung
-
Frage 1 : gültig
Frage 2 : gültigEs kann u.U. sein, dass die Werte, die Du mit SetWindowLong () gespeichert hast, ungültig wurden. Das liegt allerdings nicht an Get/SetWindowLong ().
Beschreibe das Problem mal näher.
-
naja, der Anwendungsbereich ist in 25 Teile geteilt (5x5) - jeder Teil ist ein ChildWindow. diese sollen auf knopfdruck ein Bild anzeigen oder ihren eigenen Anwendungsbereich weiß färben (wenn dort zuvor ein Bild war). Auf jeden Fall ist im Zusatzspeicher vom Hauptfenster eine Struktur gespeichert:
struct HauptInfo { TCHAR* pszFeldName; // ersatz für ne globale Variable short idFocus; // das z.Z aktive Child-Fenster HBITMAP hActiveBmp; // ein (Später auswählbares) BITMAP, bzw ein Handle int cxBmp; // Bitmapbreite int cyBmp; // BitmapHöhe };Gespeichert wird diese im Speicher mit dieser Funktion:
int SetHInfo(HWND hWnd, HauptInfo HInfo) { SetWindowLong(hWnd, 0,(LONG) HInfo.pszFeldName); SetWindowWord(hWnd, sizeof(TCHAR*),(short) HInfo.idFocus); SetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(int),(LONG) HInfo.hActiveBmp); SetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(int) + sizeof(HBITMAP),(LONG) HInfo.cxBmp); SetWindowLong(hWnd, sizeof(TCHAR*) + 2*sizeof(int) + sizeof(HBITMAP),(LONG) HInfo.cyBmp); return 0; }Abgeholt wird die Information durch
int GetHInfo(HWND hWnd, HauptInfo &HInfo) { HInfo.pszFeldName = (TCHAR*) GetWindowLong(hWnd, 0); HInfo.idFocus = (short) GetWindowWord(hWnd, sizeof(TCHAR*)); HInfo.hActiveBmp = (HBITMAP) (GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short))); HInfo.cxBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(int) + sizeof(HBITMAP)); HInfo.cyBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + 2*sizeof(int) + sizeof(HBITMAP)); return 0; }bei WM_CREATE des Haupt Proc wird folgendes gemacht:
case WM_CREATE: // für Bitmap hInstance = ((LPCREATESTRUCT) lParam)->hInstance; for(y = 0; y<5;y++) for(x = 0; x<5;x++) { FeldHwnd[x][y] = CreateWindow(HInfo.pszFeldName, NULL, WS_CHILDWINDOW | WS_VISIBLE, 0,0,0,0, //braucht man nicht, da Werte bei Size gesetzt werden hWnd, (HMENU) (y << 8 | x), (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE), NULL); } // Bitmap Laden HInfo.hActiveBmp = LoadBitmap(hInstance, TEXT("bitmap")); GetObject(HInfo.hActiveBmp, sizeof(BITMAP), &bitmap); // für spätere Ausgabe HInfo.cxBmp = bitmap.bmWidth; HInfo.cyBmp = bitmap.bmHeight; // Infos speichern SetHInfo(hWnd, HInfo); return 0;hier nochmal die Objekte/Variablen des HauptProcs:
// 25 Felder static HWND FeldHwnd[5][5]; static short idFocus = (short) LOWORD(GetWindowLong(hWnd, sizeof(TCHAR*))); // gebrauchte Variablen int x, y; static int cxClient, cyClient, cxSource, cySource; TCHAR Text[10]; static HauptInfo HInfo; // Hier werden die Infos jedes mal abgeholt abgeholt GetHInfo(hWnd, HInfo); BITMAP bitmap; HINSTANCE hInstance;dann gibt es noch eine Struktur, die im Nebenspeicher des Child-Windows gespeichert wird:
struct FeldInfo { HBITMAP hBmp; short pmd; RECT rect; int cxBmp; int cyBmp; };hier die set und getfunktionen:
int SetFInfo(HWND hWnd, FeldInfo FInfo) { SetWindowLong(hWnd, 0,(LONG) FInfo.hBmp); SetWindowWord(hWnd, sizeof(HBITMAP),(short) FInfo.pmd); SetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short), FInfo.rect.left); SetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + sizeof(LONG), FInfo.rect.top); SetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 2*sizeof(LONG), FInfo.rect.right); SetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 3*sizeof(LONG), FInfo.rect.bottom); SetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 4*sizeof(LONG),FInfo.cxBmp); SetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 4*sizeof(LONG) + sizeof(int),FInfo.cyBmp); return 0; } int GetFInfo(HWND hWnd, FeldInfo &FInfo) { FInfo.hBmp = (HBITMAP) GetWindowLong(hWnd, 0); FInfo.pmd = GetWindowWord(hWnd, sizeof(HBITMAP)); FInfo.rect.left = GetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short)); FInfo.rect.top = GetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + sizeof(LONG)); FInfo.rect.right = GetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 2*sizeof(LONG)); FInfo.rect.bottom = GetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 3*sizeof(LONG)); FInfo.cxBmp = GetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 4*sizeof(LONG)); FInfo.cyBmp = GetWindowLong(hWnd, sizeof(HBITMAP) + sizeof(short) + 4*sizeof(LONG) + sizeof(int)); return 0; }bei WM_LBUTTONDOWN im FeldProc geschieht folgendes:
if(FInfo.pmd == BRUSH) { FInfo.hBmp = GetHIhB(GetParent(hWnd)); //Die Funktion gibt das im Nebenspeicher des Hauptfensters gespeicherte Bitmaphandle zurück FInfo.pmd = BMP; GetWindowRect(hWnd, &(FInfo.rect)); InvalidateRect(hWnd, &(FInfo.rect), TRUE); return 0; } else { FInfo.hBmp = NULL; FInfo.pmd = BRUSH; GetWindowRect(hWnd, &(FInfo.rect)); SetFInfo(hWnd, FInfo); InvalidateRect(hWnd, &(FInfo.rect), TRUE); return 0; }und hier nochmal die Paint Antwort des FeldProc:
case WM_PAINT: hdc = BeginPaint(hWnd, &ps); if(FInfo.pmd == BRUSH) { SelectObject(hdc, GetStockObject(WHITE_BRUSH)); Rectangle(hdc, FInfo.rect.left, FInfo.rect.top, FInfo.rect.right, FInfo.rect.bottom); } else { FInfo.cxBmp = GetHIcx(GetParent(hWnd)); FInfo.cyBmp = GetHIcy(GetParent(hWnd)); hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, FInfo.hBmp); StretchBlt(hdc, 0, 0, FInfo.cxBmp, FInfo.cyBmp, hdcMem, 0, 0, FInfo.cxBmp, FInfo.cyBmp, SRCCOPY); DeleteDC(hdcMem); } DeleteObject(FInfo.hBmp); EndPaint(hWnd, &ps); }
-
Index verschoben (sizeof(short) = 2, sizeof(int) = 4) :
int SetHInfo(HWND hWnd, HauptInfo HInfo) { SetWindowLong(hWnd, 0,(LONG) HInfo.pszFeldName); SetWindowWord(hWnd, sizeof(TCHAR*),(short) HInfo.idFocus); // SetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(int),(LONG) HInfo.hActiveBmp); SetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short),(LONG) HInfo.hActiveBmp); // SetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(int) + sizeof(HBITMAP),(LONG) HInfo.cxBmp); SetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short) + sizeof(HBITMAP),(LONG) HInfo.cxBmp); // SetWindowLong(hWnd, sizeof(TCHAR*) + 2*sizeof(int) + sizeof(HBITMAP),(LONG) HInfo.cyBmp); SetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short) + sizeof(HBITMAP) + sizeof(int),(LONG) HInfo.cyBmp); return 0; } int GetHInfo(HWND hWnd, HauptInfo &HInfo) { HInfo.pszFeldName = (TCHAR*) GetWindowLong(hWnd, 0); HInfo.idFocus = (short) GetWindowWord(hWnd, sizeof(TCHAR*)); HInfo.hActiveBmp = (HBITMAP) (GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short))); // HInfo.cxBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(int) + sizeof(HBITMAP)); HInfo.cxBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short) + sizeof(HBITMAP)); // HInfo.cyBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + 2*sizeof(int) + sizeof(HBITMAP)); HInfo.cyBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short) + sizeof(HBITMAP) + sizeof(int)); return 0; }
-
Wie hast du denn die Fensterklasse registriert?
Wenn du Get/SetWindowLong() für eigene Werte verwenden willst musst du auf jeden Fall WNDCLASS(EX)::cbWndExtra beim Aufruf von RegisterClass(Ex) entsprechend setzen.
-
jo, speicher hab ich vor der registrierrung schon reserviert, und zwar sizeof(HauptInfo) für das Hauptfenster und sizeof(FeldInfo für das Nebenfenster)
Argh - Index jetzt richtig, klappt immer noch nicht - alles bleibt weiß

-
Es gibt ein Problem in der Ablaufsteuerung :
// bei WM_CREATE des Haupt Proc // -------------------------------------- case WM_CREATE: ... // Bitmap Laden HInfo.hActiveBmp = LoadBitmap(hInstance, TEXT("bitmap")); // hier wird HInfo.hActiveBmp erzeugt ... SetHInfo(hWnd, HInfo); ... // bei WM_LBUTTONDOWN im FeldProc : // -------------------------------------- ... FInfo.hBmp = GetHIhB(GetParent(hWnd)); // hier wird HInfo.hActiveBmp FInfo.hBmp zugewiesen ... // die Paint Antwort des FeldProc : // -------------------------------------- case WM_PAINT: ... DeleteObject(FInfo.hBmp); // und hier wird FInfo.hBmp gelöscht ! ... // -> dadurch wird auch HInfo.hActiveBmp ungültig
-
hab die delete-sache aus WM_PAINT entfernt und dafür folgendes bei WM_DESTROY des Hauptfensters hinzugefügt:
case WM_DESTROY: // Bitmap löschen DeleteObject(HInfo.hActiveBmp); // aus dem Speicher auch SetHInfo(hWnd, HInfo); PostQuitMessage(0); return 0;immer noc halles weiß, ich fange an, an hohe brücken und fenster im 6ten stock zu denken ^^"""""""""""
-
Es gibt da immer noch ein Ablaufproblem.
Kommentiere mal das CreateWindow () der Child-Fenster aus und probiere, ob Du mit den Daten der HInfo (die bei WM_CREATE initialisiert wurde) auf dem Hauptfenster zeichnen kannst.
Falls die HInfo korrekt initialisiert ist, müsste das hier eine Bitmap zeichnen :
case WM_PAINT : { HDC hdc1,hdc2; hdc1 = GetDC (hWnd); hdc2 = CreateCompatibleDC (hdc1); SelectObject (hdc2,HInfo.hActiveBmp); BitBlt ( hdc1, // DEST 0,0, HInfo.cxBmp, HInfo.cyBmp, hdc2, // SOURCE 0,0, SRCCOPY ); DeleteDC (hdc2); ReleaseDC (hWnd,hdc1); }
-
aha - hier bleibts auch weiß. weiß aber trotzdem nicht, was genau ich falsch gemacht habe. Ich poste mal mein ganzen HauptProc:
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { // 25 Felder static HWND FeldHwnd[5][5]; static short idFocus = (short) GetWindowWord(hWnd, sizeof(TCHAR*)); // gebrauchte Variablen int x, y; TCHAR Text[10]; static HauptInfo HInfo; // Infos holen GetHInfo(hWnd, HInfo); BITMAP bitmap; HINSTANCE hInstance; switch(msg) { case WM_CREATE: // für Bitmap hInstance = ((LPCREATESTRUCT) lParam)->hInstance; //for(y = 0; y<5;y++) //for(x = 0; x<5;x++) //{ // FeldHwnd[x][y] = CreateWindow(HInfo.pszFeldName, // NULL, // WS_CHILDWINDOW | WS_VISIBLE, // 0,0,0,0, //braucht man nicht, da Werte bei Size gesetzt werden // hWnd, // (HMENU) (y << 8 | x), // (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE), // NULL); //} // Bitmap Laden HInfo.hActiveBmp = LoadBitmap(hInstance, TEXT("omfg")); GetObject(HInfo.hActiveBmp, sizeof(BITMAP), &bitmap); // für spätere Ausgabe HInfo.cxBmp = bitmap.bmWidth; HInfo.cyBmp = bitmap.bmHeight; // Infos speichern SetHInfo(hWnd, HInfo); return 0; case WM_SIZE: // Größe der Felder Festlegen for(y=0;y<5;y++) for(x=0;x<5;x++) { MoveWindow(FeldHwnd[x][y], LOWORD(lParam)/5 *x, HIWORD(lParam)/5 *y, LOWORD(lParam)/5, HIWORD(lParam)/5, TRUE); } return 0; case WM_LBUTTONDOWN: MessageBeep(0); return 0; case WM_SETFOCUS: // EingabeFokus auf das aktive Child Fenster übertragen SetFocus(GetDlgItem(hWnd, HInfo.idFocus)); return 0; case WM_PAINT : { HDC hdc1,hdc2; hdc1 = GetDC (hWnd); hdc2 = CreateCompatibleDC (hdc1); SelectObject (hdc2,HInfo.hActiveBmp); BitBlt ( hdc1, // DEST 0,0, HInfo.cxBmp, HInfo.cyBmp, hdc2, // SOURCE 0,0, SRCCOPY ); DeleteDC (hdc2); ReleaseDC (hWnd,hdc1); return 0; } case WM_DESTROY: // Bitmap löschen DeleteObject(HInfo.hActiveBmp); // aus dem Speicher auch SetHInfo(hWnd, HInfo); PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); }Ich mag zwar auch net vom Löffel gefüttert zu werden, aber irgendwie ist es manchmal unvermeidlich

-
// Ersetze Zeile 38 HInfo.hActiveBmp = LoadBitmap(hInstance, TEXT("omfg")); // mit HInfo.hActiveBmp = LoadBitmap(NULL,OBM_CHECKBOXES); // oder HInfo.hActiveBmp = LoadBitmap(NULL,OBM_CLOSE);Dann werden Bitmaps vom Betriebssystem geladen. So lässt sich testen, ob die Zeichenroutine ok ist.
Wenn diese gezeichnet werden, musst Du prüfen, ob es in Deinem Projekt eine Bitmap namens "omfg" überhaupt gibt.
-
.\main.cpp(112) : error C2065: 'OBM_CLOSE': nichtdeklarierter Bezeichner
da stimmt doch was nicht...
HInfo.hActiveBmp = LoadBitmap(NULL,MAKEINTRESOURCE(32754));
Zeichnet er aber
IDB_BITMAP1 BITMAP "omfg.bmp"was hiervon nimmt man: IDB_BITMAP oder "omfg.bmp"?
Oh, mist, so - ich start nochmal von neu, hat kein Sinn, hab noch selber einiges entdeckt: z.b dass die child Windows überhauptgarnicht erstellt werden. Und die Sache mit der Struktur im Zusatzspeicher klapt auch net richtig.... mache jetzt erstmal ein einziges Child Window und nehme mir globale Variablen, dann klappts hoffentlich >.<. Trotzdem vielen Dank für die Hilfe.
-
winuser.h schrieb:
...
#define OBM_CLOSE 32754
#define OBM_UPARROW 32753
#define OBM_DNARROW 32752
#define OBM_RGARROW 32751
...Huch, so geht es also auch. Immerhin, die Zeichenroutine läuft.
Azrael, il Meraz schrieb:
was hiervon nimmt man: IDB_BITMAP oder "omfg.bmp"?
Immer den Bezeicher ganz links. Unter diesem Namen ist die Bitmap dem Programm bekannt.
// also "IDB_BITMAP1" IDB_BITMAP1 BITMAP "omfg.bmp" // Jetzt habe ich das grade nicht im Kopf. // Entweder so : (als INTRESOURCE) HInfo.hActiveBmp = LoadBitmap(hInstance,IDB_BITMAP1); // Oder so : (als Name) HInfo.hActiveBmp = LoadBitmap(hInstance,"IDB_BITMAP1");
-
Ich würde GetHInfo(hWnd, HInfo); nicht bei jeder Funktion ausführen, sondern nur dann wenn Du sie wirklich brauchst.
-
Azrael, il Meraz schrieb:
Abgeholt wird die Information durch
int GetHInfo(HWND hWnd, HauptInfo &HInfo) { HInfo.pszFeldName = (TCHAR*) GetWindowLong(hWnd, 0); HInfo.idFocus = (short) GetWindowWord(hWnd, sizeof(TCHAR*)); HInfo.hActiveBmp = (HBITMAP) (GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(short))); HInfo.cxBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + sizeof(int) + sizeof(HBITMAP)); HInfo.cyBmp = (int) GetWindowLong(hWnd, sizeof(TCHAR*) + 2*sizeof(int) + sizeof(HBITMAP)); return 0; }Sag mal! Warum machst Du Dir das Leben so schwer und allokierst nicht einfach nur Platz für einen Zeiger in der Fensterklasse erzeugst mit new/malloc einen entsprechenden Speicherbereich auf den zu zugreifst. Das ist weitaus schneller als was Du hier machst.
-
hey, stimmt, danke. bei HInfo sollte es klappen. Aber bei - FInfo nicht - da muss ja jedes Fenster ihr eigenes Rechteck und Bitmap haben >.<. Bzw. - eigentlich kann man ja ein FInfo-array machen und den Fenstern jeweils ein Pointer geben. So - das war jetzt mal Schriftliches Denken
. Ich hab jetzt mal von neu angefangen. Müsst noch ein bissl warten, bis ich euch weiter nerven kann^^
-
Verstehe Dienen Einwurf nicht. Das gilt für ale Daten.
Erzeuge eineinen Speicherblock, wenn WM_NCCREATE ankommt. Speicher die Adresse dieses Blocks mit SetWindowLong im fensterlokalem Speicher.
Wan immer Du daten brauchst holst Du Dir nur den Zeiger mit GetWindowLong und arbeitest mit der Struktur.
Bei WM_NCDESTROY entsorgst Du den Speicher!Das ist die allgemeine Technik bei so etwas. Dann hat jede Fenster-Instanz seinen eigenen Speicherbereich.