Code:
#include <windows.h>
#include <process.h>
#include <stdio.h>
#define ID_BUTTON_START 1
#define ID_BUTTON_ENDE 2
#define ID_LIST 3
#define ID_TEXT 4
#define RT_RECHTS 1
#define RT_HOCH 2
#define RT_LINKS 3
#define RT_RUNTER 4
#define MAX 3000 //Anzahl der Kartenelementen
#define Start_Punkt 200
static HWND phwndList, hwndHauptfenster, hwndButtonStart, hwndParent;
static int anzahl = 0; //Anzahl der Listenelemente der ListBox
LONG_PTR PrevWndProcEdit;
short Karte[MAX][MAX] = {0}; //[Reihe waagrecht][Spalte Senkrecht]
//Variablen für Com-Schnittstelle
HANDLE hCom;
DCB dcb;
DWORD iBytesWritten, iEvent; //unsigned int
int iAsRichtung, iAsPosition[2] = { Start_Punkt, Start_Punkt}, iAsSchritte, i, j;
RECT rect;
//Variblen für Thread
HANDLE hThread;
DWORD iExitCode;
//Asuro Nachrichten
unsigned char pcMsg[20]; // Nachrichten Puffer
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProcEdit(HWND, UINT, WPARAM, LPARAM);
VOID Thread(PVOID);
void ListBoxAusgabe(char *);
int Init_Com_Schnittstelle();
int Suchen_Umgebung(void);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Environ");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
RegisterClass(&wndclass);
hwnd = CreateWindow(szAppName, TEXT("Asuro Interface"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(GetExitCodeThread(hThread, &iExitCode) != 0)
if(TerminateThread(hThread, iExitCode) != 0)
ListBoxAusgabe("Thread beendet...");
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndEdit, hwndList, hwndButtonEnde;
static int cxChar, cyChar;
static int cxClient, cyClient;
HDC hdc;
PAINTSTRUCT ps;
int groese = 0;
hwndParent = hwnd;
switch(message)
{
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
SetWindowPos(hwndList, HWND_TOP, cxChar * 3, cyChar * 10, cxChar * 52, cyChar * (int)((cyClient - cyChar * 10 - 10) /cyChar), SWP_SHOWWINDOW);
SendMessage(hwndList, LB_SETCURSEL, (WPARAM)anzahl, 0); //Sorgt dafür das Listbox das letzte Element anzeigt
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SetViewportOrgEx(hdc, cxChar * 58 + 10 , cyChar * 3 + 10, 0);
MoveToEx(hdc, -10 , -10, NULL);
LineTo(hdc, -10, cyClient - 20 - cyChar * 3 - 10);
LineTo(hdc, cxClient - 20 - cxChar * 58 - 10 , cyClient - 20 - cyChar * 3 - 10);
LineTo(hdc, cxClient - 20 - cxChar * 58 - 10, - 10);
LineTo(hdc, -10, -10);
for(i = 0; i < cyClient - 20 - cyChar * 3; i++)
for (j = 0; j < cxClient - 20 - cxChar * 58; j++)
{
switch(Karte[i][j])
{
case 1:
SetPixel(hdc, j, i, (COLORREF) RGB(0, 0, 0));
break;
case 2:
SelectObject(hdc, GetStockObject(NULL_PEN));
SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
Ellipse(hdc, j - 3, i - 3, j + 3, i + 3);
}
}
SelectObject(hdc, GetStockObject(NULL_PEN));
SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
Ellipse(hdc, iAsPosition[1] - 5, iAsPosition[0] - 5, iAsPosition[1] + 5, iAsPosition[0] + 5);
EndPaint(hwnd, &ps);
rect.top = 0;
rect.right = cxClient;
rect.bottom = cyClient;
rect.left = 0;
return 0;
case WM_CREATE:
cxChar = LOWORD(GetDialogBaseUnits());
cyChar = HIWORD(GetDialogBaseUnits());
hwndButtonStart = CreateWindow(TEXT("button"), "Start",
WS_CHILD | WS_VISIBLE | BS_CENTER,
cxChar * 3, cyChar * 3,
cxChar * 20,
cyChar * 3,
hwnd, (HMENU) ID_BUTTON_START,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
hwndButtonEnde = CreateWindow(TEXT("button"), "Ende",
WS_CHILD | WS_VISIBLE | BS_CENTER,
cxChar * 25, cyChar * 3,
cxChar * 20,
cyChar * 3,
hwnd, (HMENU) ID_BUTTON_ENDE,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
hwndEdit = CreateWindow(TEXT("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_WANTRETURN,
cxChar * 3, cyChar * 8,
cxChar * 52,
cyChar,
hwnd, (HMENU) ID_LIST,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
PrevWndProcEdit = SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR) ChildProcEdit); //Editfenster bekommt eigene Message-Klasse um Enter abzufangen
hwndList = CreateWindow(TEXT("listbox"), NULL,
WS_CHILD | WS_BORDER | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | WS_BORDER,
cxChar * 3, cyChar * 10,
cxChar * 52,
0, //Größe wird bei WM_SIZE eingstellt
hwnd, (HMENU) ID_TEXT,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
phwndList = hwndList;
return 0;
case WM_COMMAND:
if(HIWORD(wParam) == BN_CLICKED) {
switch(LOWORD(wParam))
{
case ID_BUTTON_START:
hwndHauptfenster = hwnd;
SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
hThread = _beginthread(Thread, 0, NULL);
EnableWindow(hwndButtonStart, FALSE);
return 0;
case ID_BUTTON_ENDE:
if(GetExitCodeThread(hThread, &iExitCode) != 0)
if(TerminateThread(hThread, iExitCode) != 0)
ListBoxAusgabe("Thread beendet...");
if(hCom != NULL)
{
CloseHandle(hCom);
hCom = NULL;
}
EnableWindow(hwndButtonStart, TRUE);
return 0;
}
}
return 0;
case WM_SETFOCUS:
SetFocus(hwndEdit);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildProcEdit(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR befehl[40];
switch(message)
{
case WM_KEYDOWN:
switch(wParam)
{
case VK_RETURN:
GetWindowText(hwnd, befehl, 39);
if(befehl[0] != '\0') {
if(strncmp(befehl, "start", 5) == 0 || strncmp(befehl, "Start", 5) == 0 || strncmp(befehl, "START", 5) == 0)
{
SendMessage(hwndParent, WM_COMMAND, (WPARAM) MAKEWPARAM(ID_BUTTON_START, BN_CLICKED), 0);
SetWindowText(hwnd, "");
//anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) befehl);
//SendMessage(phwndList, LB_SETCURSEL, (WPARAM)anzahl, 0);
}
else if(strncmp(befehl, "ende", 4) == 0 || strncmp(befehl, "Ende", 4) == 0 || strncmp(befehl, "ENDE", 4) == 0)
{
SendMessage(hwndParent, WM_COMMAND, (WPARAM) MAKEWPARAM(ID_BUTTON_ENDE, BN_CLICKED), 0);
SetWindowText(hwnd, "");
//anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) befehl);
//SendMessage(phwndList, LB_SETCURSEL, (WPARAM)anzahl, 0);
}
else if(strncmp(befehl, "beenden", 7) == 0 || strncmp(befehl, "Beenden", 7) == 0 || strncmp(befehl, "BEENDEN", 7) == 0
|| strncmp(befehl, "exit", 4) == 0 || strncmp(befehl, "Exit", 4) == 0 || strncmp(befehl, "EXIT", 4) == 0)
{
SendMessage(hwndParent, WM_DESTROY, 0, 0);
}
else
{
anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) "Falsche Eingabe");
SendMessage(phwndList, LB_SETCURSEL, (WPARAM)anzahl, 0);
SetWindowText(hwnd, "");
}
}
return 1;
}
return 1;
}
return CallWindowProc((WNDPROC) PrevWndProcEdit, hwnd, message, wParam, lParam);
}
void ListBoxAusgabe(char *text)
{
anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) text);
SendMessage(phwndList, LB_SETCURSEL, (WPARAM) anzahl, 0);
}
int Init_Com_Schnittstelle(void)
{
int fehler;
GetLastError(); //Errorpuffer leeren
hCom = CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
fehler = GetLastError();
if(fehler == ERROR_FILE_NOT_FOUND) //Gerät ist nicht angeschlossen
{
ListBoxAusgabe("Gerät nicht gefunden... (angeschlossen?)");
if(hCom != 0)
{
CloseHandle(hCom);
hCom = 0;
}
return 1;
}
else if(fehler == ERROR_ACCESS_DENIED) //Gerät wird von einem anderen Programm benutzt
{
ListBoxAusgabe("Gerät wird schon benutzt...");
if(hCom != 0)
{
CloseHandle(hCom);
hCom = 0;
}
return 1;
}
else if(fehler != 0) //Abfangen anderer Fehler
{
ListBoxAusgabe("Fehler...");
if(hCom != 0)
{
CloseHandle(hCom);
hCom = 0;
}
return 1;
}
dcb.DCBlength = sizeof(DCB);
GetCommState(hCom, &dcb);
dcb.BaudRate = 2400;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fOutX = 0;
dcb.fInX = 0;
SetCommState(hCom, &dcb);
SetCommMask(hCom, EV_RXCHAR);
return 0;
}
VOID Thread(PVOID pvoid)
{
int status;
char szBuffer[40];
unsigned char *ptr;
for(i = 0; i < MAX; i++)
for(j = 0; j < MAX; j++)
Karte[i][j] = 0;
InvalidateRect(hwndHauptfenster, NULL, TRUE);
ListBoxAusgabe("Thread gestartet...");
ListBoxAusgabe("Com-Schnittstelle wird initialisiert...");
status = Init_Com_Schnittstelle();
switch(status)
{
case 1:
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
default:
ListBoxAusgabe("Mit Gerät verbunden...");
break;
}
/////////////////////////////////////////////////////////////////////////////////////////
//Warten auf Daten vom Untergrund
ListBoxAusgabe("Warten auf Daten vom Untergrund...");
if(WaitCommEvent(hCom, &iEvent, NULL) != 0)
{
if(iEvent & EV_RXCHAR)
{
Sleep(500);//Damit alle Daten empfangen werden, bevor sie ausgelesen werden
if(ReadFile(hCom, &pcMsg, 4, &iBytesWritten, NULL)== 0)
ListBoxAusgabe("Fehler");
if(iBytesWritten == 4)
ListBoxAusgabe("Daten vollständig erhalten...");
}
}
else
{
ListBoxAusgabe("Fehler beim auslesen...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
//////////////////////////////////////////////////////////////////////////////////
//Kontrolle der empfangenen Daten
wsprintf(szBuffer, "Lichtwerte: %d %d %d %d", (int) pcMsg[0], (int) pcMsg[1], (int) pcMsg[2], (int) pcMsg[3]);
ListBoxAusgabe(szBuffer);
////////////////////////////////////////////////////////////////////////////////////////
//Daten auswerten
for(i = 0; i < 4; i++)
if(((int)pcMsg[i]) < 120)
{
pcMsg[i] = '1';
}
else
pcMsg[i] = '0';
iAsPosition[0] = iAsPosition[1] = 200; //Nullpunkt festlegen
Karte[iAsPosition[0]][iAsPosition[1]] = 1;
iAsRichtung = RT_RECHTS;
if(!(pcMsg[0] == '1' || pcMsg[1] == '1' || pcMsg[2] == '1'))
{
ListBoxAusgabe("Asuro befindet sich nicht auf einer Linie...");
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
if(pcMsg[0] == '1' || pcMsg[1] == '1')
Karte[iAsPosition[0]] [iAsPosition[1] + 1] = 2;
if(pcMsg[2] == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;
if(pcMsg[3] == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;
InvalidateRect(hwndHauptfenster, NULL, TRUE);
ListBoxAusgabe("Daten ausgewertet...");
///////////////////////////////////////////////////////////////////////////////////////
//Algorithmus
while(1)
{
ListBoxAusgabe("Abzweigungen suchen und Übertragung vorbereiten...");
status = Suchen_Umgebung();
if(status == 0)
{
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
ListBoxAusgabe("Übertragung der Daten...");
if(WriteFile(hCom, &pcMsg, 1, &iBytesWritten, NULL) == 0 || iBytesWritten != 1)
{
ListBoxAusgabe("Richtung konnte nicht gesendet werden...");
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
switch(iAsRichtung)
{
case RT_RUNTER:
ListBoxAusgabe("Richtung gesendet...(runter)");
break;
case RT_RECHTS:
ListBoxAusgabe("Richtung gesendet...(rechts)");
break;
case RT_LINKS:
ListBoxAusgabe("Richtung gesendet...(links)");
break;
case RT_HOCH:
ListBoxAusgabe("Richtung gesendet...(hoch)");
break;
}
ListBoxAusgabe(" ");
ListBoxAusgabe("Warte auf Daten...");
if(WaitCommEvent(hCom, &iEvent, NULL) != 0)
{
if(iEvent & EV_RXCHAR)
{
Sleep(1000);
if(ReadFile(hCom, &pcMsg, 8, &iBytesWritten, NULL) == 0 && iBytesWritten > 6)//("Anzahl Schritte", " ", "vorne", "vorne", "rechts", "links")
{
ListBoxAusgabe("Fehler bei ReadFile()...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
}
}
else
{
ListBoxAusgabe("Fehler beim auslesen...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
ListBoxAusgabe("Daten erhalten...");
ptr = strchr(pcMsg, ' ');
if(ptr == NULL)
{
ListBoxAusgabe("Fehler...(kein Leerzeichen vorhanden)");
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
//////////////////////////////////////////////////////////////////////////////////
//Kontrolle der empfangenen Daten für Benutzer
wsprintf(szBuffer, "%d Schritte; Lichtwerte: %d %d %d %d", iAsSchritte, *(ptr + 1), *(ptr + 2), *(ptr + 3), *(ptr + 4));
ListBoxAusgabe(szBuffer);
//////////////////////////////////////////////////////////////////////////////////
sscanf(pcMsg, "%d ", &iAsSchritte);
//iAsSchritte = iAsSchritte / 2; //Zum verkleinern der Darstellung
iAsSchritte += 30; //Ausgleichswert durch Kurven
ListBoxAusgabe("Daten in Karte eintragen...");
for(i = 1; i < 5; i++)
if(*(ptr + i) < 120)
{
*(ptr + i) = '1';
}
else
*(ptr + i) = '0';
if(iAsRichtung == RT_RECHTS)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0]][iAsPosition[1] + i] = 1;
iAsPosition[1] += iAsSchritte;
if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0]][iAsPosition[1] + 1] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;
}
if(iAsRichtung == RT_RUNTER)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0] + i][iAsPosition[1]] = 1;
iAsPosition[0] += iAsSchritte;
if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0]][iAsPosition[1] - 1] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0]][iAsPosition[1] + 1] = 2;
}
if(iAsRichtung == RT_LINKS)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0]][iAsPosition[1] - i] = 1;
iAsPosition[1] -= iAsSchritte;
if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0]][iAsPosition[1] - 1] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;
}
if(iAsRichtung == RT_HOCH)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0] - i][iAsPosition[1]] = 1;
iAsPosition[0] -= iAsSchritte;
if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0]][iAsPosition[1] + 1] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0]][iAsPosition[1] - 1] = 2;
}
InvalidateRect(hwndHauptfenster, &rect, TRUE);
if(*(ptr + 1) == '0' && *(ptr + 2) == '0' && *(ptr + 3) == '0' && *(ptr + 4) == '0')
{
ListBoxAusgabe("Strecke ist zuende...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
ListBoxAusgabe("Daten auswerten...");
}
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
int Suchen_Umgebung(void) //Gibt zurück ob sich Asuro links oder rechtsrum drehen muss
{
if(Karte[iAsPosition[0]][iAsPosition[1] + 1] == 2) //rechts geht es weiter
{
ListBoxAusgabe("Nach rechts geht es weiter...");
if(iAsRichtung == RT_RECHTS)
{
pcMsg[0] = '0';
}
else if(iAsRichtung == RT_RUNTER)
{
pcMsg[0] = '3';
}
else //if(iAsRichtung == RT_HOCH)
{
pcMsg[0] = '1';
}
iAsRichtung = RT_RECHTS;
return 1;
}
else if(Karte[iAsPosition[0] + 1][iAsPosition[1]] == 2) //runter geht es weiter
{
ListBoxAusgabe("Nach unten geht es weiter...");
if(iAsRichtung == RT_RECHTS)
{
pcMsg[0] = '1';
}
else if(iAsRichtung == RT_RUNTER)
{
pcMsg[0] = '0';
}
else if(iAsRichtung == RT_LINKS)
{
pcMsg[0] = '3';
}
iAsRichtung = RT_RUNTER;
return 1;
}
else if(Karte[iAsPosition[0]][((iAsPosition[1] - 1) < 0) ? 0 : (iAsPosition[1] - 1)] == 2) //links geht es weiter
{
ListBoxAusgabe("Nach links geht es weiter...");
if(iAsRichtung == RT_RUNTER)
{
pcMsg[0] = '1';
}
else if(iAsRichtung == RT_LINKS)
{
pcMsg[0] = '0';
}
else
{
pcMsg[0] = '3';
}
iAsRichtung = RT_LINKS;
return 1;
}
else if(Karte[((iAsPosition[0] - 1) < 0) ? 0 : (iAsPosition[0] - 1)][iAsPosition[1]] == 2) //hoch geht es weiter
{
ListBoxAusgabe("Nach oben geht es weiter...");
if(iAsRichtung == RT_RECHTS)
{
pcMsg[0] = '3';
}
else if(iAsRichtung == RT_LINKS)
{
pcMsg[0] = '1';
}
else
{
pcMsg[0] = '0';
}
iAsRichtung = RT_HOCH;
return 1;
}
else
{
ListBoxAusgabe("Keine weiteren Punkte in unmittelbarer Nähe...");
return 0;
}
}
Lesezeichen