Focus setzen

fujitsufan

Erfahrenes Mitglied
Hallo,
ich versuche in einem Dialog mit mehreren Steuerelementen (edit) das Steuerelement welches zuletzt editiert wurde, die Eingabe mit der Enter-Taste zu bestätigen.
Langer Satz!
Wie schaffe ich es, dass zu diesem Zeitpunkt kein anderer Button markiert ist?
Wenn ich den Cursor in eine Edit-Box setze, lege ich im Command Event den Focus auf das betreffende Steuerelement.
Code:
SetFocus(GetDlgItem(hDlg,Id));
Betätige ich aber anschließend die Enter-Taste, dann wird immer der OK-Button ausgeführt und der Dialog geschlossen.
So soll es nicht sein.
Ich möchte in diesem Zustand (ButtonDown der Enter-Taste) ermittlen welche Edit-Box den Focus besitzt, dann den Wert aus dieser Box übernehmen.
Gibt´s da noch was anderes außer dem Focus?

Vielen Dank!

fujitsufan
 
Hallo,

du kannst via PreTranslateMessage die Return-Taste abzufangen und dann prüfen, welches Control den Fokus hat:
C++:
BOOL MyDialog::PreTranslateMessage(MSG* pMsg)
{
    if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN )
    {    
        CWnd *pWndFocus = CWnd::GetFocus();
    
        if( pWndFocus == GetDlgItem(IDC_MYEDIT) )
        {
            // irgendwas tun
            return TRUE;
        }
        else if( pWndFocus == GetDlgItem(IDC_MYEDI2) )
        {
            // ...
            return TRUE
        }
        else ...
    }
    
    return CDialog::PreTranslateMessage(pMsg);
}
Gruß
MCoder
 
Hallo MCoder,

dass ich den Tastendruck abfangen uns auswerten muss ist mir klar, aber wie.
Die Methode "PreTranslateMessage() ist in meiner Dialogklasse nicht bekannt.
Muss ich diese im Header-File noch bekanntgeben?
Ich denke, selbst wenn ich den Tastendruck abfange kann ich nicht verhindern, dass
anschließend der "OK" Button (markiert) ausgefürt wird.

Viele Grüße
fujitsufan
 
Hallo fujitsufan,

der Eintrag im Header sieht so aus:
C++:
virtual BOOL PreTranslateMessage(MSG* pMsg);
Man kann diese Methode aber auch in der Klassenansicht beim Visual Studio hinzufügen: Klassenansicht öffnen -> Dialogklasse auswählen und Eigenschaften anzeigen lasen -> Im Eigenschaftfenster bei "Überschreibungen" suchen und hinzufügen.

Doch, du kannst damit verhindern, dass der Tastendruck weiter verarbeitet wird (das ist der Sinn von PreTranslateMessage).

Gruß
MCoder
 
Hallo MCoder,

befindest Du dich in der MFC-Umgebung oder C++?
CWnd ist doch eine Objekt aus der MFC Welt.

Ich habe jetzt folgendes gemacht:
HWND hwndFocus;
hwndFocus = GetFocus();

Compilieren (Strg+F7) geht, nur der Debugger startet nicht.

Die Fehlermeldung lautet:
Fehler 144 error LNK2001: Nicht aufgelöstes externes Symbol ""public: virtual int __thiscall TGlasDialoge::preTranslateMessage(struct tagMSG *)" (?PreTranslateMessage@TGlasDialoge@@UAEHPAUtagMSG@@@Z)". ttableau_glasdlg.obj WsTab

Fehlt mit noch ein CPP- bzw. Header- File.
Solche Fehler treten sonst auf wenn ich Funktionen einfüge, die in einem nicht bekannten CPP- bzw. Header- File stehen.

Vielen Dank!
fujitsufan
 
Hallo,

ja stimmt, das war vorher die MFC-Variante.
Für Win32 kannst du den Code in der Message-Loop des Dialogs unterbringen, etwa so:
C++:
while( GetMessage(&msg, NULL, 0, 0) )
{
    if( !TranslateAccelerator(msg.hwnd, hAccelTable, &msg) )
    {
        if( msg.message == WM_KEYDOWN && msg.wParam == VK_RETURN )
        {
            if( GetFocus() == GetDlgItem(hDlg, IDC_MYEDIT) )
            {
                // ...
                continue;
            }
            else if( GetFocus() == GetDlgItem(hDlg, IDC_MYEDIT2) )
            {
                // ...
                continue;
            }
        }
        
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
Gruß
MCoder
 
Hallo MCoder,

bin leider noch nicht zu gekommen es zu implementieren.
Bin an was anderem dran.
Trotzdem, vielen Dank!

Gruß
fujitsufan
 
Hallo MCoder,

bin wieder dran.

Ich habe jetzt diese Meldungsschleife drin.
Bei mir sieht die so aus:
Code:
BOOL FAR TDialog::MsgProc(HWND hWndDlg, UINT Message, WPARAM wParam, LPARAM lParam)
{
  switch(Message)
  {
    case WM_INITDIALOG:
      hDlg=hWndDlg;
      Setup();
      break;
    case WM_DESTROY:
      Destroy();
      break;
    case WM_CLOSE:
      PostMessage(hDlg,WM_COMMAND,IDCANCEL,0);
      break;
    case WM_NOTIFY:
      Notify(wParam, lParam);
      break;
    case WM_COMMAND:
      Command(id, cmd);
      break;
    case WM_KEYDOWN:
      Command(wParam,HIWORD(lParam));
      break;
  }
  return TRUE;
}

Alle Fälle funktionieren, nur in den case: WM_KEYDOWN wird beim Tastendruck nicht gesprungen.
Muss ich da noch was freischalten oder im Header freigeben?


Besten Dank!
fujitsufan
 
Hallo zusammen,

ich bins nochmal, fujitsufan.

Auch das Einbinden der Funktion "TranslateAccelerator(hWndDlg,hAccTable,(LPMSG)Message)" geht nicht.


Code:
HACCEL hAccTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCEL1));

if(!TranslateAccelerator(hWndDlg,hAccTable,(LPMSG)Message))
{
    if( Message == WM_KEYDOWN && wParam == VK_RETURN )
    {
    }

    TranslateMessage((MSG*)Message);
    DispatchMessage((MSG*)Message);
}

Die Tabelle "hAccTable" macht mir Sorgen.
Ich mache alles genau nach Microsoft Anweisung.
http://msdn.microsoft.com/de-de/library/windows/desktop/gg153544(v=vs.85).aspx

Meine Header:
Code:
#define IDR_ACCEL1                      101
#define ID_TOGGLE_MODE                40002
#define ID_DRAW_MODE                  40003
#define ID_SELECT_MODE                40004

Meine Ressourcendetei:
Code:
#ifndef RESOURCE_H
 #define RESOURCE_H
#include "resource.h"

IDR_ACCEL1 ACCELERATORS
{
    0x4D,   ID_TOGGLE_MODE, VIRTKEY, CONTROL    // ctrl-M
    0x70,   ID_DRAW_MODE, VIRTKEY               // F1
    0x71,   ID_SELECT_MODE, VIRTKEY             // F2
}
#endif

Die Präprozessoranweisung nur um den Error 1024 zu vermeiden.

Weitere Fehler:
1>c:\...\resource.h(1268) : error C2059: Syntaxfehler: 'Konstante'
1>c:\...\resource.h(1269) : error C2143: Syntaxfehler: Es fehlt ';' vor '{'
1>c:\...\resource.h(1269) : error C2447: '{': Funktionsheader fehlt - Parameterliste im alten Stil?

Was soll ich machen?
Es kann doch nicht sein, dass die einfachsten Dinge nicht gehen.


Vielen Dank!
fujitsufan
 
Alle Fälle funktionieren, nur in den case: WM_KEYDOWN wird beim Tastendruck nicht gesprungen.
Vermutlich wird die Message schon verarbeitet, bevor sie bei MsgProc aufschlägt. Was ist TDialog für eine Klasse und gibt es das eine Basisklasse?

Zu deinen Fehlermeldungen: Was steht in den Zeilen 1268 und 1269 der resource.h?

Gruß
MCoder
 
Zurück