WndProc in Klasse... again >.<



  • Das Set/GetWindowLong () und die CREATESTRUCT brauchst Du nur, wenn die WndProc in einer Klasse ist.
    Allerdings ist sie das nicht. Deshalb reicht folgendes :

    // so übergeben :
    INT WINAPI WinMain (...) {
    ...
     MMMUSIC *mmm = new (MMMUSIC);
    ...
     CreateWindowEx (...,mmm);
    ...
     delete (mmm);
    ...
    }
    
    // so initialisieren :
    LRESULT WINAPI WndProc(...) {
    ...
     static MMMUSIC *mmm = 0;
    ...
      case WM_CREATE : {
       mmm = (MMMUSIC *) lParam;
       mmm -> InitDirectShow();
       break;
      }
    ...
    }
    


  • ne - geht auch nicht 😣 hab ausprobiert. aber eigentlich will ich das ja auch den WndProc in die klasse tun, hier ist halt nur ein anderes Beispiel. Ich vertseh überhauptnicht, wie das nicht klappen kann...



  • hmmm - ich hab mir jetzt ne eigene Message definiert, damit geht das Oo

    #define WM_MMMCR WM_USER
    ...
    hWnd = CreateWindowEx(...);
    SendMessage(hWnd, WM_MMMCR, NULL, (LONG) mmm);
    ....
    case WM_MMMCR:
    		mmm = (MMMUSIC*) lParam;
    		mmm->InitDirectShow();
    		break;
    ...
    

    total krank, ich glaub, ich fass die WM_CREATE net mehr an...

    mal schaun, ob das auch mit SetWindowLong klappt und den member-wndproc...



  • Such lieber eine geeignete Stelle, wo "mmm->InitDirectShow()" aufgerufen wird.
    Vielleicht gleich nach CreateWindowEx () in der WinMain :

    // hier rein :
    WinMain (...)
    ...
    CreateWindowEx (...,mmm);
    mmm -> InitDirectShow();
    ...
    
    // hier raus :
    WndProc (...)
    ...
     case WM_CREATE : {
        mmm = (MMMUSIC *) lParam;
    //    mmm -> InitDirectShow();
        break;
       }
    ...
    


  • ne - klappt nicht - der zeiger ist wieder verwirrt...

    Ist die Lösung mit eigener Nachricht irgendwie schlechter Stil?



  • merker schrieb:

    case WM_CREATE:
        mmm = (MMMUSIC *)lParam;
        break;
    

    Win32 Programmer's Reference schrieb:

    WM_CREATE

    lParam

    Value of lParam. Points to a CREATESTRUCT structure that contains information about the window being created.

    Ich hab das Problem in C auch mal gehabt...



  • Ahhh, Dank an "keksekekse" für den Hinweis 🙂

    Funktioniert folgendes Casting :

    WinProc (...)
    ...
     case WM_CREATE : {
    //  mmm = (MMMUSIC *) lParam;
      mmm = (MMUSIC *) ((LPCREATESTRUCT) lParam) -> lpCreateParams;
      mmm -> InitDirectShow();
      break;
     }
    

    P.S.: Eigene Nachrichten sind kein schlechter Stil.



  • ne - immer noch verwirrter zeiger.

    Was spricht dann gegen ne eigene Nachricht?



  • Nichts spricht gegen die eigene Nachricht. Das ist auch eine schöne und saubere Lösung.
    Schliesslich geht es nur darum, einen in der WinMain erzeugten Zeiger zu übergeben.

    Mich verwirrt jetzt nur, warum der Zeiger nicht via "CreateWindowEx (..., mmm)" und WM_CREATE mit "mmm = (MMUSIC 😉 ((LPCREATESTRUCT) lParam) -> lpCreateParams" korrekt übergeben werden konnte.

    Aber das muss jetzt nicht das Problem sein 🙂



  • Also bei mir funktioniert der Code einwandfrei. Schau doch mal, per debugging printf(xyz) was genau bei Dir mit WM_CREATE ankommt. Mein Verdacht ist dahingehend, daß Klassenvariablen dynamisch sind oder so. Neue Idee: Ich versuchs mal auch mit ner c++-Klasse.

    #include <windows.h>
    #include <stdio.h>
    
    long _stdcall WndProc(HWND hwnd, unsigned int message, unsigned int wParam,
                                                                       long lParam)
    {
      HDC hdc;
      PAINTSTRUCT ps;
      CREATESTRUCT *lpcs;
      static long iAABBCCDD;
      char o[1000];
    
      switch(message)
    	{ case WM_CREATE:
    		  lpcs = (CREATESTRUCT *)lParam;
    		  iAABBCCDD = (long)(lpcs->lpCreateParams);
    		  return 0;
    	  case WM_PAINT:
    	      hdc = BeginPaint(hwnd, &ps);
    		  _snprintf(o, sizeof(o), "0x%08lX", iAABBCCDD);
              TextOut(hdc, 10, 10, o, strlen(o));
    		  EndPaint(hwnd, &ps);
    	      return 0;
    	  case WM_DESTROY:
    		  PostQuitMessage(0);
        }
      return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                                                     char *szCmdLine, int iCmdShow)
    {
      HWND hwnd;
      MSG msg;
      WNDCLASS wc;
    
      ZeroMemory(&wc, sizeof(WNDCLASS));
      wc.style         = CS_HREDRAW | CS_VREDRAW;
      wc.lpfnWndProc   = WndProc;
      wc.hInstance     = hInstance;
      wc.hIcon         = LoadIcon(0, IDI_INFORMATION);
      wc.hCursor       = LoadCursor(0, IDC_ARROW);
      wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
      wc.lpszClassName = "mbclass";
      RegisterClass(&wc);
    
      hwnd = CreateWindow("mbclass", "Titel", WS_OVERLAPPEDWINDOW,
    					  CW_USEDEFAULT, CW_USEDEFAULT,
    					  CW_USEDEFAULT, CW_USEDEFAULT,
    					  0, 0, hInstance, (void *)0xAABBCCDD);
      ShowWindow(hwnd, iCmdShow);
      UpdateWindow(hwnd);
    
      while(GetMessage(&msg, 0, 0, 0) > 0)
          DispatchMessage(&msg);
    
      return msg.wParam;
    }
    


  • Ich hab noch eine Idee: Ist die Struktur MMM, deren Zeiger Du übergibst, denn auch nicht "flüchtig", d.h. wird sie freigegeben, nach dem der Zeiger übergeben ist? Das könnte vieles erklären.



  • der code funktioniert bei mir Oo.. aber in meinem fall hatte sich der zeiger am ende ja auch nicht verändert - nur die daten der struktur.... und ne - die mmm wird erst nach der Messageschleife freigegeben



  • Läuft's nun oder nicht ?



  • mit CreateWindowEx() -> nein
    mit eigener nachricht ja

    der zeiger auf die instanz bleibt mit WM_CREATE richtig, aber die daten der instanz werden zerwürfelt



  • Dann kann das ja mit der eigenen Nachricht so bleiben. Schliesslich wird mit der Instanz von mmm erst gearbeitet, wenn das Hauptfenster "fertig" ist.
    Bleibt wohl ein offenes Rätsel, warum es mit CreateWindowEx () und WM_CREATE nicht geht. Mit dem this-pointer funktionierte das ja auch problemlos.


Anmelden zum Antworten