Menu wird überdeckt



  • Hallo,

    ich habe ein ganz komisches Problem.
    Mein Hauptfenster hat oben ein Menu. Darunter ist ein Fenster (oder Bereich im Hauptfenster), das Text enthält und alle 100 ms oder so aktualisiert wird. Dort werden Daten angezeigt. Die Aktualisierung und das Neuschreiben ist wichtig.

    Wählt man ein Menupunkt aus, so klappt das Submenu nach unten und läge eigentlich über diesem Textfenster. Allerdings wird es durch diese Aktualiserung überschrieben.

    Liegen Menus also nicht mehr automatisch ganz oben? Ich dachte die liegen wie ein Fremdfenster über dem eigenen Fenster.

    Oder ist das ein Symptom eines Programmierfehlers?

    Gruß Thomas



  • Das ist wirklich merkwürdig...
    Kannst Du etwas Code posten?



  • ralros schrieb:

    Das ist wirklich merkwürdig...
    Kannst Du etwas Code posten?

    Schwierig. Weil extrem verteilt. Ich müsste erst mal ein Simples Projekt mit dem Fehler aufbauen.



  • Eigentlich dürfte das nicht passieren, wenn der "Device Context (hdc)", der "Richtige" ist...zb von "BeginPain()" geholt...dann wird nur in das Fenster geschrieben...wie ist Dein Programm zu dem HDC des Menüs gekommen? Hast Du ein "Owner-Draw-Menu"?



  • ralros schrieb:

    wie ist Dein Programm zu dem HDC des Menüs gekommen? Hast Du ein "Owner-Draw-Menu"?

    Das Menu ist Standard.

    //main menu
    if (!ParentMenu){
    HMenu = ::CreateMenu();
    return HMenu != 0;
    }
    //sub menu
    else{
    HMenu = ::CreatePopupMenu();

    ::InsertMenuItem(HMenu, ChildMenuItems.size() - 1, TRUE, &menuiteminfo);

    ::SetMenu(Hwnd, HMenu)

    Das darunter liegende Fenster ist ein Unterfenster des Hauptfenster und wird mit Invalidate()-Aufruf neu gemalt.
    In dessen Paint-Methode wird HDC mit BeginPaint geholt.

    //*********
    // PaintAll
    //*********
    void ttwin::TTInfofield::PaintAll(){
    
      PAINTSTRUCT ps;
      HDC hdc = ::BeginPaint(Hwnd, &ps);
    
      RECT rect;
      ::GetClientRect(Hwnd, &rect);
    
      const int DRAW_TEXT_BORDER_HOR = 5;
      const int DRAW_TEXT_BORDER_VER = 15;
    
      //----------- check if it is to drawn ------------
    
      //----------------- background -----------------
      //HBRUSH backgroundBrush = CreateSolidBrush(RGB(50, 50, 50));
      //FillRect(hdc, &Rect, backgroundBrush);
      //DeleteObject(backgroundBrush);
    
      //-------------- text area backgroud -----------
      HBRUSH textgroundBrush = ::CreateSolidBrush(RGB(0, 0, 0));
      rect.left += DRAW_TEXT_BORDER_HOR;
      rect.right -= DRAW_TEXT_BORDER_HOR;
      rect.top += DRAW_TEXT_BORDER_VER;
      rect.bottom -= DRAW_TEXT_BORDER_VER;
      ::FillRect(hdc, &rect, textgroundBrush);
      ::DeleteObject(textgroundBrush);
    
      //--------------- text area border ---------------------
    
      HPEN penBorder1  = ::CreatePen(PS_SOLID, 1, RGB(129, 129, 129));
      HPEN penBorder2  = ::CreatePen(PS_SOLID, 1, RGB( 74,  74,  74));
    

    ....



  • ist "Hwnd" nicht automatisch ein Member bei ::BeginPaint() und somit überladen?
    Leider kann ich Dir auch nicht weiterhelfen...zeit langem habe ich ein Programm, das auch in einem Intervall das Fenster neu zeichnet (bzw die veränderten Elemente), welches eine "primitive" Zeichenfläche benutzt, mit "TextOut()" usw. und da passiert das nicht...woran das jetzt liegt, kann ich nicht sagen...vielleicht stimmt doch etwas mit dem Menü nicht...welche Klassenbibliothek liegt da zugrunde...eine Selbstgeschriebene?
    Mit der C-API wäre das "durchsichtiger"...



  • Sorry, das "::" bedeutet ja, daß man eine externe C-Funktionen aufruft...
    Ich für meinen Teil programmiere mit C/API und C++/MFC und deshalb bin ich da jetzt etwas verwirrt gewesen :D.
    Das "Hwnd" muß aber doch eine Member-Variable sein und diese ist mit "m_hwnd", übersichtlicher deklariert.



  • ralros schrieb:

    Sorry, das "::" bedeutet ja, daß man eine externe C-Funktionen aufruft...

    Nein. Damit rufe ich meist die Win-Api-Funktionen auf, um mir deutlich zu machen, dass es die im globalen Namespace liegenden Win-Api-Funktionen sind. Keine Member meiner Klassenbibliothek, welche die Win-Api-Methoden kapselt.

    ralros schrieb:

    Das "Hwnd" muß aber doch eine Member-Variable sein und diese ist mit "m_hwnd", übersichtlicher deklariert.

    Iiiiiihhhh ... ungarische Notation ... 😉

    Im konkreten Fall spielt das aber keine Rolle, ich wollte nur die Funktionen erwähnen.

    Warum eigene Bibliothek sei kurz erklärt: die entstand als in Photoshop-Plugins entwickelte und kein QT nehmen konnte, MFC nicht in den Free-Versionen von Visual C++ enthalten war (und sowieso war Borland OWL viel besser ;-)) und ich selbstdesignte Controls haben wollte mit komplexen Verhalten.

    Womöglich ist da ein Hau drin. Aber um den zu finden, frage ich ja.

    Was übrigens auch komisch ist. Wenn ich mein Programm als Debug in Visual C++ Express starte bleibt das Fenster hartnäckig vorn. D.h. ich kann zwar andere Fenster in den Vordergrund holen, aber nicht Visual C++.
    Das scheint mir erst bei Win7 so zu sein.


  • Mod

    Menüs sind eigene Fenster und liegen über anderen Fenstern.
    Sofern die Handle stimmen dürfte das durch ein reguläres "WM_PAINT" HDC handle niemals passieren.



  • Martin Richter schrieb:

    Menüs sind eigene Fenster und liegen über anderen Fenstern.
    Sofern die Handle stimmen dürfte das durch ein reguläres "WM_PAINT" HDC handle niemals passieren.

    Dass das Menu überschrieben wird?



  • Ich überlege gerade, ob WS_CLIPCHILDREN oder WS_CLIPSIBLINGS evtl. beim Fenster fehlen könnten?


  • Mod

    geeky schrieb:

    Ich überlege gerade, ob WS_CLIPCHILDREN oder WS_CLIPSIBLINGS evtl. beim Fenster fehlen könnten?

    Nöö. Ein Menü oder solch ein Child ist weder Kind noch Sibling.



  • ThomasT schrieb:

    ralros schrieb:

    Sorry, das "::" bedeutet ja, daß man eine externe C-Funktionen aufruft...

    Nein. Damit rufe ich meist die Win-Api-Funktionen auf, um mir deutlich zu machen, dass es die im globalen Namespace liegenden Win-Api-Funktionen sind. Keine Member meiner Klassenbibliothek, welche die Win-Api-Methoden kapselt.

    ralros schrieb:

    Das "Hwnd" muß aber doch eine Member-Variable sein und diese ist mit "m_hwnd", übersichtlicher deklariert.

    Iiiiiihhhh ... ungarische Notation ... 😉

    Im konkreten Fall spielt das aber keine Rolle, ich wollte nur die Funktionen erwähnen.

    Warum eigene Bibliothek sei kurz erklärt: die entstand als in Photoshop-Plugins entwickelte und kein QT nehmen konnte, MFC nicht in den Free-Versionen von Visual C++ enthalten war (und sowieso war Borland OWL viel besser ;-)) und ich selbstdesignte Controls haben wollte mit komplexen Verhalten.

    Womöglich ist da ein Hau drin. Aber um den zu finden, frage ich ja.

    Was übrigens auch komisch ist. Wenn ich mein Programm als Debug in Visual C++ Express starte bleibt das Fenster hartnäckig vorn. D.h. ich kann zwar andere Fenster in den Vordergrund holen, aber nicht Visual C++.
    Das scheint mir erst bei Win7 so zu sein.

    Ja, das "::" bedeutet aber, wenn man eine externe API-Funktion aufruft, dann geschieht das immer in C-Notation...

    Ja, ungarische Notation ist immer noch die Beste 👍 - ich kann gar nicht anders 😃

    Ich würde wirklich sagen, es liegt an der selbstgeschriebene Klassenbibliothek. Der Bug dürfte tief versteckt in diesen liegen.
    Schreibe doch das Programm in C/API um und sehe dann was passiert...wie Martin Richter schon schrieb, dürfte das nicht passieren, wenn der richtige Device-Context angesprochen wird.

    Holla OWL...die möchte ich nie wirklich, damals programmierte ich ausschließlich in C, hatte aber "Turbo C++ 4.5" - Hach, das waren Zeiten. 🙂
    ...Aber die MFC sind für größere Projekte unvermeidbar...und ich mag Microsoft ♥ 😃



  • ralros schrieb:

    Ja, das "::" bedeutet aber, wenn man eine externe API-Funktion aufruft, dann geschieht das immer in C-Notation...

    Ich weiss nicht genau was du mit "in C-Notation" meinst.
    Das :: bedeutet nur dass man etwas aus dem globalen Namespace referenziert.
    Man kann auch ::SomeFunction(foo::bar<int>(), ()[]{ return 42; }) schreiben.



  • hustbaer schrieb:

    ralros schrieb:

    Ja, das "::" bedeutet aber, wenn man eine externe API-Funktion aufruft, dann geschieht das immer in C-Notation...

    Ich weiss nicht genau was du mit "in C-Notation" meinst.
    Das :: bedeutet nur dass man etwas aus dem globalen Namespace referenziert.
    Man kann auch ::SomeFunction(foo::bar<int>(), ()[]{ return 42; }) schreiben.

    Der "Global Namespace" ist aber in diesem Falle meistens eine API-Funktion und die ist immer noch in "C-Notation"...ich rufe immer noch manchmal ATL-Funktionen in C-Programmen auf (eigentlich nur, um mir das Leben nicht zu einfach zu machen :D)
    ein Beispiel:

    if (g_pITaskbarList)
    g_pITaskbarList->lpVtbl->SetProgressState(g_pITaskbarList, g_hWnd, TBPF_ERROR);
    

    Ich mag C und verwende C++/MFC nur in größeren Projekten, da man dann sich mit C/API die Finger wundcodiert 😃


Anmelden zum Antworten