MDI und Callback Funktion
-
Hab' noch was vergessen:
case WM_DESTROY: pMDData = (PMDDATA) GetWindowLong (hwnd, 0); HeapFree (GetProcessHeap (), 0, pMDData);Die Types
CSBAR sbMD;
CTABC tcMD;
CREDIT reMD;sind Klassen, die alle Methoden fuer die Controls enthalten, z.B.: fuer die Statusbar
CSBAR::CSBAR (HWND hwnd, int iFields) { if (!hwnd) return; m_hwnd = hwnd; m_iFields = iFields; m_hwndSbar = InitSBar (); };Hier wird das Handle der Instanz (eines Clients) an die Statusbar uebergeben:
pMDData->sbMD.Init (hwnd, NUM_FIELDS); // VARIANTE 1Blackbird
-
[quote]wie stellst du dir eine umwandlung von einer INTEGER ZAHL in eine HINSTANCE vor? mein compiler macht da nicht mit. [/quote]
Hast Recht, war ein bißchen zu sehr aus dem Bauch geschossen
-
AN BLACKBIRD:
also ich muss leider sagen, dass ich nichts verstehe von dem, was du schreibst. hab auch irgendwie das gefühl, dass das nicht so zu meiner frage passt (?). weiss zum beispiel gar nicht, wozu ich WM_SIZE und so brauche und was die klassen der statusbar mit meinem problem zu tun haben.
mein problem ist einfach so, dass ich ein MAIN MDI WINDOW habe, mit ner TOOLBAR. wenn ich auf den button drücke, kommt ein OpenGL window, das ein CHILD WINDOW ist. in der CALLBACK FUNKTION für dieses child fenster steht, dass beim drücken von F1 eingezoomt wird. nun soll dieses zoomen aber immer nur beim aktiven fenster erfolgen, nicht bei allen OpenGl-fenstern. man müsste also auch irgendwie abfragen, welches fenster gerade aktiv ist.
DANKE schonmal, falls du noch irgendwelche ideen hast.
STICK.
-
Deine Callback-Funktion hat eine WM_CREATE case-Falle?
Wenn ja, dann muss dort das Handle (als Parameter HWND hwnd im Funktionsaufruf) dieser Instanz gespeichert werden. Und zwar in einem eigenen Speicherbereich:// Platz für individuelle Daten pMDData = (PMDDATA) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof (MDDATA));Die Struct pMMDDate ist hier nur Beispiel, sie kann auch aus nur einem Element (dem Handle) bestehen.
Mit
SetWindowLong (hwnd, 0, (long) pMDData); pMDData->sbMD.Init (hwnd, NUM_FIELDS); // VARIANTE 1wird das Handle gespeichert, hier fuer eine Statusbar. Dann nochmals fuer ein Tab-Feld und ein Edit-Fenster. Ist hier nur ein Beispiel. Das kannst Du natuerlich viel einfacher machen.
Einfach nur das Handle speichern.In Deinem Code in der case-Falle WM_COMMAND wird irgendwo die F1-Taste verarbeitet. Dort muss alles was Deine Instanz betrifft (zoomen), mit genau diesem Handle passieren. Und das holt man sich so, wie ich es in WM_SIZE gezeigt habe (zuerst die struct, darin ist das Handle):
case WM_SIZE: pMDData = (PMDDATA) GetWindowLong (hwnd, 0);Der restliche Code zeigt nur beispielhaft, wie es geht.
Den Speicherbereich immer freigeben, wenn die Instanz des Childs zerstoert wird.Blackbird
-
SERVUS.
habe in meinem programm folgendes hinzugefügt, klappt aber leider immer noch nicht. vielleicht kann jemand den grund für folgende fehlermeldung finden:
"error C2228: Der linke Teil von '.Init' muss eine Klasse/Struktur/Union sein"global:
typedef struct tagMDDATA { HWND hTab; } MDDATA, *PMDDATA;am anfang der Callbackfunktion habe ich folgende variable definiert:
PMDDATA pMDData;WM_CREATE:
pMDData = (PMDDATA) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof (MDDATA)); SetWindowLong (hWnd, 0, (long) pMDData); pMDData->hTab.Init (hWnd);WM_SIZE:
pMDData = (PMDDATA) GetWindowLong (hWnd, 0);WM_CLOSE:
pMDData = (PMDDATA) GetWindowLong (hWnd, 0); HeapFree (GetProcessHeap (), 0, pMDData);DANKE schonmal.
STICK.
-
Du weißt inzwischen, ich bin auch Anfänger
Aber hast Du es schon mal mit
cbWndExtra versucht?[quote]
Specifies the number of extra bytes to allocate following the window instance. The operating system initializes the bytes to zero. If an application uses the WNDCLASS structure to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA. [/quote]
Also, den Status des Fensters in WndClassExtra speichern... ist halt so ne Idee...
-
Statt
pMDData->hTab.Init (hWnd);einfach nur
pMDData->hTab = hWnd;Weil: Deine Struct MDData enthaelt keine Klasse (wie in meinem Beispiel), sondern nur das Handle.
Und wenn die F1-Taste verarbeitet wird, musst Du das gespeicherte Handle auch verwenden:
case WM_KEYDOWN: pMDData = (PMDDATA) GetWindowLong (hWnd, 0); if (pMDData->hTab == (HWND)lParam && VK_F1 == wParam) { MessageBox (pMDData->hTab, "F1 down", "Eingabebox", MB_OK); // nur Beispiel! } ...Wo die F1-Taste abgefangen wird; das kann bei Dir auch anders aussehen.
Blackbird
-
SERVUS BLACKBIRD.
danke für die antwort. ich werde deine hinweise mit einbauen und sag dann bescheid, ob alles funktioniert hat.
STICK.
-
HALLO.
ich hatte vor einer weile (23.01.2006) dieses problem mit MDI und verschiedenen CALLBACK FUNKTIONEN gepostet.
leider bin ich seit dem nicht mehr dazu gekommen, das zu ende zu bringen. darum wollte ich jetzt noch einmal nachfragen, ob mir noch jemand helfen kann??

ich habe immer noch das problem, dass ich nicht weis, wie ich das gespeicherte HANDLE für meine verschiedenen CALLBACK FUNKTIONEN wieder verwenden kann. ich habe es jetzt am beispiel der F1 taste so gemacht, aber wenn ich F1 betätige, dann stürzt das program ab.
case WM_KEYDOWN: { pMDData = (PMDDATA) GetWindowLong (hWnd, 0); if (pMDData->hTab == (HWND)lParam && PAD[wParam] == TRUE) MessageBox (pMDData->hTab, "F1 down", "Eingabebox", MB_OK); return 0; }DANKE.

STICK.
-
An welcher Stelle genau stürzt er denn ab?
-
das programm macht nicht mehr weiter, wenn ich auf F1 drücke.
STICK.

-
PAD[wParam]das dürfte in einen Speicherbereich zeigen, der nicht zu Deinem Prozess gehört.
Blackbird
-
Du drückst dich nicht gerade präzise aus. Wie genau sieht der Fehler aus? Zugriffsverletzung? Wenn ja, wo tritt diese auf (in welcher Zeile)?
-
ja. hast ja recht, damit kann man als aussenstehender ohne quellcode vor augen nicht viel anfangen. darum hier jetzt mehr informationen:
fehlermeldung:
unbehandelte ausnahme in api6.exe: 0*C000000005 access violation
an folgender stelle:
if (pMDData->hTab == (HWND)lParam && PAD[wParam] == TRUE)
dazu muss ich aber sagen, dass ich zuvor, also bevor ich die callbackfunktion angenfangen habe zu verändern für viele childwindows, folgenden code hatte und da gab es keine access violation meldung bei F1 betätigung. soll heissen, dass es da keine problem mit dem speicherzugriff geben müsste.
case WM_KEYDOWN: { PAD[wParam] == TRUE; return 0; }okay. lasst mich bitte wissen, wenn ihr noch mehr infos zu meinem code braucht.
DANKE!STICK

-
Hast du mal pMDData->hTab == (HWND)lParam oder PAD[wParam] == TRUE weggelassen`- dann sollte ja zumindest in einem Fall die Fehlermeldung ja weg sein.
PAD[wParam] == TRUE;Was soll das tun

-
Hast du mal pMDData->hTab == (HWND)lParam oder PAD[wParam] == TRUE weggelassen`
JA. das habe ich gerade gemacht. die fehlermeldung verschwindet dann auch. aber das problem ist dann, dass natürlich bei einer betätigung der F1 taste kein zoomen mehr ermöglicht wird. denn in einer while schleife, die u.a. auch meine OpenGL scene zeichnet, befindet sich auch folgender code:
if (PAD[VK_F1]) zoom +=0.2f; if (PAD[VK_F2]) zoom -=0.2f;was soll ich denn nun machen?
STICK.
-
Ich hatte eigentlich nicht gemeint, dass du das ganz weglässt, sondern wollte nur den Fehler einschränken, also ob es an
pMDData->hTab == (HWND)lParamoder an
PAD[wParam] == TRUEliegt....
Aber ich denke, dass am ehesten PAD[wParam] den Fehler verursacht, also dass wParam vielleicht manchmal ein ungültiger Index ist
Du kannst ja mal über den Debugger schauen, ob es bei jedem WM_KEYDOWN dort abstürzt und was für Werte die einzelnen Variablen dort haben...
-
HALLO.
ich habe nun deinen ratschlag befolgt und herausgefunden, wo der fehler liegt. deine vermutung, dass es dabei an PAD[wParam] == TRUE liegt, hat sich nicht bestätigt. wenn ich nur diesen befehl in der if-bedingung lasse, stürzt das programm nicht mehr ab, führt aber auch nicht die gewünschte ZOOM funktion aus.
bleibt nur pMDData->hTab == (HWND)lParam in der if-bedingung, dann stürzt das programm ab und gibt wieder die FEHLERMELDUNG "unbehandelte ausnahme etc.".
über den wert von "pMDData->hTab" wird gesagt:CXX0017: FEHLER: Symbol "" nicht gefunden.
ich kann damit aber leider nicht so viel anfangen.

STICK.
-
pMDData = (PMDDATA) GetWindowLong (hWnd, 0);Bekommst du hier was gültiges zurück?!
-
wenn ich mir den wert von "pMDData" anschaue, nachdem ich F1 gedrückt habe, wird folgendes ausgegeben:
Name: Wert: pMDData 0x000000000 -hTab CXX0030: Fehler: Ausdruck kann nicht ausgewertet werdenSTICK.