Nachrichtenschleifen verlassen + focus setzen

HansJ

Mitglied
Hallo,
ich habe eine Hauptnachrichten Schleife und eine für ein Editfeld. Wenn ich nun in der Hauptnachrichten Schleife den focus in das Editfeld setze gelange ich in die Editfeld Schleife und bekomme auch Tastatureingaben. Nach der Entertaste wird wieder zur Hauptnachrichten Schleife gewechselt. Das funktioniert so weit, aber der Focus bleibt auf dem Editfeld und wenn ich versuche in der Editfeld Schleife den Focus auf ein anders Feld zulegen stürzt das Programm ab. In dem switch(uMsg) funktioniert es auch nicht da bleibt er in dem Editfeld.



Code:
LRESULT CALLBACK BasicScanProc(HWND,UINT,WPARAM,LPARAM);
WNDPROC pOldWndProc;	//Sicherungs Pointer

// Hauptnachrichten Schleife 
LRESULT CALLBACK BasicScanProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
    {	
case WM_INITDIALOG:
        // Handle vom Editfeld holen		
       hctl_zstand = GetDlgItem(hwnd,IDC_EDIT_STAND);

       // Den Pointer der Hauptnachrichtenschleife sichern
       pOldWndProc = (WNDPROC)SetWindowLong( hctl_zstand, GWL_WNDPROC, LONG_PTR)MyEditProc);
      ... 
      break;

case E_SCN_SUCCESS:	
       // Focus auf das Editfeld
       SetFocus(hctl_zstand);
break;
	
// Nachrichten Schleife Tasteneingabe Editfeld
LRESULT CALLBACK MyEditProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{	 
	switch (uMsg)	
	{
	case WM_KEYUP :

		if (wParam == VK_RETURN)	
		{	
			Edit_GetText(hctl_zstand, szEingabe,14);
		}
			
		break;
	}

	// Zurück zur Hauptnachrichten Schleife BasicScanProc
	return CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
}
 
Wo genau steht dieses:

case E_SCN_SUCCESS:
// Focus auf das Editfeld
SetFocus(hctl_zstand);
break;

denn drin, wenn nicht auf ein WM_COMMAND oder Ähnliches hin?
 
Need more input:

Was steht im switch zu case E_SCN_SUCCESS ?

Ich könnte mir vorstellen, dass da eine SetFocus-Endlosschleife ist: Du setzt den Fokus auf das Edit, das Edit setzt zurück, das Hauptfenster setzt den Fokus wieder usw.
 
Nach dem ich die Zeilen in
Code:
case WA_INACTIVE:
// ?     ctl_zbez = GetDlgItem(hwnd,IDC_EDIT_BEZ);
// ?	hctl_ben = GetDlgItem(hwnd,IDC_EDIT_BEN);
// ?	hctl_zbez = GetDlgIt
auskommentiert habe stürzt das Programm nicht mehr ab, warum weiß ich nicht.

Nach einer Eingabe in das Edit Feld hctl_zstand ist dieser Wert in szEingabe.

In dem Proagramm Ablauf bearbeite ich die vom Scanner kommenden Daten in "case E_SCN_SUCCESS:",
hier werden die Längen auffüllen usw. Dann setzte ich den Focus auf das
Edit Feld "hctl_zstand" und erhalte szEingabe, nach der Entertaste wird die MyEditProc verlassen.

So nun möchte ich die Eingaben des Edit Feld "hctl_zstand" mit den anderen Daten speichern, aber ich kann erst wieder etwas bearbeiten wenn gescannt wird und ich zu "case E_SCN_SUCCESS:" komme.

Gibt es hier einen Ansatz wie ich die Scanner Daten bearbeiten, den Wert des Edit Feld "hctl_zstand" bekomme und mit den übrigen Daten Speichen kann ?

Code:
#include <windows.h>
#include <windowsx.h>
#include <ScanCAPI.h>
#include "resource.h"
#include "audiocapi.h"
#include "keycheck.h"
#include "..\common\StdStrng.h"

#define		countof(x)		sizeof(x)/sizeof(x[0])
#define		DEFAULT_BEEPER_FREQUENCY	2600	
#define		DEFAULT_BEEPER_DURATION		1000

// Define user messages
enum tagUSERMSGS
{
	UM_SCAN	= WM_USER + 0x200,
	UM_STARTSCANNING,
	UM_STOPSCANNING
};

// Global variables
...

HWND			hctl_zbez, hctl_ben, hctl_zstand, hctl_Focus;

static TCHAR szMsg[MAX_PATH];
static LONG_PTR PrevWndProcEdit;

FILE *stream;

LRESULT CALLBACK BasicScanProc(HWND,UINT,WPARAM,LPARAM);

WNDPROC pOldWndProc;	//Sicherungs Pointer

void	ErrorExit(HWMD, UINT, LPTSTR);
LPTSTR	LoadMsg(UINT, LPTSTR, int);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpszCmdLine, int nCmdShow)
{
	int nResult;

	hInst = hInstance;		// save the instance handle to a global variable
	nResult = DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_SSCAN), NULL, 
						BasicScanProc);

	return nResult;
}

LRESULT CALLBACK MyEditProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{	// Nachrichten Schleife Tasteneingabe Zählerstand

	switch (uMsg)	
	{
	     case WM_KEYUP :
		if (wParam == VK_RETURN)	
		{	
			Edit_GetText(hctl_zstand, szEingabe,14);
			iTastenEing	= 1;
			SetFocus(hctl_Focus);  // Ist ein nicht sichtbares Editfeld 
		}
		break;
	}

	// Zurück zur Hauptnachrichten Schleife BasicScanProc
	return CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
}

// Hauptnachrichten Schleife 
LRESULT CALLBACK BasicScanProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	DWORD			dwResult;
	LPSCAN_BUFFER	lpScanBuf;

	SYSTEMTIME systime;

	switch(uMsg)
              {
                    case WM_INITDIALOG:
		hctl_Focus = GetDlgItem(hwnd,IDC_EDIT_FOCUS);
		// Handle vom Editfeld holen		
		hctl_zstand = GetDlgItem(hwnd,IDC_EDIT_STAND);

		// Den Pointer der Hauptnachrichtenschleife sichern
		pOldWndProc = (WNDPROC)SetWindowLong( hctl_zstand, GWL_WNDPROC, (LONG_PTR)MyEditProc);
			
		PostMessage(hwnd,UM_STARTSCANNING,0,0L);

		g_AudioInfo.szSound[0] = 0;
		g_AudioInfo.dwFrequency = DEFAULT_BEEPER_FREQUENCY;
		g_AudioInfo.dwDuration = DEFAULT_BEEPER_DURATION;
		AUDIO_SetBeeperVolume(dwVolume); 
		SI_INIT(&g_AudioVersion); 
 	        break;

   	        case UM_STARTSCANNING:
	        	...
		return TRUE;

	        case UM_STOPSCANNING:
		...
		return TRUE;
	
	       case WM_ACTIVATE:
		switch(LOWORD(wParam))
		{
			case WA_INACTIVE:
			// ?	hctl_zbez = GetDlgItem(hwnd,IDC_EDIT_BEZ);
			// ?	hctl_ben = GetDlgItem(hwnd,IDC_EDIT_BEN);
	 			...		
			default;			
			// ?	hctl_zbez = GetDlgItem(hwnd,IDC_EDIT_BEZ);
break;

			case UM_SCAN:
				hctl_zbez = GetDlgItem(hwnd,IDC_EDIT_BEZ);
				hctl_ben = GetDlgItem(hwnd,IDC_EDIT_BEN);
				
				if (bRequestPending)
				dwResult = SCAN_Flush(hScanner);
				// Do not set bRequestPending to FALSE until
				// we get the UM_SCAN message
				break;
	 		default:	// activating
			...
			break;
		}
		break;
		
		case E_SCN_SUCCESS:

// Hier läuft die Verabeitung und das Speichern der Scanndaten 

 		return TRUE;

		case WM_COMMAND:
			switch (LOWORD(wParam))
		 	{
			case IDOK:	// fall through
			case IDCANCEL:
 			  SendMessage(hwnd,UM_STOPSCANNING,0,0L);
			break;
			}
		return TRUE;
	}
	return FALSE;
}
 
Ich glaube, da gibt es noch ein Verständnisproblem:

Die MyEditProc wird andauernd aufgerufen, nicht nur wenn Enter kommt. Jede Nachricht (Maus,Tastatur,Focusänderung,usw.) an das Edit-Fenster geht zuerst durch deine MyEditProc und wird durch den CallwindowProc-Aufruf an die Original-Edit-Proc weitergegeben.

Wenn ich dich richtig verstanden habe, möchtest du, dass auf den Enter-Druck hin die Eingabe ausgelesen wird und danach irgendein Vorgang startet. Das Vorgang-starten müsstest du auch in die Enter-Tasten-Abfrage reinsetzen, da die MyEditProc danach immer noch weiter durchlaufen wird.
 
Ja richtig, verstehe ich diese Nachrichtenschleifen noch nicht richtig.

So wie ich es verstehe wird nach dem Programmstart immer die Hauptnachrichtenschleife durchlaufen und wenn ein Ereigniss z.B. WM_ACTIVATE eintritt können in diesem Abschnitt Arbeiten erledigt werden.
Tritt nun eine Focus Änderung ein, wird die MyEditProc durchlaufen und hier wieder auf Ereignisse reagiert. Danach wird wieder zur Hauptnachrichtenschleife gewechselt. Nun wird diese wieder durchlaufen.
Wie komme ich jetzt aber wieder an die Stelle zurück an der der Fokus auf das Editfeld gesetzt wurde um da hinter weiter zu arbeiten.
Oder kann ich ein Ereigniss erzeugen auf das dann in der Hauptnachrichtenschleife eragiert werden kann ?
 
Die Schleifen laufen andauern durch. Wenn du einen Fokus auf das Edit setzt, wird eine (oder evtl. mehrere) Nachricht durch die MyEditProc gejagt, danach ist dein Problem DIREKT an dem Punkt nach dem SetFocus.

Du kannst aber in der Edit ein Ereignis erzeugen, du könntest zum Beispiel eine selbst definierte Nachricht (WM_APP + einen Wert) an dein Hauptfenster posten und dort dann die Bearbeitung fortsetzen.

So in etwa:

Code:
case WM_KEYUP :

		if (wParam == VK_RETURN)	
		{	
			Edit_GetText(hctl_zstand, szEingabe,14);
PostMessage( WM_APP + 1, GetParent( hwnd ), 0, 0 );		}
			
		break;

Und innerhalb deiner BasicScanProc ein neues case aufmachen:

Code:
case WM_APP + 1:
  // Bearbeitung fortsetzen
  break;
 
Zurück