Forum: PC-Programmierung RS232, WinAPI, C


von Faddi Roller (Gast)


Lesenswert?

Hallo Leute,

ich habe zwei kleine Programme in C-Code. Das eine baut mit WinAPI ein
Fenster auf mit 3 Buttons. Das andere setzt die Pins RTS und DTR auf 0
oder 1. Jetzt möchte ich diese beiden Programme Verknüpfen, so dass
wenn man auf einen Button klickt jeweils der dazugehörige Pin auf 1
gesetzt wird. Hier der Code:


#include <windows.h>

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);

HDC dc;
HWND button1, button2, button3;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow) {
WNDCLASS wc;
HWND hWnd;
MSG msg;
wc.style = CS_HREDRAW|CS_VREDRAW|CS_BYTEALIGNCLIENT;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
/*(HBRUSH)(COLOR_WINDOW+1);*/
wc.lpszMenuName = NULL;
wc.lpszClassName = "ButtonExample";
RegisterClass(&wc);

hWnd = CreateWindow(wc.lpszClassName,"Switch 1.0",
WS_OVERLAPPEDWINDOW,100,100,410,90,
NULL,NULL,hInstance,NULL);

button1 =
CreateWindow("BUTTON","Battery",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
10,10,120,40,hWnd,NULL,hInstance,NULL);
button2 = CreateWindow("BUTTON","Solar",WS_CHILD |WS_VISIBLE|
BS_PUSHBUTTON,
140,10,120,40,hWnd,NULL,hInstance,NULL);
button3 = CreateWindow("BUTTON","OFF",WS_CHILD |WS_VISIBLE|
BS_PUSHBUTTON,
270,10,120,40,hWnd,NULL,hInstance,NULL);

ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
HANDLE hPort;
hPort =  CreateFile (TEXT("COM1"), GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);

switch(uMsg)
{
case WM_COMMAND:
{
if ((HWND)lParam==button1) {
EscapeCommFunction (hPort, CLRDTR);
EscapeCommFunction (hPort, SETRTS);
MessageBox(hwnd,"Battery ON","Good!",MB_OK); };
if ((HWND)lParam==button2) {
EscapeCommFunction (hPort, CLRRTS);
EscapeCommFunction (hPort, SETDTR);
MessageBox(hwnd,"Solar ON","Better!",MB_OK); }
if ((HWND)lParam==button3) {
EscapeCommFunction (hPort, CLRRTS);
EscapeCommFunction (hPort, CLRDTR);
MessageBox(hwnd,"Energy OFF","",MB_OK); }
return 0;
}

case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
{
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
}
CloseHandle (hPort);

return 0;
}


Das Problem ist, wenn ich das Programm kompiliere, ausführe und dann
einen Button klicke kommt zwar ein Message-Fenster wie vorgesehen aber
die WinAPI-Funktionen "EscapeCommFunction" werden übersprungen. Das
sehe ich daran, dass sich die Spannungen an den Pins nicht ändern. Was
mache ich falsch?

Danke für eure Hilfe im Voraus,

Faddi

von Dr. Nick (Gast)


Lesenswert?

1. Du öffnest die serielle Schnittstelle in WndProc(), d.h. bei jeder
Windows-Nachricht wird COM1 geöffnet (auch beim Neuzeichnen des
Fensters, Mausbewegung...). Besser erstellst du das HANDLE für COM1 in
WinMain() vor "ShowWindow(...);" und schliesst es wieder vor "return
msg.wParam;" Wenn der serielle Port unbedingt gleich nach dem Öffnen
wieder geschlossen werden soll, dann öffne und schliesse ihn innerhalbe
der Klammern von "case WM_COMMAND".

Ich weiss nicht, ob der COM-Port nach dem Schliessen wieder in den
"Urzustand" versetzt wird. Das würde bedeuten, dass Du in WndProc()
RTS und DTR zwar änderst, diese aber am Ende der Funktion wieder den
ursprünglichen Zustand erhalten würden. Also besser den COM-Port am
Programmstart öffnen und am Programmende wieder schliessen wie oben
beschrieben. Das Handle muss dann natürlich als globale Variable
definiert werden.

2. Du prüfst überhaupt nicht, ob der COM-Port geöffnet werden konnte
(ist hPort ein gültiges HANDLE?)! Wenn COM1 durch ein anderes Programm
geöffnet wurde (z.B. Teminal), kannst Du COM1: nicht öffnen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.