viele Probleme gelöst! wichtiges Lehrmuster
Sowas geht so:
Eine Fensterklasse aus Sicht der Windows API hat nichts mit
einer MFC Klasse (CWnd,CDialog…) zu tun.
Ja, dies ist bei all den Klassen manchmal schwer zu unterscheiden und kaum zu überschauen, da es in der Hilfe zu wenig ausführliche systematische Anleitungen gibt und die knappen Musterbeispiele schwer zu wünschen lassen.
Vielmehr wird damit der Typ eines Fensters gemeint.
Von Hause aus bringt Windows mehrere solcher Klassen/Typen mit
(z.b. Button,ListView usw.)
Du kannst dir die Fensterklasse (nochmal hat nichts mit einer
MFC Klasse zu tun!) mal mit SPY+ (ist beim VisualStudio dabei)
anschauen.
Dies war eine wichtige Hilfe, vor allem bei der wichtigen Aufgabe, das Problem zu lösen, dass meine neu kreierten Fenster trotz Spezifikation des aktuellen View-Objekts kein Parentfenster hatten, sondern nur das Hauptfenster der Anwendung als Owner. Dies war möglicherweise auch eine wichtiger Grund, warum ich die Aufgabe nicht auf andere Weise lösen konnte und alle Versuche versagten, ein Ereignis von einem Dialogfenster direkt in die aktuelle Dokumentendarstellungsinstanz durchzureichen.
Jede Fensterklasse hat ihre eigene (CaallBack) Funktion die
vom Betriebssystem zwecks bearbeitung von Nachrichten
angeknüpft wird.
Dies wusste ich schon. Trotzdem ist es nicht ganz einfach mit so einer neuen Klasse und es fehlte ein vollständiges Musterbeispiel ohne Stolpersteine. Weiter bleibt die Frage, ob so eine Funktion auch später nach dem Aufruf einer Fensterklasseninstanz noch irgendwie abgeändert und angepasst werden kann.
Du müsstest zur lösung deines Problems also eine eigene
Fensterklasse im System registrieren mit:
Dies hatte ich schon mal versucht, aber ohne eine neue WndProc-Funktion, eine sehr eigenartige Konstruktion. Leider lassen sich von dieser aus auch keine der üblichen nichtstatischen Memberfunktionen der anderen Klassenobjekte aufrufen, sondern nur Messages versenden, etwa durch SendMessage, so dass auch hier noch beträchtlicher Anpassungsaufwand erforderlich war.
//register and open process link window
WNDCLASS wc ;
TCHAR className[]=TEXT(GERALDFENSTERKLASSE);
TEXT funktionierte bei mir mit Studio 97 hier nicht, sondern nur „…“;
wc.lpszClassName = className ;
wc.hInstance = AfxGetApp()->m_hInstance;
//hier fragt sich, für was dies gut sein soll!
wc.lpfnWndProc = GeraldWndProc ;
wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
wc.hIcon = 0;//LoadIcon(m_hInst, IDI_APPLICATION) ;
wc.lpszMenuName = 0 ;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH) ;
besser zur freien Farbwahl etwa:
wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00d0ff) ;
Dies ist auch eine ganz kritische Funktion, deren Bedeutung schwer zu ermitteln ist. So fragt sich, wie man sonst bei einer aufgerufenen Instanz eines Klassenfensters die Hintergrundfarbe noch am problemlosesten ändern kann, falls dies überhaupt ohne große Umständlichkeiten möglich ist.
wc.style = CS_HREDRAW | CS_VREDRAW ;
wc.cbClsExtra = 0 ;
wc.cbWndExtra = 0 ;
if(!::RegisterClass(&wc))
{
AfxMessageBox(„error registering GRIDPROCESSLINKWND!\n“
„exitting application…“);
exit(0);
}
hier Problem bei wiederholtem Funktionsaufruf aufgetreten,
dann kein Abbruch angebracht;
Die GeraldWndProc ist dabei die Funktion die vom BS
angesprungen wird.
eine solche Funktion kann so aussehen:
//////////////////////////////////////////////////////////////////////////////
LONG FAR PASCAL GeraldWndProc(HWND hWnd, UINT Message, UINT
wParam, LONG lParam)
//////////////////////////////////////////////////////////////////////////////
{
if(Message==WM_COPYDATA)
{
//tu irgend was…
}
return DefWindowProc(hWnd,Message,wParam,lParam);
}
Am Schluss musst du noch ein Fenster dieser Klasse öffnen.
Das Parentfenster kann jetzt ein CDialog Fenster sein.
Das geht so:
m_hGeraldWnd= ::CreateWindow(
className,
className,
WS_POPUP,
//hier muss bei mir WS_VISIBLE|WS_BORDER|WS_CAPTION stehen;
0, 0,
320,200,
m_hWnd,//der parent ist dein Dialog!!!
//Diese Zuordnung ist nicht zuverlässig und eine Schwachstelle,
//die genau zu überprüfen ist, etwa auf Hauptfenster;
//so etwa für Zugriff auf richtiges Fenster folgendes wichtig:
/*
CMDIFrameWnd* whandle = (CMDIFrameWnd*) AfxGetMainWnd( );
CMDIChildWnd* chandle = whandle->MDIGetActive(NULL );
CBildverarbeitungView *vhandle = (CBildverarbeitungView *) chandle->GetActiveView();
SendMessage(vhandle->m_hWnd,WM_SWAP, 0, 0);
*/
NULL,
AfxGetApp()->m_hInstance,
NULL) ;
Du musst jetzt noch bei CreateWindow bzw. RegisterClass die
Parameter so setzen dass das erzeugte Fenster so aussieht wie
du möchtest (z.b. wie ein Button).
//Um hier das richtige funktionsfähige zu finden, war nochmals einiges an Experimenten nötig mit Suche der richtigen Typspezifikationsparameter.
Wenn du jetzt in irgend einem Modalen Dialog ein Fenster von
deinem Typ öffnest wird immer in die GeraldWndProc gesprungen,
dort kannst du dann alle deine Dialoge aktualisieren usw.
//leider nur über Umwege der Ermittlung von Fensterhandles und
SendMessage-Anweisungen!
Ich hoffe es war das was du gemeint hast, gruß Pauli!
Ja, dies ist im Wesentlichen das, was ich brauchte und nun auch einen gewissen Durchbruch brachte. Zuvor war es aber auch schon mit einigen Aufwand verbunden, überhaupt herauszufinden, dass es hierfür keine einfachere Alternative der Manipulation fertiger Instanzen der üblichen Klassen gibt.
Daher frage ich auch gerne, wodurch Sie hier so gut informiert sind oder wie Sie zu diesen detaillierten Erfahrungen gekommen sind. Dies ist mir leider trotz langem Wühlen durch den Wust der Windowshilfen und dürftigen Musterprogramme noch nicht so gut gelungen.
Und erst jetzt ist damit der Weg frei zu höchst funktionalen Programmen, wo zu jedem Bild einer Bildverarbeitung noch intelligente Kommandozeilenfenster nach Bedarf eingeblendet werden können. Leider unterstützt Microsoft wie auch die übliche Literatur solche sehr praktischen Lösungen so gut wie nicht, sondern führt den Systementwickler mit den aufwändigen unflexiblen Klassenhierarchiearchitekturen zu oft nur an der Nase herum. Dies gilt auch generell für den Bereich der Bildverarbeitung, wo so gut wie jeder Ansatz für einen Aufbau anspruchsvoller Anwendungen fehlt und der Umgang mit allen Eigenheiten von Bitmapstrukturen einschließlich schnellem effektivem Low-Level-Byte-Zugriff in einem zuverlässigen geschlossenem System vergeblich zu suchen ist.
ps. copy and paste vom VisualStudio hierhin geht nicht
gescheit, keine Farben, keine Formatierung, warum das? , wir
haben 2004! (Dies liegt am eigenartigen RichEdit-Textformat. Ähnliche Probleme sind besonders schlimm beim Abspeichern und Sichern von Mails aus Outlook-Express.)
Ich arbeite noch mit VisualStudio97, obwohl ich auf einem schnelleren Rechner die Edition von 2003 habe und vielleicht einige Neuigkeiten noch nicht kenne. Aber auch sonst könnte vieles noch besser sein, etwa zur Videoprogrammierung, wo bei der älteren Version leider noch jegliches Musterbeispiel fehlte und ich erst später ich auf diesen wichtigen Ansatz stieß. Microsoft bietet bis heute hier nicht mal eine Schnittfunktion. Ähnliches gilt für Systeme der räumlichen Objektmodellierung.
Danke
Gerald