Transparentes Eingabefeld

Thomasio

Erfahrenes Mitglied
Kann man, und wenn ja, dann wie, ein "edit" feld in einem Fenster vollkommen transparent machen, so dass nur der Cursor auf dem Fensterhintergrund blinkt?

Ich möchte dass der User glaubt er schreibt direkt ins Fenster, brauche aber trotzdem ein handle auf die Eingabe, damit ich die weiter verarbeiten kann

Ich hab schon überlegt, ein zweites "echtes" Eingabefeld ausserhalb vom sichtbaren Fensterbereich zu erstellen und den Inhalt bei jeder Eingabe mit einer WM_PAINT message ins Fenster kopieren, aber es wäre natürlich viel einfacher, wenn ein transparentes edit Feld machbar wäre
 
Hi,

also wenn dein Dialog eine feste Hintergrundfarbe hat, dann nimm dem Edit-Control den Rahmen weg und setze dessen Farbe in dem Eventhandler für WM_CTLCOLOR.

Code:
    HBRUSH hbr = NULL;
    if( nCtlColor == CTLCOLOR_EDIT ) {
        hbr = CreateSolidBrush(m_myBkgColor);
        pDC->SetBkMode(TRANSPARENT);
    }
    else {
        hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    }
    return hbr;

Bei dem Code werden allerdings alle Edit Controls Transparent.

Wenn du nur eines deiner Edit-Controls transparent machen möchtest, dann leite eine Klasse von CEdit ab und erledige das dann dort.

Wenn dein Hintergrund graphischer Natur ist (Bitmap, Farbverlauf...), ist es etwas komplizierter.
Dann kannste ja noch mal posten.

Gruß,

Peter
 
Man kann's bei OnCtlColor auch selektiv für ein Control machen:
C++:
// ...
if( pWnd->GetDlgCtrlID() == IDC_EDIT_IRGENDWAS )
{
    hbr = CreateSolidBrush(m_myBkgColor);
    pDC->SetBkMode(TRANSPARENT);
}
//...
Gruß
MCoder
 
Erstmal danke für die Antworten, das hilft schon mal einen Schritt weiter

Allerdings ist mein Hintergrund tatsächlich eine .bmp Grafik, sprich ich bräuchte die etwas kompliziertere Lösung
Dafür hat mein Fenster aber nur dieses eine Edit Control, ich muss also nicht selektieren (aber den Hinweis wie das geht merke ich mir auf jeden Fall trotzdem)
 
Ja hi,

also in dem Fall gehst du so vor:

Du hälst dir in deiner Klasse ein CBrush und ein CBitmap Objekt.

Code:
MyDialog.h

..
    CBrush  m_myBrush;
    CBitmap m_myBmp;
..


Dann gehst du in deiner OnEraseBkgnd-Funktion hin und initialisierst dir dein CBrush Objekt einmalig beim ersten zeichnen.

Code:
MyDialog.cpp

..
BOOL CMyDialog::OnEraseBkgnd(CDC* pDC)
{
    // Dein zeichencode

    if( !m_myBrush.GetSafeHandle() ) {
        //Das Brush ist noch nicht erzeugt, also machen wir es hier einmalig
        CRect editRc;
        // Position des Edit Controls auf dem Dialog ermitteln
        m_cEdit.GetWindowRect(&editRc);
        ScreenToClient(&editRc);
        CDC dc;
        dc.CreateCompatibleDC(pDC);
        // Du blittest dann genau den Ausschnitt, der hinter dem Edit Control liegt in deine Bitmap m_myBmp
        m_myBmp.CreateCompatibleBitmap(pDC,editRc.Width(),editRc.Height());
        CBitmap *pOldBitmap = dc.SelectObject(&m_myBmp);
        dc.BitBlt(0,0,editRc.Width(),editRc.Height(), pDC, editRc.left,editRc.top, SRCCOPY);
        dc.SelectObject(pOldBitmap);
        m_myBrush.CreatePatternBrush( &m_myBmp );
    }
    return 1;
}
..

Und in der Methode OnCtlColor gibst du das in OnEraseBkgnd erzeugte Pattern-Brush zurück.

Code:
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    
    HBRUSH hbr = NULL;
    if( nCtlColor == CTLCOLOR_EDIT ) {
        pDC->SelectObject( &m_myBrush );
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetBrushOrg( 0, 0 );
        return m_myBrush;
    }
    else {
        hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    }
    return hbr;
}

Weiterhin viel Erfolg,

Peter
 
Zuletzt bearbeitet:
Ei wei,

ich glaube ich brauche eine neue Definition für "etwas komplizierter" :eek:

Trotzdem vielen Dank, das gibt mir was zum knabbern und lernen, aber dazu mache ich das Ganze ja
 
Nachdem ich jetzt den halben Nachmittag damit verbracht habe, funktioniert das Ganze sogar, allerdings ist mir dabei etwas aufgefallen, nämlich, dass es im Prinzip viel einfacher sein müsste, zumindest in diesem Fall

Nachdem ich nur dieses eine edit Feld habe, an nur einer ganz bestimmten Stelle, auf immer dem gleichen Hintergrund, wäre es da nicht viel einfacher, wenn ich mir den ganzen Kram mit Hintergrund rauskopieren und wieder rein kopieren spare, schlicht den Ausschnitt aus dem Hintergrund als separates .bmp speichere und dieses direkt als Grafik für das edit Feld nehme?

Vermutlich schon einfacher, nur wie geht das dann wieder?
 
Genau das ist es doch was passiert.

Man kopiert sich einmal den Bitmapausschnitt raus und verwendet diesen als Hintergrund für das Edit Control.

Und da dies ja auch nur genau einmal passiert, frisst es weder Resourcen sonst noch was.

Du kannst dantürlich auch diesen Ausschnitt vorher definieren, als Resource in deinem Projekt ablegen und mit LoadBitmap laden.

Aber weniger Aufwand bedeutet dies sicher nicht, vor allem dann nicht, wenn du die Grafik auch mal austauschen willst.

Gruß,

Peter
 
Zurück